kopia lustrzana https://github.com/espressif/esp-idf
Merge branch 'feature/usb_host_feature_and_refactor_backports_v5.0' into 'release/v5.0'
USB Host: Backport multiple feature and refactors to v5.0 See merge request espressif/esp-idf!21584pull/10970/head
commit
6a86124ff5
|
@ -128,6 +128,7 @@ build:integration_test:
|
|||
- wifi # example_test_002, example_test*wifi*
|
||||
- ethernet # example_test*ethernet*
|
||||
- sdio # UT_044, UT_045
|
||||
- usb # USB Device & Host tests
|
||||
- adc # component_ut_pytest_esp32x_adc
|
||||
patterns:
|
||||
- "{0}-{1}-{2}"
|
||||
|
|
|
@ -224,6 +224,21 @@
|
|||
- "components/driver/**/*"
|
||||
- "components/sdmmc/**/*"
|
||||
|
||||
# for jobs: USB host and device examples
|
||||
.patterns-example_test-usb: &patterns-example_test-usb
|
||||
- "components/hal/usb*.c"
|
||||
- "components/hal/esp32s*/include/hal/usb*.h"
|
||||
- "components/tinyusb/**/**/*"
|
||||
- "components/usb/**/*"
|
||||
- "examples/peripherals/usb/host/**/**/**/*"
|
||||
- "examples/peripherals/usb/device/**/**/*"
|
||||
|
||||
# for jobs: USB component (Host) pytest test_app
|
||||
.patterns-component_ut-usb: &patterns-component_ut-usb
|
||||
- "components/hal/usb*.c"
|
||||
- "components/hal/esp32s*/include/hal/usb*.h"
|
||||
- "components/usb/**/*"
|
||||
|
||||
# for jobs: component_ut_pytest_esp32x_adc:
|
||||
.patterns-component_ut-adc: &patterns-component_ut-adc
|
||||
- "components/esp_adc/**/*"
|
||||
|
@ -232,6 +247,7 @@
|
|||
- "components/esp_hw_support/**/*"
|
||||
- "components/efuse/**/*"
|
||||
|
||||
|
||||
##############
|
||||
# if anchors #
|
||||
##############
|
||||
|
@ -517,6 +533,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -540,6 +558,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -562,6 +582,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -584,6 +606,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -606,6 +630,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -628,6 +654,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -650,6 +678,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-target_test-wifi
|
||||
|
||||
|
@ -824,6 +854,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -852,6 +884,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -878,6 +912,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -905,6 +941,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -931,6 +969,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -957,6 +997,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -983,6 +1025,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -1072,6 +1116,8 @@
|
|||
changes: *patterns-component_ut
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-adc
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-custom_test
|
||||
- <<: *if-dev-push
|
||||
|
@ -1080,6 +1126,8 @@
|
|||
changes: *patterns-example_test-bt
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-ethernet
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-wifi
|
||||
- <<: *if-dev-push
|
||||
|
@ -1345,6 +1393,19 @@
|
|||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1419,6 +1480,19 @@
|
|||
- <<: *if-label-component_ut_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32c2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32c2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1493,6 +1567,19 @@
|
|||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32c3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32c3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1567,6 +1654,19 @@
|
|||
- <<: *if-label-component_ut_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32h2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32h2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1641,6 +1741,19 @@
|
|||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32s2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32s2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1715,6 +1828,19 @@
|
|||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:component_ut-esp32s3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-component_ut
|
||||
- <<: *if-label-component_ut_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-component_ut-usb
|
||||
|
||||
.rules:test:component_ut-esp32s3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1785,6 +1911,17 @@
|
|||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1855,6 +1992,17 @@
|
|||
- <<: *if-label-custom_test_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32c2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32c2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1925,6 +2073,17 @@
|
|||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32c3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32c3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -1995,6 +2154,17 @@
|
|||
- <<: *if-label-custom_test_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32h2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32h2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2065,6 +2235,17 @@
|
|||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32s2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32s2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2135,6 +2316,17 @@
|
|||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32s3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-custom_test
|
||||
- <<: *if-label-custom_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:custom_test-esp32s3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2220,6 +2412,19 @@
|
|||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2298,6 +2503,19 @@
|
|||
- <<: *if-label-example_test_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32c2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32c2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32c2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2385,6 +2603,19 @@
|
|||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32c3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32c3
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32c3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2463,6 +2694,19 @@
|
|||
- <<: *if-label-example_test_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32h2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32h2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32h2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2541,6 +2785,19 @@
|
|||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32s2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s2
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32s2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2619,6 +2876,19 @@
|
|||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
|
||||
.rules:test:example_test-esp32s3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-example_test
|
||||
- <<: *if-label-example_test_esp32s3
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-dev-push
|
||||
changes: *patterns-example_test-usb
|
||||
|
||||
.rules:test:example_test-esp32s3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2761,6 +3031,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32
|
||||
|
||||
.rules:test:unit_test-esp32-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2833,6 +3114,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32c2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c2
|
||||
|
||||
.rules:test:unit_test-esp32c2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2905,6 +3197,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32c3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32c3
|
||||
|
||||
.rules:test:unit_test-esp32c3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -2977,6 +3280,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32h2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32h2
|
||||
|
||||
.rules:test:unit_test-esp32h2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -3049,6 +3363,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32s2-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s2
|
||||
|
||||
.rules:test:unit_test-esp32s2-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
@ -3121,6 +3446,17 @@
|
|||
- <<: *if-dev-push
|
||||
changes: *patterns-unit_test-sdio
|
||||
|
||||
.rules:test:unit_test-esp32s3-usb:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
when: never
|
||||
- <<: *if-protected
|
||||
- <<: *if-label-build-only
|
||||
when: never
|
||||
- <<: *if-label-target_test
|
||||
- <<: *if-label-unit_test
|
||||
- <<: *if-label-unit_test_esp32s3
|
||||
|
||||
.rules:test:unit_test-esp32s3-wifi:
|
||||
rules:
|
||||
- <<: *if-revert-branch
|
||||
|
|
|
@ -396,6 +396,14 @@ component_ut_pytest_esp32c3_flash_encryption:
|
|||
- build_pytest_components_esp32c3
|
||||
tags: [ esp32c3, flash_encryption ]
|
||||
|
||||
component_ut_pytest_esp32s3_usb_host:
|
||||
extends:
|
||||
- .pytest_components_dir_template
|
||||
- .rules:test:component_ut-esp32s3-usb
|
||||
needs:
|
||||
- build_pytest_components_esp32s3
|
||||
tags: [ esp32s3, usb_host_flash_disk ]
|
||||
|
||||
.pytest_test_apps_dir_template:
|
||||
extends: .pytest_template
|
||||
variables:
|
||||
|
|
|
@ -119,7 +119,7 @@ if(NOT BOOTLOADER_BUILD)
|
|||
"esp32s2/cp_dma_hal.c"
|
||||
"esp32s2/touch_sensor_hal.c"
|
||||
"esp32s2/dac_hal.c"
|
||||
"usbh_hal.c")
|
||||
"usb_dwc_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32s3")
|
||||
|
@ -136,7 +136,7 @@ if(NOT BOOTLOADER_BUILD)
|
|||
"esp32s3/hmac_hal.c"
|
||||
"esp32s3/touch_sensor_hal.c"
|
||||
"esp32s3/rtc_cntl_hal.c"
|
||||
"usbh_hal.c")
|
||||
"usb_dwc_hal.c")
|
||||
endif()
|
||||
|
||||
if(${target} STREQUAL "esp32c3")
|
||||
|
|
|
@ -17,8 +17,8 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
|
|||
|
||||
#include <stdlib.h>
|
||||
#include <stddef.h>
|
||||
#include "soc/usbh_struct.h"
|
||||
#include "hal/usbh_ll.h"
|
||||
#include "soc/usb_dwc_struct.h"
|
||||
#include "hal/usb_dwc_ll.h"
|
||||
#include "hal/usb_types_private.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
|
@ -26,11 +26,11 @@ NOTE: Thread safety is the responsibility fo the HAL user. All USB Host HAL
|
|||
|
||||
// ------------------ Constants/Configs --------------------
|
||||
|
||||
#define USBH_HAL_DMA_MEM_ALIGN 512
|
||||
#define USBH_HAL_FRAME_LIST_MEM_ALIGN 512 //The frame list needs to be 512 bytes aligned (contrary to the databook)
|
||||
#define USBH_HAL_NUM_CHAN 8
|
||||
#define USBH_HAL_XFER_DESC_SIZE (sizeof(usbh_ll_dma_qtd_t))
|
||||
#define USBH_HAL_FIFO_TOTAL_USABLE_LINES 200 //Although we have a 256 lines, only 200 lines are usuable due to EPINFO_CTL
|
||||
#define USB_DWC_HAL_DMA_MEM_ALIGN 512
|
||||
#define USB_DWC_HAL_FRAME_LIST_MEM_ALIGN 512 //The frame list needs to be 512 bytes aligned (contrary to the databook)
|
||||
#define USB_DWC_HAL_NUM_CHAN 8
|
||||
#define USB_DWC_HAL_XFER_DESC_SIZE (sizeof(usb_dwc_ll_dma_qtd_t))
|
||||
#define USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES 200 //Although we have a 256 lines, only 200 lines are usuable due to EPINFO_CTL
|
||||
|
||||
/**
|
||||
* @brief FIFO size configuration structure
|
||||
|
@ -39,7 +39,7 @@ typedef struct {
|
|||
uint32_t rx_fifo_lines; /**< Size of the RX FIFO in terms the number of FIFO lines */
|
||||
uint32_t nptx_fifo_lines; /**< Size of the Non-periodic FIFO in terms the number of FIFO lines */
|
||||
uint32_t ptx_fifo_lines; /**< Size of the Periodic FIFO in terms the number of FIFO lines */
|
||||
} usbh_hal_fifo_config_t;
|
||||
} usb_dwc_hal_fifo_config_t;
|
||||
|
||||
// --------------------- HAL Events ------------------------
|
||||
|
||||
|
@ -47,25 +47,25 @@ typedef struct {
|
|||
* @brief Host port HAL events
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_HAL_PORT_EVENT_NONE, /**< No event occurred, or could not decode interrupt */
|
||||
USBH_HAL_PORT_EVENT_CHAN, /**< A channel event has occurred. Call the the channel event handler instead */
|
||||
USBH_HAL_PORT_EVENT_CONN, /**< The host port has detected a connection */
|
||||
USBH_HAL_PORT_EVENT_DISCONN, /**< The host port has been disconnected */
|
||||
USBH_HAL_PORT_EVENT_ENABLED, /**< The host port has been enabled (i.e., connected to a device that has been reset. Started sending SOFs) */
|
||||
USBH_HAL_PORT_EVENT_DISABLED, /**< The host port has been disabled (no more SOFs). Could be due to disable/reset request, or a port error (e.g. port babble condition. See 11.8.1 of USB2.0 spec) */
|
||||
USBH_HAL_PORT_EVENT_OVRCUR, /**< The host port has encountered an overcurrent condition */
|
||||
USBH_HAL_PORT_EVENT_OVRCUR_CLR, /**< The host port has been cleared of the overcurrent condition */
|
||||
} usbh_hal_port_event_t;
|
||||
USB_DWC_HAL_PORT_EVENT_NONE, /**< No event occurred, or could not decode interrupt */
|
||||
USB_DWC_HAL_PORT_EVENT_CHAN, /**< A channel event has occurred. Call the the channel event handler instead */
|
||||
USB_DWC_HAL_PORT_EVENT_CONN, /**< The host port has detected a connection */
|
||||
USB_DWC_HAL_PORT_EVENT_DISCONN, /**< The host port has been disconnected */
|
||||
USB_DWC_HAL_PORT_EVENT_ENABLED, /**< The host port has been enabled (i.e., connected to a device that has been reset. Started sending SOFs) */
|
||||
USB_DWC_HAL_PORT_EVENT_DISABLED, /**< The host port has been disabled (no more SOFs). Could be due to disable/reset request, or a port error (e.g. port babble condition. See 11.8.1 of USB2.0 spec) */
|
||||
USB_DWC_HAL_PORT_EVENT_OVRCUR, /**< The host port has encountered an overcurrent condition */
|
||||
USB_DWC_HAL_PORT_EVENT_OVRCUR_CLR, /**< The host port has been cleared of the overcurrent condition */
|
||||
} usb_dwc_hal_port_event_t;
|
||||
|
||||
/**
|
||||
* @brief Channel events
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_HAL_CHAN_EVENT_CPLT, /**< The channel has completed execution of a transfer descriptor that had the USBH_HAL_XFER_DESC_FLAG_HOC flag set. Channel is now halted */
|
||||
USBH_HAL_CHAN_EVENT_ERROR, /**< The channel has encountered an error. Channel is now halted. */
|
||||
USBH_HAL_CHAN_EVENT_HALT_REQ, /**< The channel has been successfully halted as requested */
|
||||
USBH_HAL_CHAN_EVENT_NONE, /**< No event (interrupt ran for internal processing) */
|
||||
} usbh_hal_chan_event_t;
|
||||
USB_DWC_HAL_CHAN_EVENT_CPLT, /**< The channel has completed execution of a transfer descriptor that had the USB_DWC_HAL_XFER_DESC_FLAG_HOC flag set. Channel is now halted */
|
||||
USB_DWC_HAL_CHAN_EVENT_ERROR, /**< The channel has encountered an error. Channel is now halted. */
|
||||
USB_DWC_HAL_CHAN_EVENT_HALT_REQ, /**< The channel has been successfully halted as requested */
|
||||
USB_DWC_HAL_CHAN_EVENT_NONE, /**< No event (interrupt ran for internal processing) */
|
||||
} usb_dwc_hal_chan_event_t;
|
||||
|
||||
// --------------------- HAL Errors ------------------------
|
||||
|
||||
|
@ -73,20 +73,20 @@ typedef enum {
|
|||
* @brief Channel errors
|
||||
*/
|
||||
typedef enum {
|
||||
USBH_HAL_CHAN_ERROR_XCS_XACT = 0, /**< Excessive (three consecutive) transaction errors (e.g., no response, bad CRC etc */
|
||||
USBH_HAL_CHAN_ERROR_BNA, /**< Buffer Not Available error (i.e., An inactive transfer descriptor was fetched by the channel) */
|
||||
USBH_HAL_CHAN_ERROR_PKT_BBL, /**< Packet babbler error (packet exceeded MPS) */
|
||||
USBH_HAL_CHAN_ERROR_STALL, /**< STALL response received */
|
||||
} usbh_hal_chan_error_t;
|
||||
USB_DWC_HAL_CHAN_ERROR_XCS_XACT = 0, /**< Excessive (three consecutive) transaction errors (e.g., no response, bad CRC etc */
|
||||
USB_DWC_HAL_CHAN_ERROR_BNA, /**< Buffer Not Available error (i.e., An inactive transfer descriptor was fetched by the channel) */
|
||||
USB_DWC_HAL_CHAN_ERROR_PKT_BBL, /**< Packet babbler error (packet exceeded MPS) */
|
||||
USB_DWC_HAL_CHAN_ERROR_STALL, /**< STALL response received */
|
||||
} usb_dwc_hal_chan_error_t;
|
||||
|
||||
// ------------- Transfer Descriptor Related ---------------
|
||||
|
||||
/**
|
||||
* @brief Flags used to describe the type of transfer descriptor to fill
|
||||
*/
|
||||
#define USBH_HAL_XFER_DESC_FLAG_IN 0x01 /**< Indicates this transfer descriptor is of the IN direction */
|
||||
#define USBH_HAL_XFER_DESC_FLAG_SETUP 0x02 /**< Indicates this transfer descriptor is an OUT setup */
|
||||
#define USBH_HAL_XFER_DESC_FLAG_HOC 0x04 /**< Indicates that the channel will be halted after this transfer descriptor completes */
|
||||
#define USB_DWC_HAL_XFER_DESC_FLAG_IN 0x01 /**< Indicates this transfer descriptor is of the IN direction */
|
||||
#define USB_DWC_HAL_XFER_DESC_FLAG_SETUP 0x02 /**< Indicates this transfer descriptor is an OUT setup */
|
||||
#define USB_DWC_HAL_XFER_DESC_FLAG_HOC 0x04 /**< Indicates that the channel will be halted after this transfer descriptor completes */
|
||||
|
||||
/**
|
||||
* @brief Status value of a transfer descriptor
|
||||
|
@ -95,10 +95,10 @@ typedef enum {
|
|||
* or an error). Therefore, if a channel halt is requested before a transfer descriptor completes, the transfer
|
||||
* descriptor remains unexecuted.
|
||||
*/
|
||||
#define USBH_HAL_XFER_DESC_STS_SUCCESS USBH_LL_QTD_STATUS_SUCCESS
|
||||
#define USBH_HAL_XFER_DESC_STS_PKTERR USBH_LL_QTD_STATUS_PKTERR
|
||||
#define USBH_HAL_XFER_DESC_STS_BUFFER_ERR USBH_LL_QTD_STATUS_BUFFER
|
||||
#define USBH_HAL_XFER_DESC_STS_NOT_EXECUTED USBH_LL_QTD_STATUS_NOT_EXECUTED
|
||||
#define USB_DWC_HAL_XFER_DESC_STS_SUCCESS USB_DWC_LL_QTD_STATUS_SUCCESS
|
||||
#define USB_DWC_HAL_XFER_DESC_STS_PKTERR USB_DWC_LL_QTD_STATUS_PKTERR
|
||||
#define USB_DWC_HAL_XFER_DESC_STS_BUFFER_ERR USB_DWC_LL_QTD_STATUS_BUFFER
|
||||
#define USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED USB_DWC_LL_QTD_STATUS_NOT_EXECUTED
|
||||
|
||||
// -------------------- Object Types -----------------------
|
||||
|
||||
|
@ -122,7 +122,7 @@ typedef struct {
|
|||
usb_hal_interval_t interval; /**< The interval of the endpoint */
|
||||
uint32_t phase_offset_frames; /**< Phase offset in number of frames */
|
||||
} periodic; /**< Characteristic for periodic (interrupt/isochronous) endpoints only */
|
||||
} usbh_hal_ep_char_t;
|
||||
} usb_dwc_hal_ep_char_t;
|
||||
|
||||
/**
|
||||
* @brief Channel object
|
||||
|
@ -139,18 +139,18 @@ typedef struct {
|
|||
};
|
||||
uint32_t val;
|
||||
} flags; /**< Flags regarding channel's status and information */
|
||||
usb_host_chan_regs_t *regs; /**< Pointer to the channel's register set */
|
||||
usbh_hal_chan_error_t error; /**< The last error that occurred on the channel */
|
||||
usb_dwc_host_chan_regs_t *regs; /**< Pointer to the channel's register set */
|
||||
usb_dwc_hal_chan_error_t error; /**< The last error that occurred on the channel */
|
||||
usb_priv_xfer_type_t type; /**< The transfer type of the channel */
|
||||
void *chan_ctx; /**< Context variable for the owner of the channel */
|
||||
} usbh_hal_chan_t;
|
||||
} usb_dwc_hal_chan_t;
|
||||
|
||||
/**
|
||||
* @brief HAL context structure
|
||||
*/
|
||||
typedef struct {
|
||||
//Context
|
||||
usbh_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */
|
||||
usb_dwc_dev_t *dev; /**< Pointer to base address of DWC_OTG registers */
|
||||
//Host Port related
|
||||
uint32_t *periodic_frame_list; /**< Pointer to scheduling frame list */
|
||||
usb_hal_frame_list_len_t frame_list_len; /**< Length of the periodic scheduling frame list */
|
||||
|
@ -168,9 +168,9 @@ typedef struct {
|
|||
struct {
|
||||
int num_allocd; /**< Number of channels currently allocated */
|
||||
uint32_t chan_pend_intrs_msk; /**< Bit mask of channels with pending interrupts */
|
||||
usbh_hal_chan_t *hdls[USBH_HAL_NUM_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */
|
||||
usb_dwc_hal_chan_t *hdls[USB_DWC_HAL_NUM_CHAN]; /**< Handles of each channel. Set to NULL if channel has not been allocated */
|
||||
} channels;
|
||||
} usbh_hal_context_t;
|
||||
} usb_dwc_hal_context_t;
|
||||
|
||||
// -------------------------------------------------- Core (Global) ----------------------------------------------------
|
||||
|
||||
|
@ -188,12 +188,12 @@ typedef struct {
|
|||
* - Sets default values to some global and OTG registers (GAHBCFG and GUSBCFG)
|
||||
* - Umask global interrupt signal
|
||||
* - Put DWC_OTG into host mode. Require 25ms delay before this takes effect.
|
||||
* - State -> USBH_HAL_PORT_STATE_OTG
|
||||
* - State -> USB_DWC_HAL_PORT_STATE_OTG
|
||||
* - Interrupts cleared. Users can now enable their ISR
|
||||
*
|
||||
* @param[inout] hal Context of the HAL layer
|
||||
*/
|
||||
void usbh_hal_init(usbh_hal_context_t *hal);
|
||||
void usb_dwc_hal_init(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Deinitialize the HAL context
|
||||
|
@ -206,20 +206,20 @@ void usbh_hal_init(usbh_hal_context_t *hal);
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
void usbh_hal_deinit(usbh_hal_context_t *hal);
|
||||
void usb_dwc_hal_deinit(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Issue a soft reset to the controller
|
||||
*
|
||||
* This should be called when the host port encounters an error event or has been disconnected. Before calling this,
|
||||
* users are responsible for safely freeing all channels as a soft reset will wipe all host port and channel registers.
|
||||
* This function will result in the host port being put back into same state as after calling usbh_hal_init().
|
||||
* This function will result in the host port being put back into same state as after calling usb_dwc_hal_init().
|
||||
*
|
||||
* @note This has nothing to do with a USB bus reset. It simply resets the peripheral
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
void usbh_hal_core_soft_reset(usbh_hal_context_t *hal);
|
||||
void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Set FIFO sizes
|
||||
|
@ -229,14 +229,14 @@ void usbh_hal_core_soft_reset(usbh_hal_context_t *hal);
|
|||
* may be situations where this function may need to be called again to resize the FIFOs. If resizing FIFOs dynamically,
|
||||
* it is the user's responsibility to ensure there are no active channels when this function is called.
|
||||
*
|
||||
* @note The totol size of all the FIFOs must be less than or equal to USBH_HAL_FIFO_TOTAL_USABLE_LINES
|
||||
* @note The totol size of all the FIFOs must be less than or equal to USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES
|
||||
* @note After a port reset, the FIFO size registers will reset to their default values, so this function must be called
|
||||
* again post reset.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param fifo_config FIFO configuration
|
||||
*/
|
||||
void usbh_hal_set_fifo_size(usbh_hal_context_t *hal, const usbh_hal_fifo_config_t *fifo_config);
|
||||
void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config);
|
||||
|
||||
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
||||
|
||||
|
@ -249,11 +249,11 @@ void usbh_hal_set_fifo_size(usbh_hal_context_t *hal, const usbh_hal_fifo_config_
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_port_init(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_init(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//Configure Host related interrupts
|
||||
usbh_ll_haintmsk_dis_chan_intr(hal->dev, 0xFFFFFFFF); //Disable interrupts for all channels
|
||||
usb_ll_en_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_HCHINT);
|
||||
usb_dwc_ll_haintmsk_dis_chan_intr(hal->dev, 0xFFFFFFFF); //Disable interrupts for all channels
|
||||
usb_dwc_ll_gintmsk_en_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_HCHINT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -263,10 +263,10 @@ static inline void usbh_hal_port_init(usbh_hal_context_t *hal)
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_port_deinit(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_deinit(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//Disable Host port and channel interrupts
|
||||
usb_ll_dis_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_HCHINT);
|
||||
usb_dwc_ll_gintmsk_dis_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_HCHINT);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -275,12 +275,12 @@ static inline void usbh_hal_port_deinit(usbh_hal_context_t *hal)
|
|||
* @param hal Context of the HAL layer
|
||||
* @param power_on Whether to power ON or OFF the port
|
||||
*/
|
||||
static inline void usbh_hal_port_toggle_power(usbh_hal_context_t *hal, bool power_on)
|
||||
static inline void usb_dwc_hal_port_toggle_power(usb_dwc_hal_context_t *hal, bool power_on)
|
||||
{
|
||||
if (power_on) {
|
||||
usbh_ll_hprt_en_pwr(hal->dev);
|
||||
usb_dwc_ll_hprt_en_pwr(hal->dev);
|
||||
} else {
|
||||
usbh_ll_hprt_dis_pwr(hal->dev);
|
||||
usb_dwc_ll_hprt_dis_pwr(hal->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -291,19 +291,19 @@ static inline void usbh_hal_port_toggle_power(usbh_hal_context_t *hal, bool powe
|
|||
* Entry:
|
||||
* - Host port detects a device connection or Host port is already enabled
|
||||
* Exit:
|
||||
* - On release of the reset signal, a USBH_HAL_PORT_EVENT_ENABLED will be generated
|
||||
* - On release of the reset signal, a USB_DWC_HAL_PORT_EVENT_ENABLED will be generated
|
||||
*
|
||||
* @note If the host port is already enabled, then issuing a reset will cause it be disabled and generate a
|
||||
* USBH_HAL_PORT_EVENT_DISABLED event. The host port will not be enabled until the reset signal is released (thus
|
||||
* generating the USBH_HAL_PORT_EVENT_ENABLED event)
|
||||
* USB_DWC_HAL_PORT_EVENT_DISABLED event. The host port will not be enabled until the reset signal is released (thus
|
||||
* generating the USB_DWC_HAL_PORT_EVENT_ENABLED event)
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param enable Enable/disable reset signal
|
||||
*/
|
||||
static inline void usbh_hal_port_toggle_reset(usbh_hal_context_t *hal, bool enable)
|
||||
static inline void usb_dwc_hal_port_toggle_reset(usb_dwc_hal_context_t *hal, bool enable)
|
||||
{
|
||||
HAL_ASSERT(hal->channels.num_allocd == 0); //Cannot reset if there are still allocated channels
|
||||
usbh_ll_hprt_set_port_reset(hal->dev, enable);
|
||||
usb_dwc_ll_hprt_set_port_reset(hal->dev, enable);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -317,7 +317,7 @@ static inline void usbh_hal_port_toggle_reset(usbh_hal_context_t *hal, bool enab
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
void usbh_hal_port_enable(usbh_hal_context_t *hal);
|
||||
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Disable the host port
|
||||
|
@ -327,9 +327,9 @@ void usbh_hal_port_enable(usbh_hal_context_t *hal);
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_port_disable(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_disable(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
usbh_ll_hprt_port_dis(hal->dev);
|
||||
usb_dwc_ll_hprt_port_dis(hal->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -337,9 +337,9 @@ static inline void usbh_hal_port_disable(usbh_hal_context_t *hal)
|
|||
*
|
||||
* @param hal Context of the HAL layers
|
||||
*/
|
||||
static inline void usbh_hal_port_suspend(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_suspend(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
usbh_ll_hprt_set_port_suspend(hal->dev);
|
||||
usb_dwc_ll_hprt_set_port_suspend(hal->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -352,12 +352,12 @@ static inline void usbh_hal_port_suspend(usbh_hal_context_t *hal)
|
|||
* @param hal Context of the HAL layer
|
||||
* @param enable Enable/disable resume signal
|
||||
*/
|
||||
static inline void usbh_hal_port_toggle_resume(usbh_hal_context_t *hal, bool enable)
|
||||
static inline void usb_dwc_hal_port_toggle_resume(usb_dwc_hal_context_t *hal, bool enable)
|
||||
{
|
||||
if (enable) {
|
||||
usbh_ll_hprt_set_port_resume(hal->dev);
|
||||
usb_dwc_ll_hprt_set_port_resume(hal->dev);
|
||||
} else {
|
||||
usbh_ll_hprt_clr_port_resume(hal->dev);
|
||||
usb_dwc_ll_hprt_clr_port_resume(hal->dev);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -371,9 +371,9 @@ static inline void usbh_hal_port_toggle_resume(usbh_hal_context_t *hal, bool ena
|
|||
* @return true Resume signal is still being driven
|
||||
* @return false Resume signal is no longer driven
|
||||
*/
|
||||
static inline bool usbh_hal_port_check_resume(usbh_hal_context_t *hal)
|
||||
static inline bool usb_dwc_hal_port_check_resume(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
return usbh_ll_hprt_get_port_resume(hal->dev);
|
||||
return usb_dwc_ll_hprt_get_port_resume(hal->dev);
|
||||
}
|
||||
|
||||
// ---------------- Host Port Scheduling -------------------
|
||||
|
@ -382,13 +382,13 @@ static inline bool usbh_hal_port_check_resume(usbh_hal_context_t *hal)
|
|||
* @brief Sets the periodic scheduling frame list
|
||||
*
|
||||
* @note This function must be called before attempting configuring any channels to be period via
|
||||
* usbh_hal_chan_set_ep_char()
|
||||
* usb_dwc_hal_chan_set_ep_char()
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @param frame_list Base address of the frame list
|
||||
* @param frame_list_len Number of entries in the frame list (can only be 8, 16, 32, 64)
|
||||
*/
|
||||
static inline void usbh_hal_port_set_frame_list(usbh_hal_context_t *hal, uint32_t *frame_list, usb_hal_frame_list_len_t len)
|
||||
static inline void usb_dwc_hal_port_set_frame_list(usb_dwc_hal_context_t *hal, uint32_t *frame_list, usb_hal_frame_list_len_t len)
|
||||
{
|
||||
//Clear and save frame list
|
||||
hal->periodic_frame_list = frame_list;
|
||||
|
@ -401,7 +401,7 @@ static inline void usbh_hal_port_set_frame_list(usbh_hal_context_t *hal, uint32_
|
|||
* @param hal Context of the HAL layer
|
||||
* @return uint32_t* Base address of the periodic scheduling frame list
|
||||
*/
|
||||
static inline uint32_t *usbh_hal_port_get_frame_list(usbh_hal_context_t *hal)
|
||||
static inline uint32_t *usb_dwc_hal_port_get_frame_list(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
return hal->periodic_frame_list;
|
||||
}
|
||||
|
@ -409,18 +409,18 @@ static inline uint32_t *usbh_hal_port_get_frame_list(usbh_hal_context_t *hal)
|
|||
/**
|
||||
* @brief Enable periodic scheduling
|
||||
*
|
||||
* @note The periodic frame list must be set via usbh_hal_port_set_frame_list() should be set before calling this
|
||||
* @note The periodic frame list must be set via usb_dwc_hal_port_set_frame_list() should be set before calling this
|
||||
* function
|
||||
* @note This function must be called before activating any periodic channels
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_port_periodic_enable(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_periodic_enable(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
HAL_ASSERT(hal->periodic_frame_list != NULL);
|
||||
usbh_ll_set_frame_list_base_addr(hal->dev, (uint32_t)hal->periodic_frame_list);
|
||||
usbh_ll_hcfg_set_num_frame_list_entries(hal->dev, hal->frame_list_len);
|
||||
usbh_ll_hcfg_en_perio_sched(hal->dev);
|
||||
usb_dwc_ll_hflbaddr_set_base_addr(hal->dev, (uint32_t)hal->periodic_frame_list);
|
||||
usb_dwc_ll_hcfg_set_num_frame_list_entries(hal->dev, hal->frame_list_len);
|
||||
usb_dwc_ll_hcfg_en_perio_sched(hal->dev);
|
||||
hal->flags.periodic_sched_enabled = 1;
|
||||
}
|
||||
|
||||
|
@ -435,16 +435,16 @@ static inline void usbh_hal_port_periodic_enable(usbh_hal_context_t *hal)
|
|||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_port_periodic_disable(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_port_periodic_disable(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
HAL_ASSERT(hal->flags.periodic_sched_enabled);
|
||||
usbh_ll_hcfg_dis_perio_sched(hal->dev);
|
||||
usb_dwc_ll_hcfg_dis_perio_sched(hal->dev);
|
||||
hal->flags.periodic_sched_enabled = 0;
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_hal_port_get_cur_frame_num(usbh_hal_context_t *hal)
|
||||
static inline uint32_t usb_dwc_hal_port_get_cur_frame_num(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
return usbh_ll_get_frm_num(hal->dev);
|
||||
return usb_dwc_ll_hfnum_get_frame_num(hal->dev);
|
||||
}
|
||||
|
||||
// --------------- Host Port Status/State ------------------
|
||||
|
@ -453,19 +453,19 @@ static inline uint32_t usbh_hal_port_get_cur_frame_num(usbh_hal_context_t *hal)
|
|||
* @brief Check if a device is currently connected to the host port
|
||||
*
|
||||
* This function is intended to be called after one of the following events followed by an adequate debounce delay
|
||||
* - USBH_HAL_PORT_EVENT_CONN
|
||||
* - USBH_HAL_PORT_EVENT_DISCONN
|
||||
* - USB_DWC_HAL_PORT_EVENT_CONN
|
||||
* - USB_DWC_HAL_PORT_EVENT_DISCONN
|
||||
*
|
||||
* @note No other connection/disconnection event will occur again until the debounce lock is disabled via
|
||||
* usbh_hal_disable_debounce_lock()
|
||||
* usb_dwc_hal_disable_debounce_lock()
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @return true A device is connected to the host port
|
||||
* @return false A device is not connected to the host port
|
||||
*/
|
||||
static inline bool usbh_hal_port_check_if_connected(usbh_hal_context_t *hal)
|
||||
static inline bool usb_dwc_hal_port_check_if_connected(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
return usbh_ll_hprt_get_conn_status(hal->dev);
|
||||
return usb_dwc_ll_hprt_get_conn_status(hal->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -476,27 +476,27 @@ static inline bool usbh_hal_port_check_if_connected(usbh_hal_context_t *hal)
|
|||
* @param hal Context of the HAL layer
|
||||
* @return usb_priv_speed_t Speed of the connected device (FS or LS only on the esp32-s2 and esp32-s3)
|
||||
*/
|
||||
static inline usb_priv_speed_t usbh_hal_port_get_conn_speed(usbh_hal_context_t *hal)
|
||||
static inline usb_priv_speed_t usb_dwc_hal_port_get_conn_speed(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
return usbh_ll_hprt_get_speed(hal->dev);
|
||||
return usb_dwc_ll_hprt_get_speed(hal->dev);
|
||||
}
|
||||
|
||||
/**
|
||||
* @brief Disable the debounce lock
|
||||
*
|
||||
* This function must be called after calling usbh_hal_port_check_if_connected() and will allow connection/disconnection
|
||||
* This function must be called after calling usb_dwc_hal_port_check_if_connected() and will allow connection/disconnection
|
||||
* events to occur again. Any pending connection or disconenction interrupts are cleared.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
*/
|
||||
static inline void usbh_hal_disable_debounce_lock(usbh_hal_context_t *hal)
|
||||
static inline void usb_dwc_hal_disable_debounce_lock(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
hal->flags.dbnc_lock_enabled = 0;
|
||||
//Clear Conenction and disconenction interrupt in case it triggered again
|
||||
usb_ll_intr_clear(hal->dev, USB_LL_INTR_CORE_DISCONNINT);
|
||||
usbh_ll_hprt_intr_clear(hal->dev, USBH_LL_INTR_HPRT_PRTCONNDET);
|
||||
usb_dwc_ll_gintsts_clear_intrs(hal->dev, USB_DWC_LL_INTR_CORE_DISCONNINT);
|
||||
usb_dwc_ll_hprt_intr_clear(hal->dev, USB_DWC_LL_INTR_HPRT_PRTCONNDET);
|
||||
//Reenable the hprt (connection) and disconnection interrupts
|
||||
usb_ll_en_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_DISCONNINT);
|
||||
usb_dwc_ll_gintmsk_en_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_DISCONNINT);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------- Channel -------------------------------------------------------
|
||||
|
@ -512,7 +512,7 @@ static inline void usbh_hal_disable_debounce_lock(usbh_hal_context_t *hal)
|
|||
* @return true Channel successfully allocated
|
||||
* @return false Failed to allocate channel
|
||||
*/
|
||||
bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, void *chan_ctx);
|
||||
bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj, void *chan_ctx);
|
||||
|
||||
/**
|
||||
* @brief Free a channel
|
||||
|
@ -520,7 +520,7 @@ bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, voi
|
|||
* @param[in] hal Context of the HAL layer
|
||||
* @param[in] chan_obj Channel object
|
||||
*/
|
||||
void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj);
|
||||
void usb_dwc_hal_chan_free(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj);
|
||||
|
||||
// ---------------- Channel Configuration ------------------
|
||||
|
||||
|
@ -530,7 +530,7 @@ void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj);
|
|||
* @param[in] chan_obj Channel object
|
||||
* @return void* The context variable of the channel
|
||||
*/
|
||||
static inline void *usbh_hal_chan_get_context(usbh_hal_chan_t *chan_obj)
|
||||
static inline void *usb_dwc_hal_chan_get_context(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
return chan_obj->chan_ctx;
|
||||
}
|
||||
|
@ -547,7 +547,7 @@ static inline void *usbh_hal_chan_get_context(usbh_hal_chan_t *chan_obj)
|
|||
* @param chan_obj Channel object
|
||||
* @param ep_char Endpoint characteristics
|
||||
*/
|
||||
void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep_char);
|
||||
void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj, usb_dwc_hal_ep_char_t *ep_char);
|
||||
|
||||
/**
|
||||
* @brief Set the direction of the channel
|
||||
|
@ -561,11 +561,11 @@ void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_ob
|
|||
* @param chan_obj Channel object
|
||||
* @param is_in Whether the direction is IN
|
||||
*/
|
||||
static inline void usbh_hal_chan_set_dir(usbh_hal_chan_t *chan_obj, bool is_in)
|
||||
static inline void usb_dwc_hal_chan_set_dir(usb_dwc_hal_chan_t *chan_obj, bool is_in)
|
||||
{
|
||||
//Cannot change direction whilst channel is still active or in error
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
usbh_ll_chan_set_dir(chan_obj->regs, is_in);
|
||||
usb_dwc_ll_hcchar_set_dir(chan_obj->regs, is_in);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -580,12 +580,12 @@ static inline void usbh_hal_chan_set_dir(usbh_hal_chan_t *chan_obj, bool is_in)
|
|||
* @param chan_obj Channel object
|
||||
* @param pid PID of the next DATA packet (DATA0 or DATA1)
|
||||
*/
|
||||
static inline void usbh_hal_chan_set_pid(usbh_hal_chan_t *chan_obj, int pid)
|
||||
static inline void usb_dwc_hal_chan_set_pid(usb_dwc_hal_chan_t *chan_obj, int pid)
|
||||
{
|
||||
//Cannot change pid whilst channel is still active or in error
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
//Update channel object and set the register
|
||||
usbh_ll_chan_set_pid(chan_obj->regs, pid);
|
||||
usb_dwc_ll_hctsiz_set_pid(chan_obj->regs, pid);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -598,10 +598,10 @@ static inline void usbh_hal_chan_set_pid(usbh_hal_chan_t *chan_obj, int pid)
|
|||
* @param chan_obj Channel object
|
||||
* @return uint32_t Starting PID of the next transfer (DATA0 or DATA1)
|
||||
*/
|
||||
static inline uint32_t usbh_hal_chan_get_pid(usbh_hal_chan_t *chan_obj)
|
||||
static inline uint32_t usb_dwc_hal_chan_get_pid(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
return usbh_ll_chan_get_pid(chan_obj->regs);
|
||||
return usb_dwc_ll_hctsiz_get_pid(chan_obj->regs);
|
||||
}
|
||||
|
||||
// ------------------- Channel Control ---------------------
|
||||
|
@ -619,7 +619,7 @@ static inline uint32_t usbh_hal_chan_get_pid(usbh_hal_chan_t *chan_obj)
|
|||
* @param desc_list_len Transfer descriptor list length
|
||||
* @param start_idx Index of the starting transfer descriptor in the list
|
||||
*/
|
||||
void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx);
|
||||
void usb_dwc_hal_chan_activate(usb_dwc_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx);
|
||||
|
||||
/**
|
||||
* @brief Get the index of the current transfer descriptor
|
||||
|
@ -627,9 +627,9 @@ void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int
|
|||
* @param chan_obj Channel object
|
||||
* @return int Descriptor index
|
||||
*/
|
||||
static inline int usbh_hal_chan_get_qtd_idx(usbh_hal_chan_t *chan_obj)
|
||||
static inline int usb_dwc_hal_chan_get_qtd_idx(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
return usbh_ll_chan_get_ctd(chan_obj->regs);
|
||||
return usb_dwc_ll_hcdam_get_cur_qtd_idx(chan_obj->regs);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -637,24 +637,24 @@ static inline int usbh_hal_chan_get_qtd_idx(usbh_hal_chan_t *chan_obj)
|
|||
*
|
||||
* This function should be called in order to halt a channel. If the channel is already halted, this function will
|
||||
* return true. If the channel is still active, this function will return false and users must wait for the
|
||||
* USBH_HAL_CHAN_EVENT_HALT_REQ event before treating the channel as halted.
|
||||
* USB_DWC_HAL_CHAN_EVENT_HALT_REQ event before treating the channel as halted.
|
||||
*
|
||||
* @note When a transfer is in progress (i.e., the channel is active) and a halt is requested, the channel will halt
|
||||
* after the next USB packet is completed. If the transfer has more pending packets, the transfer will just be
|
||||
* marked as USBH_HAL_XFER_DESC_STS_NOT_EXECUTED.
|
||||
* marked as USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED.
|
||||
*
|
||||
* @param chan_obj Channel object
|
||||
* @return true The channel is already halted
|
||||
* @return false The halt was requested, wait for USBH_HAL_CHAN_EVENT_HALT_REQ
|
||||
* @return false The halt was requested, wait for USB_DWC_HAL_CHAN_EVENT_HALT_REQ
|
||||
*/
|
||||
bool usbh_hal_chan_request_halt(usbh_hal_chan_t *chan_obj);
|
||||
bool usb_dwc_hal_chan_request_halt(usb_dwc_hal_chan_t *chan_obj);
|
||||
|
||||
/**
|
||||
* @brief Indicate that a channel is halted after a port error
|
||||
*
|
||||
* When a port error occurs (e.g., discconect, overcurrent):
|
||||
* - Any previously active channels will remain active (i.e., they will not receive a channel interrupt)
|
||||
* - Attempting to disable them using usbh_hal_chan_request_halt() will NOT generate an interrupt for ISOC channels
|
||||
* - Attempting to disable them using usb_dwc_hal_chan_request_halt() will NOT generate an interrupt for ISOC channels
|
||||
* (probalby something to do with the periodic scheduling)
|
||||
*
|
||||
* However, the channel's enable bit can be left as 1 since after a port error, a soft reset will be done anyways.
|
||||
|
@ -663,7 +663,7 @@ bool usbh_hal_chan_request_halt(usbh_hal_chan_t *chan_obj);
|
|||
*
|
||||
* @param chan_obj Channel object
|
||||
*/
|
||||
static inline void usbh_hal_chan_mark_halted(usbh_hal_chan_t *chan_obj)
|
||||
static inline void usb_dwc_hal_chan_mark_halted(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
chan_obj->flags.active = 0;
|
||||
}
|
||||
|
@ -672,9 +672,9 @@ static inline void usbh_hal_chan_mark_halted(usbh_hal_chan_t *chan_obj)
|
|||
* @brief Get a channel's error
|
||||
*
|
||||
* @param chan_obj Channel object
|
||||
* @return usbh_hal_chan_error_t The type of error the channel has encountered
|
||||
* @return usb_dwc_hal_chan_error_t The type of error the channel has encountered
|
||||
*/
|
||||
static inline usbh_hal_chan_error_t usbh_hal_chan_get_error(usbh_hal_chan_t *chan_obj)
|
||||
static inline usb_dwc_hal_chan_error_t usb_dwc_hal_chan_get_error(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
return chan_obj->error;
|
||||
}
|
||||
|
@ -688,8 +688,8 @@ static inline usbh_hal_chan_error_t usbh_hal_chan_get_error(usbh_hal_chan_t *cha
|
|||
* - A stage of a transfer (for control transfers)
|
||||
* - A frame of a transfer interval (for interrupt and isoc)
|
||||
* - An entire transfer (for bulk transfers)
|
||||
* - Check the various USBH_HAL_XFER_DESC_FLAG_ flags for filling a specific type of descriptor
|
||||
* - For IN transfer entries, set the USBH_HAL_XFER_DESC_FLAG_IN. The transfer size must also be an integer multiple of
|
||||
* - Check the various USB_DWC_HAL_XFER_DESC_FLAG_ flags for filling a specific type of descriptor
|
||||
* - For IN transfer entries, set the USB_DWC_HAL_XFER_DESC_FLAG_IN. The transfer size must also be an integer multiple of
|
||||
* the endpoint's MPS
|
||||
*
|
||||
* @note Critical section is not required for this function
|
||||
|
@ -700,19 +700,19 @@ static inline usbh_hal_chan_error_t usbh_hal_chan_get_error(usbh_hal_chan_t *cha
|
|||
* @param xfer_len Transfer length
|
||||
* @param flags Transfer flags
|
||||
*/
|
||||
static inline void usbh_hal_xfer_desc_fill(void *desc_list, uint32_t desc_idx, uint8_t *xfer_data_buff, int xfer_len, uint32_t flags)
|
||||
static inline void usb_dwc_hal_xfer_desc_fill(void *desc_list, uint32_t desc_idx, uint8_t *xfer_data_buff, int xfer_len, uint32_t flags)
|
||||
{
|
||||
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
|
||||
if (flags & USBH_HAL_XFER_DESC_FLAG_IN) {
|
||||
usbh_ll_set_qtd_in(&qtd_list[desc_idx],
|
||||
usb_dwc_ll_dma_qtd_t *qtd_list = (usb_dwc_ll_dma_qtd_t *)desc_list;
|
||||
if (flags & USB_DWC_HAL_XFER_DESC_FLAG_IN) {
|
||||
usb_dwc_ll_qtd_set_in(&qtd_list[desc_idx],
|
||||
xfer_data_buff, xfer_len,
|
||||
flags & USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
flags & USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
} else {
|
||||
usbh_ll_set_qtd_out(&qtd_list[desc_idx],
|
||||
usb_dwc_ll_qtd_set_out(&qtd_list[desc_idx],
|
||||
xfer_data_buff,
|
||||
xfer_len,
|
||||
flags & USBH_HAL_XFER_DESC_FLAG_HOC,
|
||||
flags & USBH_HAL_XFER_DESC_FLAG_SETUP);
|
||||
flags & USB_DWC_HAL_XFER_DESC_FLAG_HOC,
|
||||
flags & USB_DWC_HAL_XFER_DESC_FLAG_SETUP);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -722,10 +722,10 @@ static inline void usbh_hal_xfer_desc_fill(void *desc_list, uint32_t desc_idx, u
|
|||
* @param desc_list Transfer descriptor list
|
||||
* @param desc_idx Transfer descriptor index
|
||||
*/
|
||||
static inline void usbh_hal_xfer_desc_clear(void *desc_list, uint32_t desc_idx)
|
||||
static inline void usb_dwc_hal_xfer_desc_clear(void *desc_list, uint32_t desc_idx)
|
||||
{
|
||||
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
|
||||
usbh_ll_set_qtd_null(&qtd_list[desc_idx]);
|
||||
usb_dwc_ll_dma_qtd_t *qtd_list = (usb_dwc_ll_dma_qtd_t *)desc_list;
|
||||
usb_dwc_ll_qtd_set_null(&qtd_list[desc_idx]);
|
||||
}
|
||||
|
||||
/**
|
||||
|
@ -738,12 +738,12 @@ static inline void usbh_hal_xfer_desc_clear(void *desc_list, uint32_t desc_idx)
|
|||
*
|
||||
* @note Critical section is not required for this function
|
||||
*/
|
||||
static inline void usbh_hal_xfer_desc_parse(void *desc_list, uint32_t desc_idx, int *xfer_rem_len, int *xfer_status)
|
||||
static inline void usb_dwc_hal_xfer_desc_parse(void *desc_list, uint32_t desc_idx, int *xfer_rem_len, int *xfer_status)
|
||||
{
|
||||
usbh_ll_dma_qtd_t *qtd_list = (usbh_ll_dma_qtd_t *)desc_list;
|
||||
usbh_ll_get_qtd_status(&qtd_list[desc_idx], xfer_rem_len, xfer_status);
|
||||
usb_dwc_ll_dma_qtd_t *qtd_list = (usb_dwc_ll_dma_qtd_t *)desc_list;
|
||||
usb_dwc_ll_qtd_get_status(&qtd_list[desc_idx], xfer_rem_len, xfer_status);
|
||||
//Clear the QTD to prevent it from being read again
|
||||
usbh_ll_set_qtd_null(&qtd_list[desc_idx]);
|
||||
usb_dwc_ll_qtd_set_null(&qtd_list[desc_idx]);
|
||||
}
|
||||
|
||||
// ------------------------------------------------- Event Handling ----------------------------------------------------
|
||||
|
@ -757,9 +757,9 @@ static inline void usbh_hal_xfer_desc_parse(void *desc_list, uint32_t desc_idx,
|
|||
* @note This should be the first interrupt decode function to be run
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @return usbh_hal_port_event_t Host port event
|
||||
* @return usb_dwc_hal_port_event_t Host port event
|
||||
*/
|
||||
usbh_hal_port_event_t usbh_hal_decode_intr(usbh_hal_context_t *hal);
|
||||
usb_dwc_hal_port_event_t usb_dwc_hal_decode_intr(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Gets the next channel with a pending interrupt
|
||||
|
@ -768,9 +768,9 @@ usbh_hal_port_event_t usbh_hal_decode_intr(usbh_hal_context_t *hal);
|
|||
* interrupt, this function returns one of the channel's objects. Call this function repeatedly until it returns NULL.
|
||||
*
|
||||
* @param hal Context of the HAL layer
|
||||
* @return usbh_hal_chan_t* Channel object. NULL if no channel are pending an interrupt.
|
||||
* @return usb_dwc_hal_chan_t* Channel object. NULL if no channel are pending an interrupt.
|
||||
*/
|
||||
usbh_hal_chan_t *usbh_hal_get_chan_pending_intr(usbh_hal_context_t *hal);
|
||||
usb_dwc_hal_chan_t *usb_dwc_hal_get_chan_pending_intr(usb_dwc_hal_context_t *hal);
|
||||
|
||||
/**
|
||||
* @brief Decode a particular channel's interrupt
|
||||
|
@ -781,9 +781,9 @@ usbh_hal_chan_t *usbh_hal_get_chan_pending_intr(usbh_hal_context_t *hal);
|
|||
* @param chan_obj Channel object
|
||||
* @note If the host port has an error (e.g., a sudden disconnect or an port error), any active channels will not
|
||||
* receive an interrupt. Each active channel must be manually halted.
|
||||
* @return usbh_hal_chan_event_t Channel event
|
||||
* @return usb_dwc_hal_chan_event_t Channel event
|
||||
*/
|
||||
usbh_hal_chan_event_t usbh_hal_chan_decode_intr(usbh_hal_chan_t *chan_obj);
|
||||
usb_dwc_hal_chan_event_t usb_dwc_hal_chan_decode_intr(usb_dwc_hal_chan_t *chan_obj);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
|
@ -12,7 +12,7 @@ extern "C" {
|
|||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "soc/usbh_struct.h"
|
||||
#include "soc/usb_dwc_struct.h"
|
||||
#include "hal/usb_types_private.h"
|
||||
#include "hal/misc.h"
|
||||
|
||||
|
@ -24,48 +24,48 @@ extern "C" {
|
|||
/*
|
||||
* Interrupt bit masks of the GINTSTS and GINTMSK registers
|
||||
*/
|
||||
#define USB_LL_INTR_CORE_WKUPINT (1 << 31)
|
||||
#define USB_LL_INTR_CORE_SESSREQINT (1 << 30)
|
||||
#define USB_LL_INTR_CORE_DISCONNINT (1 << 29)
|
||||
#define USB_LL_INTR_CORE_CONIDSTSCHNG (1 << 28)
|
||||
#define USB_LL_INTR_CORE_PTXFEMP (1 << 26)
|
||||
#define USB_LL_INTR_CORE_HCHINT (1 << 25)
|
||||
#define USB_LL_INTR_CORE_PRTINT (1 << 24)
|
||||
#define USB_LL_INTR_CORE_RESETDET (1 << 23)
|
||||
#define USB_LL_INTR_CORE_FETSUSP (1 << 22)
|
||||
#define USB_LL_INTR_CORE_INCOMPIP (1 << 21)
|
||||
#define USB_LL_INTR_CORE_INCOMPISOIN (1 << 20)
|
||||
#define USB_LL_INTR_CORE_OEPINT (1 << 19)
|
||||
#define USB_LL_INTR_CORE_IEPINT (1 << 18)
|
||||
#define USB_LL_INTR_CORE_EPMIS (1 << 17)
|
||||
#define USB_LL_INTR_CORE_EOPF (1 << 15)
|
||||
#define USB_LL_INTR_CORE_ISOOUTDROP (1 << 14)
|
||||
#define USB_LL_INTR_CORE_ENUMDONE (1 << 13)
|
||||
#define USB_LL_INTR_CORE_USBRST (1 << 12)
|
||||
#define USB_LL_INTR_CORE_USBSUSP (1 << 11)
|
||||
#define USB_LL_INTR_CORE_ERLYSUSP (1 << 10)
|
||||
#define USB_LL_INTR_CORE_GOUTNAKEFF (1 << 7)
|
||||
#define USB_LL_INTR_CORE_GINNAKEFF (1 << 6)
|
||||
#define USB_LL_INTR_CORE_NPTXFEMP (1 << 5)
|
||||
#define USB_LL_INTR_CORE_RXFLVL (1 << 4)
|
||||
#define USB_LL_INTR_CORE_SOF (1 << 3)
|
||||
#define USB_LL_INTR_CORE_OTGINT (1 << 2)
|
||||
#define USB_LL_INTR_CORE_MODEMIS (1 << 1)
|
||||
#define USB_LL_INTR_CORE_CURMOD (1 << 0)
|
||||
#define USB_DWC_LL_INTR_CORE_WKUPINT (1 << 31)
|
||||
#define USB_DWC_LL_INTR_CORE_SESSREQINT (1 << 30)
|
||||
#define USB_DWC_LL_INTR_CORE_DISCONNINT (1 << 29)
|
||||
#define USB_DWC_LL_INTR_CORE_CONIDSTSCHNG (1 << 28)
|
||||
#define USB_DWC_LL_INTR_CORE_PTXFEMP (1 << 26)
|
||||
#define USB_DWC_LL_INTR_CORE_HCHINT (1 << 25)
|
||||
#define USB_DWC_LL_INTR_CORE_PRTINT (1 << 24)
|
||||
#define USB_DWC_LL_INTR_CORE_RESETDET (1 << 23)
|
||||
#define USB_DWC_LL_INTR_CORE_FETSUSP (1 << 22)
|
||||
#define USB_DWC_LL_INTR_CORE_INCOMPIP (1 << 21)
|
||||
#define USB_DWC_LL_INTR_CORE_INCOMPISOIN (1 << 20)
|
||||
#define USB_DWC_LL_INTR_CORE_OEPINT (1 << 19)
|
||||
#define USB_DWC_LL_INTR_CORE_IEPINT (1 << 18)
|
||||
#define USB_DWC_LL_INTR_CORE_EPMIS (1 << 17)
|
||||
#define USB_DWC_LL_INTR_CORE_EOPF (1 << 15)
|
||||
#define USB_DWC_LL_INTR_CORE_ISOOUTDROP (1 << 14)
|
||||
#define USB_DWC_LL_INTR_CORE_ENUMDONE (1 << 13)
|
||||
#define USB_DWC_LL_INTR_CORE_USBRST (1 << 12)
|
||||
#define USB_DWC_LL_INTR_CORE_USBSUSP (1 << 11)
|
||||
#define USB_DWC_LL_INTR_CORE_ERLYSUSP (1 << 10)
|
||||
#define USB_DWC_LL_INTR_CORE_GOUTNAKEFF (1 << 7)
|
||||
#define USB_DWC_LL_INTR_CORE_GINNAKEFF (1 << 6)
|
||||
#define USB_DWC_LL_INTR_CORE_NPTXFEMP (1 << 5)
|
||||
#define USB_DWC_LL_INTR_CORE_RXFLVL (1 << 4)
|
||||
#define USB_DWC_LL_INTR_CORE_SOF (1 << 3)
|
||||
#define USB_DWC_LL_INTR_CORE_OTGINT (1 << 2)
|
||||
#define USB_DWC_LL_INTR_CORE_MODEMIS (1 << 1)
|
||||
#define USB_DWC_LL_INTR_CORE_CURMOD (1 << 0)
|
||||
|
||||
/*
|
||||
* Bit mask of interrupt generating bits of the the HPRT register. These bits
|
||||
* are ORd into the USB_LL_INTR_CORE_PRTINT interrupt.
|
||||
* are ORd into the USB_DWC_LL_INTR_CORE_PRTINT interrupt.
|
||||
*
|
||||
* Note: Some fields of the HPRT are W1C (write 1 clear), this we cannot do a
|
||||
* simple read and write-back to clear the HPRT interrupt bits. Instead we need
|
||||
* a W1C mask the non-interrupt related bits
|
||||
*/
|
||||
#define USBH_LL_HPRT_W1C_MSK (0x2E)
|
||||
#define USBH_LL_HPRT_ENA_MSK (0x04)
|
||||
#define USBH_LL_INTR_HPRT_PRTOVRCURRCHNG (1 << 5)
|
||||
#define USBH_LL_INTR_HPRT_PRTENCHNG (1 << 3)
|
||||
#define USBH_LL_INTR_HPRT_PRTCONNDET (1 << 1)
|
||||
#define USB_DWC_LL_HPRT_W1C_MSK (0x2E)
|
||||
#define USB_DWC_LL_HPRT_ENA_MSK (0x04)
|
||||
#define USB_DWC_LL_INTR_HPRT_PRTOVRCURRCHNG (1 << 5)
|
||||
#define USB_DWC_LL_INTR_HPRT_PRTENCHNG (1 << 3)
|
||||
#define USB_DWC_LL_INTR_HPRT_PRTCONNDET (1 << 1)
|
||||
|
||||
/*
|
||||
* Bit mask of channel interrupts (HCINTi and HCINTMSKi registers)
|
||||
|
@ -78,22 +78,22 @@ extern "C" {
|
|||
* - XFERCOMPL
|
||||
* The remaining interrupt bits will still be set (when the corresponding event occurs)
|
||||
* but will not generate an interrupt. Therefore we must proxy through the
|
||||
* USBH_LL_INTR_CHAN_CHHLTD interrupt to check the other interrupt bits.
|
||||
* USB_DWC_LL_INTR_CHAN_CHHLTD interrupt to check the other interrupt bits.
|
||||
*/
|
||||
#define USBH_LL_INTR_CHAN_DESC_LS_ROLL (1 << 13)
|
||||
#define USBH_LL_INTR_CHAN_XCS_XACT_ERR (1 << 12)
|
||||
#define USBH_LL_INTR_CHAN_BNAINTR (1 << 11)
|
||||
#define USBH_LL_INTR_CHAN_DATATGLERR (1 << 10)
|
||||
#define USBH_LL_INTR_CHAN_FRMOVRUN (1 << 9)
|
||||
#define USBH_LL_INTR_CHAN_BBLEER (1 << 8)
|
||||
#define USBH_LL_INTR_CHAN_XACTERR (1 << 7)
|
||||
#define USBH_LL_INTR_CHAN_NYET (1 << 6)
|
||||
#define USBH_LL_INTR_CHAN_ACK (1 << 5)
|
||||
#define USBH_LL_INTR_CHAN_NAK (1 << 4)
|
||||
#define USBH_LL_INTR_CHAN_STALL (1 << 3)
|
||||
#define USBH_LL_INTR_CHAN_AHBERR (1 << 2)
|
||||
#define USBH_LL_INTR_CHAN_CHHLTD (1 << 1)
|
||||
#define USBH_LL_INTR_CHAN_XFERCOMPL (1 << 0)
|
||||
#define USB_DWC_LL_INTR_CHAN_DESC_LS_ROLL (1 << 13)
|
||||
#define USB_DWC_LL_INTR_CHAN_XCS_XACT_ERR (1 << 12)
|
||||
#define USB_DWC_LL_INTR_CHAN_BNAINTR (1 << 11)
|
||||
#define USB_DWC_LL_INTR_CHAN_DATATGLERR (1 << 10)
|
||||
#define USB_DWC_LL_INTR_CHAN_FRMOVRUN (1 << 9)
|
||||
#define USB_DWC_LL_INTR_CHAN_BBLEER (1 << 8)
|
||||
#define USB_DWC_LL_INTR_CHAN_XACTERR (1 << 7)
|
||||
#define USB_DWC_LL_INTR_CHAN_NYET (1 << 6)
|
||||
#define USB_DWC_LL_INTR_CHAN_ACK (1 << 5)
|
||||
#define USB_DWC_LL_INTR_CHAN_NAK (1 << 4)
|
||||
#define USB_DWC_LL_INTR_CHAN_STALL (1 << 3)
|
||||
#define USB_DWC_LL_INTR_CHAN_AHBERR (1 << 2)
|
||||
#define USB_DWC_LL_INTR_CHAN_CHHLTD (1 << 1)
|
||||
#define USB_DWC_LL_INTR_CHAN_XFERCOMPL (1 << 0)
|
||||
|
||||
/*
|
||||
* QTD (Queue Transfer Descriptor) structure used in Scatter/Gather DMA mode.
|
||||
|
@ -150,7 +150,7 @@ typedef struct {
|
|||
uint32_t buffer_status_val;
|
||||
};
|
||||
uint8_t *buffer;
|
||||
} usbh_ll_dma_qtd_t;
|
||||
} usb_dwc_ll_dma_qtd_t;
|
||||
|
||||
|
||||
/* -----------------------------------------------------------------------------
|
||||
|
@ -159,61 +159,61 @@ typedef struct {
|
|||
|
||||
// --------------------------- GAHBCFG Register --------------------------------
|
||||
|
||||
static inline void usb_ll_en_dma_mode(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gahbcfg_en_dma_mode(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gahbcfg_reg.dmaen = 1;
|
||||
}
|
||||
|
||||
static inline void usb_ll_en_slave_mode(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gahbcfg_en_slave_mode(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gahbcfg_reg.dmaen = 0;
|
||||
}
|
||||
|
||||
static inline void usb_ll_set_hbstlen(usbh_dev_t *hw, uint32_t burst_len)
|
||||
static inline void usb_dwc_ll_gahbcfg_set_hbstlen(usb_dwc_dev_t *hw, uint32_t burst_len)
|
||||
{
|
||||
hw->gahbcfg_reg.hbstlen = burst_len;
|
||||
}
|
||||
|
||||
static inline void usb_ll_en_global_intr(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gahbcfg_en_global_intr(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gahbcfg_reg.glbllntrmsk = 1;
|
||||
}
|
||||
|
||||
static inline void usb_ll_dis_global_intr(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gahbcfg_dis_global_intr(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gahbcfg_reg.glbllntrmsk = 0;
|
||||
}
|
||||
|
||||
// --------------------------- GUSBCFG Register --------------------------------
|
||||
|
||||
static inline void usb_ll_set_host_mode(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gusbcfg_force_host_mode(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gusbcfg_reg.forcehstmode = 1;
|
||||
}
|
||||
|
||||
static inline void usb_ll_dis_hnp_cap(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gusbcfg_dis_hnp_cap(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gusbcfg_reg.hnpcap = 0;
|
||||
}
|
||||
|
||||
static inline void usb_ll_dis_srp_cap(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_gusbcfg_dis_srp_cap(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->gusbcfg_reg.srpcap = 0;
|
||||
}
|
||||
|
||||
// --------------------------- GRSTCTL Register --------------------------------
|
||||
|
||||
static inline bool usb_ll_check_ahb_idle(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_grstctl_is_ahb_idle(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->grstctl_reg.ahbidle;
|
||||
}
|
||||
|
||||
static inline bool usb_ll_check_dma_req_in_progress(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_grstctl_is_dma_req_in_progress(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->grstctl_reg.dmareq;
|
||||
}
|
||||
|
||||
static inline void usb_ll_flush_nptx_fifo(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_grstctl_flush_nptx_fifo(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->grstctl_reg.txfnum = 0; //Set the TX FIFO number to 0 to select the non-periodic TX FIFO
|
||||
hw->grstctl_reg.txfflsh = 1; //Flush the selected TX FIFO
|
||||
|
@ -223,7 +223,7 @@ static inline void usb_ll_flush_nptx_fifo(usbh_dev_t *hw)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void usb_ll_flush_ptx_fifo(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_grstctl_flush_ptx_fifo(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->grstctl_reg.txfnum = 1; //Set the TX FIFO number to 1 to select the periodic TX FIFO
|
||||
hw->grstctl_reg.txfflsh = 1; //FLush the select TX FIFO
|
||||
|
@ -233,7 +233,7 @@ static inline void usb_ll_flush_ptx_fifo(usbh_dev_t *hw)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void usb_ll_flush_rx_fifo(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_grstctl_flush_rx_fifo(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->grstctl_reg.rxfflsh = 1;
|
||||
//Wait for the flushing to complete
|
||||
|
@ -242,17 +242,17 @@ static inline void usb_ll_flush_rx_fifo(usbh_dev_t *hw)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void usb_ll_reset_frame_counter(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_grstctl_reset_frame_counter(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->grstctl_reg.frmcntrrst = 1;
|
||||
}
|
||||
|
||||
static inline void usb_ll_core_soft_reset(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_grstctl_core_soft_reset(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->grstctl_reg.csftrst = 1;
|
||||
}
|
||||
|
||||
static inline bool usb_ll_check_core_soft_reset(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_grstctl_is_core_soft_reset_in_progress(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->grstctl_reg.csftrst;
|
||||
}
|
||||
|
@ -265,9 +265,9 @@ static inline bool usb_ll_check_core_soft_reset(usbh_dev_t *hw)
|
|||
* @param hw Start address of the DWC_OTG registers
|
||||
* @return uint32_t Mask of interrupts
|
||||
*/
|
||||
static inline uint32_t usb_ll_intr_read_and_clear(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_gintsts_read_and_clear_intrs(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_gintsts_reg_t gintsts;
|
||||
usb_dwc_gintsts_reg_t gintsts;
|
||||
gintsts.val = hw->gintsts_reg.val;
|
||||
hw->gintsts_reg.val = gintsts.val; //Write back to clear
|
||||
return gintsts.val;
|
||||
|
@ -279,7 +279,7 @@ static inline uint32_t usb_ll_intr_read_and_clear(usbh_dev_t *hw)
|
|||
* @param hw Start address of the DWC_OTG registers
|
||||
* @param intr_msk Mask of interrupts to clear
|
||||
*/
|
||||
static inline void usb_ll_intr_clear(usbh_dev_t *hw, uint32_t intr_msk)
|
||||
static inline void usb_dwc_ll_gintsts_clear_intrs(usb_dwc_dev_t *hw, uint32_t intr_msk)
|
||||
{
|
||||
//All GINTSTS fields are either W1C or read only. So safe to write directly
|
||||
hw->gintsts_reg.val = intr_msk;
|
||||
|
@ -287,19 +287,19 @@ static inline void usb_ll_intr_clear(usbh_dev_t *hw, uint32_t intr_msk)
|
|||
|
||||
// --------------------------- GINTMSK Register --------------------------------
|
||||
|
||||
static inline void usb_ll_en_intrs(usbh_dev_t *hw, uint32_t intr_mask)
|
||||
static inline void usb_dwc_ll_gintmsk_en_intrs(usb_dwc_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->gintmsk_reg.val |= intr_mask;
|
||||
}
|
||||
|
||||
static inline void usb_ll_dis_intrs(usbh_dev_t *hw, uint32_t intr_mask)
|
||||
static inline void usb_dwc_ll_gintmsk_dis_intrs(usb_dwc_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
hw->gintmsk_reg.val &= ~intr_mask;
|
||||
}
|
||||
|
||||
// --------------------------- GRXFSIZ Register --------------------------------
|
||||
|
||||
static inline void usb_ll_set_rx_fifo_size(usbh_dev_t *hw, uint32_t num_lines)
|
||||
static inline void usb_dwc_ll_grxfsiz_set_fifo_size(usb_dwc_dev_t *hw, uint32_t num_lines)
|
||||
{
|
||||
//Set size in words
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hw->grxfsiz_reg, rxfdep, num_lines);
|
||||
|
@ -307,20 +307,24 @@ static inline void usb_ll_set_rx_fifo_size(usbh_dev_t *hw, uint32_t num_lines)
|
|||
|
||||
// -------------------------- GNPTXFSIZ Register -------------------------------
|
||||
|
||||
static inline void usb_ll_set_nptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t num_lines)
|
||||
static inline void usb_dwc_ll_gnptxfsiz_set_fifo_size(usb_dwc_dev_t *hw, uint32_t addr, uint32_t num_lines)
|
||||
{
|
||||
usb_gnptxfsiz_reg_t gnptxfsiz;
|
||||
usb_dwc_gnptxfsiz_reg_t gnptxfsiz;
|
||||
gnptxfsiz.val = hw->gnptxfsiz_reg.val;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(gnptxfsiz, nptxfstaddr, addr);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(gnptxfsiz, nptxfdep, num_lines);
|
||||
hw->gnptxfsiz_reg.val = gnptxfsiz.val;
|
||||
}
|
||||
|
||||
static inline uint32_t usb_ll_get_controller_core_id(usbh_dev_t *hw)
|
||||
// --------------------------- GSNPSID Register --------------------------------
|
||||
|
||||
static inline uint32_t usb_dwc_ll_gsnpsid_get_id(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->gsnpsid_reg.val;
|
||||
}
|
||||
|
||||
// --------------------------- GHWCFGx Register --------------------------------
|
||||
|
||||
/**
|
||||
* @brief Get the hardware configuration regiters of the DWC_OTG controller
|
||||
*
|
||||
|
@ -333,7 +337,7 @@ static inline uint32_t usb_ll_get_controller_core_id(usbh_dev_t *hw)
|
|||
* @param[out] ghwcfg3 Hardware configuration registesr 3
|
||||
* @param[out] ghwcfg4 Hardware configuration registesr 4
|
||||
*/
|
||||
static inline void usb_ll_get_hardware_config(usbh_dev_t *hw, uint32_t *ghwcfg1, uint32_t *ghwcfg2, uint32_t *ghwcfg3, uint32_t *ghwcfg4)
|
||||
static inline void usb_dwc_ll_ghwcfg_get_hw_config(usb_dwc_dev_t *hw, uint32_t *ghwcfg1, uint32_t *ghwcfg2, uint32_t *ghwcfg3, uint32_t *ghwcfg4)
|
||||
{
|
||||
*ghwcfg1 = hw->ghwcfg1_reg.val;
|
||||
*ghwcfg2 = hw->ghwcfg2_reg.val;
|
||||
|
@ -343,9 +347,9 @@ static inline void usb_ll_get_hardware_config(usbh_dev_t *hw, uint32_t *ghwcfg1,
|
|||
|
||||
// --------------------------- HPTXFSIZ Register -------------------------------
|
||||
|
||||
static inline void usbh_ll_set_ptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint32_t num_lines)
|
||||
static inline void usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(usb_dwc_dev_t *hw, uint32_t addr, uint32_t num_lines)
|
||||
{
|
||||
usb_hptxfsiz_reg_t hptxfsiz;
|
||||
usb_dwc_hptxfsiz_reg_t hptxfsiz;
|
||||
hptxfsiz.val = hw->hptxfsiz_reg.val;
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hptxfsiz, ptxfstaddr, addr);
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(hptxfsiz, ptxfsize, num_lines);
|
||||
|
@ -358,12 +362,12 @@ static inline void usbh_ll_set_ptx_fifo_size(usbh_dev_t *hw, uint32_t addr, uint
|
|||
|
||||
// ----------------------------- HCFG Register ---------------------------------
|
||||
|
||||
static inline void usbh_ll_hcfg_en_perio_sched(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hcfg_en_perio_sched(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->hcfg_reg.perschedena = 1;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hcfg_dis_perio_sched(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hcfg_dis_perio_sched(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->hcfg_reg.perschedena = 0;
|
||||
}
|
||||
|
@ -373,7 +377,7 @@ static inline void usbh_ll_hcfg_dis_perio_sched(usbh_dev_t *hw)
|
|||
*
|
||||
* @param num_entires Number of entires in the frame list
|
||||
*/
|
||||
static inline void usbh_ll_hcfg_set_num_frame_list_entries(usbh_dev_t *hw, usb_hal_frame_list_len_t num_entries)
|
||||
static inline void usb_dwc_ll_hcfg_set_num_frame_list_entries(usb_dwc_dev_t *hw, usb_hal_frame_list_len_t num_entries)
|
||||
{
|
||||
uint32_t frlisten;
|
||||
switch (num_entries) {
|
||||
|
@ -393,17 +397,17 @@ static inline void usbh_ll_hcfg_set_num_frame_list_entries(usbh_dev_t *hw, usb_h
|
|||
hw->hcfg_reg.frlisten = frlisten;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hcfg_en_scatt_gatt_dma(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hcfg_en_scatt_gatt_dma(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->hcfg_reg.descdma = 1;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hcfg_set_fsls_supp_only(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hcfg_set_fsls_supp_only(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->hcfg_reg.fslssupp = 1;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hcfg_set_fsls_pclk_sel(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hcfg_set_fsls_pclk_sel(usb_dwc_dev_t *hw)
|
||||
{
|
||||
hw->hcfg_reg.fslspclksel = 1;
|
||||
}
|
||||
|
@ -414,7 +418,7 @@ static inline void usbh_ll_hcfg_set_fsls_pclk_sel(usbh_dev_t *hw)
|
|||
* @param hw Start address of the DWC_OTG registers
|
||||
* @param speed Speed to initialize the host port at
|
||||
*/
|
||||
static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
|
||||
static inline void usb_dwc_ll_hcfg_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed)
|
||||
{
|
||||
hw->hcfg_reg.descdma = 1; //Enable scatt/gatt
|
||||
hw->hcfg_reg.fslssupp = 1; //FS/LS support only
|
||||
|
@ -429,9 +433,9 @@ static inline void usbh_ll_hcfg_set_defaults(usbh_dev_t *hw, usb_priv_speed_t sp
|
|||
|
||||
// ----------------------------- HFIR Register ---------------------------------
|
||||
|
||||
static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_priv_speed_t speed)
|
||||
static inline void usb_dwc_ll_hfir_set_defaults(usb_dwc_dev_t *hw, usb_priv_speed_t speed)
|
||||
{
|
||||
usb_hfir_reg_t hfir;
|
||||
usb_dwc_hfir_reg_t hfir;
|
||||
hfir.val = hw->hfir_reg.val;
|
||||
hfir.hfirrldctrl = 0; //Disable dynamic loading
|
||||
/*
|
||||
|
@ -445,49 +449,49 @@ static inline void usbh_ll_hfir_set_defaults(usbh_dev_t *hw, usb_priv_speed_t sp
|
|||
|
||||
// ----------------------------- HFNUM Register --------------------------------
|
||||
|
||||
static inline uint32_t usbh_ll_get_frm_time_rem(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hfnum_get_frame_time_rem(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(hw->hfnum_reg, frrem);
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_get_frm_num(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hfnum_get_frame_num(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hfnum_reg.frnum;
|
||||
}
|
||||
|
||||
// ---------------------------- HPTXSTS Register -------------------------------
|
||||
|
||||
static inline uint32_t usbh_ll_get_p_tx_queue_top(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hptxsts_get_ptxq_top(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(hw->hptxsts_reg, ptxqtop);
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_get_p_tx_queue_space_avail(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hptxsts_get_ptxq_space_avail(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hptxsts_reg.ptxqspcavail;
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_get_p_tx_fifo_space_avail(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_ptxsts_get_ptxf_space_avail(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(hw->hptxsts_reg, ptxfspcavail);
|
||||
}
|
||||
|
||||
// ----------------------------- HAINT Register --------------------------------
|
||||
|
||||
static inline uint32_t usbh_ll_get_chan_intrs_msk(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_haint_get_chan_intrs(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return HAL_FORCE_READ_U32_REG_FIELD(hw->haint_reg, haint);
|
||||
}
|
||||
|
||||
// --------------------------- HAINTMSK Register -------------------------------
|
||||
|
||||
static inline void usbh_ll_haintmsk_en_chan_intr(usbh_dev_t *hw, uint32_t mask)
|
||||
static inline void usb_dwc_ll_haintmsk_en_chan_intr(usb_dwc_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
|
||||
hw->haintmsk_reg.val |= mask;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_haintmsk_dis_chan_intr(usbh_dev_t *hw, uint32_t mask)
|
||||
static inline void usb_dwc_ll_haintmsk_dis_chan_intr(usb_dwc_dev_t *hw, uint32_t mask)
|
||||
{
|
||||
hw->haintmsk_reg.val &= ~mask;
|
||||
}
|
||||
|
@ -504,7 +508,7 @@ static inline void usbh_ll_haintmsk_dis_chan_intr(usbh_dev_t *hw, uint32_t mask)
|
|||
* @param hw Start address of the DWC_OTG registers
|
||||
* @param addr Base address of the scheduling frame list
|
||||
*/
|
||||
static inline void usbh_ll_set_frame_list_base_addr(usbh_dev_t *hw, uint32_t addr)
|
||||
static inline void usb_dwc_ll_hflbaddr_set_base_addr(usb_dwc_dev_t *hw, uint32_t addr)
|
||||
{
|
||||
hw->hflbaddr_reg.hflbaddr = addr;
|
||||
}
|
||||
|
@ -515,14 +519,14 @@ static inline void usbh_ll_set_frame_list_base_addr(usbh_dev_t *hw, uint32_t add
|
|||
* @param hw Start address of the DWC_OTG registers
|
||||
* @return uint32_t Base address of the scheduling frame list
|
||||
*/
|
||||
static inline uint32_t usbh_ll_get_frame_list_base_addr(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hflbaddr_get_base_addr(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hflbaddr_reg.hflbaddr;
|
||||
}
|
||||
|
||||
// ----------------------------- HPRT Register ---------------------------------
|
||||
|
||||
static inline usb_priv_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
|
||||
static inline usb_priv_speed_t usb_dwc_ll_hprt_get_speed(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_priv_speed_t speed;
|
||||
//esp32-s2 and esp32-s3 only support FS or LS
|
||||
|
@ -537,163 +541,163 @@ static inline usb_priv_speed_t usbh_ll_hprt_get_speed(usbh_dev_t *hw)
|
|||
return speed;
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_hprt_get_test_ctl(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hprt_get_test_ctl(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prttstctl;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_set_test_ctl(usbh_dev_t *hw, uint32_t test_mode)
|
||||
static inline void usb_dwc_ll_hprt_set_test_ctl(usb_dwc_dev_t *hw, uint32_t test_mode)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prttstctl = test_mode;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_en_pwr(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_en_pwr(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtpwr = 1;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_dis_pwr(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_dis_pwr(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtpwr = 0;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_hprt_get_pwr_line_status(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hprt_get_pwr_line_status(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtlnsts;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_set_port_reset(usbh_dev_t *hw, bool reset)
|
||||
static inline void usb_dwc_ll_hprt_set_port_reset(usb_dwc_dev_t *hw, bool reset)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtrst = reset;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_port_reset(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_port_reset(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtrst;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_set_port_suspend(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_set_port_suspend(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtsusp = 1;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_port_suspend(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_port_suspend(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtsusp;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_set_port_resume(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_set_port_resume(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtres = 1;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_clr_port_resume(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_clr_port_resume(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtres = 0;
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_W1C_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_W1C_MSK);
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_port_resume(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_port_resume(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtres;
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_port_overcur(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_port_overcur(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtovrcurract;
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_port_en(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_port_en(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtena;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_port_dis(usbh_dev_t *hw)
|
||||
static inline void usb_dwc_ll_hprt_port_dis(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hprt.prtena = 1; //W1C to disable
|
||||
//we want to W1C ENA but not W1C the interrupt bits
|
||||
hw->hprt_reg.val = hprt.val & ((~USBH_LL_HPRT_W1C_MSK) | USBH_LL_HPRT_ENA_MSK);
|
||||
hw->hprt_reg.val = hprt.val & ((~USB_DWC_LL_HPRT_W1C_MSK) | USB_DWC_LL_HPRT_ENA_MSK);
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_hprt_get_conn_status(usbh_dev_t *hw)
|
||||
static inline bool usb_dwc_ll_hprt_get_conn_status(usb_dwc_dev_t *hw)
|
||||
{
|
||||
return hw->hprt_reg.prtconnsts;
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_hprt_intr_read_and_clear(usbh_dev_t *hw)
|
||||
static inline uint32_t usb_dwc_ll_hprt_intr_read_and_clear(usb_dwc_dev_t *hw)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
//We want to W1C the interrupt bits but not that ENA
|
||||
hw->hprt_reg.val = hprt.val & (~USBH_LL_HPRT_ENA_MSK);
|
||||
hw->hprt_reg.val = hprt.val & (~USB_DWC_LL_HPRT_ENA_MSK);
|
||||
//Return only the interrupt bits
|
||||
return (hprt.val & (USBH_LL_HPRT_W1C_MSK & ~(USBH_LL_HPRT_ENA_MSK)));
|
||||
return (hprt.val & (USB_DWC_LL_HPRT_W1C_MSK & ~(USB_DWC_LL_HPRT_ENA_MSK)));
|
||||
}
|
||||
|
||||
static inline void usbh_ll_hprt_intr_clear(usbh_dev_t *hw, uint32_t intr_mask)
|
||||
static inline void usb_dwc_ll_hprt_intr_clear(usb_dwc_dev_t *hw, uint32_t intr_mask)
|
||||
{
|
||||
usb_hprt_reg_t hprt;
|
||||
usb_dwc_hprt_reg_t hprt;
|
||||
hprt.val = hw->hprt_reg.val;
|
||||
hw->hprt_reg.val = ((hprt.val & ~USBH_LL_HPRT_ENA_MSK) & ~USBH_LL_HPRT_W1C_MSK) | intr_mask;
|
||||
hw->hprt_reg.val = ((hprt.val & ~USB_DWC_LL_HPRT_ENA_MSK) & ~USB_DWC_LL_HPRT_W1C_MSK) | intr_mask;
|
||||
}
|
||||
|
||||
//Per Channel registers
|
||||
|
||||
// --------------------------- HCCHARi Register --------------------------------
|
||||
|
||||
static inline void usbh_ll_chan_start(volatile usb_host_chan_regs_t *chan)
|
||||
static inline void usb_dwc_ll_hcchar_enable_chan(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hcchar_reg.chena = 1;
|
||||
}
|
||||
|
||||
static inline bool usbh_ll_chan_is_active(volatile usb_host_chan_regs_t *chan)
|
||||
static inline bool usb_dwc_ll_hcchar_chan_is_enabled(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
return chan->hcchar_reg.chena;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_halt(volatile usb_host_chan_regs_t *chan)
|
||||
static inline void usb_dwc_ll_hcchar_disable_chan(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hcchar_reg.chdis = 1;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_xfer_odd_frame(volatile usb_host_chan_regs_t *chan)
|
||||
static inline void usb_dwc_ll_hcchar_set_odd_frame(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hcchar_reg.oddfrm = 1;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_xfer_even_frame(volatile usb_host_chan_regs_t *chan)
|
||||
static inline void usb_dwc_ll_hcchar_set_even_frame(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hcchar_reg.oddfrm = 0;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_dev_addr(volatile usb_host_chan_regs_t *chan, uint32_t addr)
|
||||
static inline void usb_dwc_ll_hcchar_set_dev_addr(volatile usb_dwc_host_chan_regs_t *chan, uint32_t addr)
|
||||
{
|
||||
chan->hcchar_reg.devaddr = addr;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan, usb_priv_xfer_type_t type)
|
||||
static inline void usb_dwc_ll_hcchar_set_ep_type(volatile usb_dwc_host_chan_regs_t *chan, usb_priv_xfer_type_t type)
|
||||
{
|
||||
uint32_t ep_type;
|
||||
switch (type) {
|
||||
|
@ -715,42 +719,42 @@ static inline void usbh_ll_chan_set_ep_type(volatile usb_host_chan_regs_t *chan,
|
|||
|
||||
//Indicates whether channel is commuunicating with a LS device connected via a FS hub. Setting this bit to 1 will cause
|
||||
//each packet to be preceded by a PREamble packet
|
||||
static inline void usbh_ll_chan_set_lspddev(volatile usb_host_chan_regs_t *chan, bool is_ls)
|
||||
static inline void usb_dwc_ll_hcchar_set_lspddev(volatile usb_dwc_host_chan_regs_t *chan, bool is_ls)
|
||||
{
|
||||
chan->hcchar_reg.lspddev = is_ls;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_dir(volatile usb_host_chan_regs_t *chan, bool is_in)
|
||||
static inline void usb_dwc_ll_hcchar_set_dir(volatile usb_dwc_host_chan_regs_t *chan, bool is_in)
|
||||
{
|
||||
chan->hcchar_reg.epdir = is_in;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_ep_num(volatile usb_host_chan_regs_t *chan, uint32_t num)
|
||||
static inline void usb_dwc_ll_hcchar_set_ep_num(volatile usb_dwc_host_chan_regs_t *chan, uint32_t num)
|
||||
{
|
||||
chan->hcchar_reg.epnum = num;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_mps(volatile usb_host_chan_regs_t *chan, uint32_t mps)
|
||||
static inline void usb_dwc_ll_hcchar_set_mps(volatile usb_dwc_host_chan_regs_t *chan, uint32_t mps)
|
||||
{
|
||||
chan->hcchar_reg.mps = mps;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_hcchar_init(volatile usb_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_priv_xfer_type_t type, bool is_in, bool is_ls)
|
||||
static inline void usb_dwc_ll_hcchar_init(volatile usb_dwc_host_chan_regs_t *chan, int dev_addr, int ep_num, int mps, usb_priv_xfer_type_t type, bool is_in, bool is_ls)
|
||||
{
|
||||
//Sets all persistent fields of the channel over its lifetimez
|
||||
usbh_ll_chan_set_dev_addr(chan, dev_addr);
|
||||
usbh_ll_chan_set_ep_type(chan, type);
|
||||
usbh_ll_chan_set_lspddev(chan, is_ls);
|
||||
usbh_ll_chan_set_dir(chan, is_in);
|
||||
usbh_ll_chan_set_ep_num(chan, ep_num);
|
||||
usbh_ll_chan_set_mps(chan, mps);
|
||||
usb_dwc_ll_hcchar_set_dev_addr(chan, dev_addr);
|
||||
usb_dwc_ll_hcchar_set_ep_type(chan, type);
|
||||
usb_dwc_ll_hcchar_set_lspddev(chan, is_ls);
|
||||
usb_dwc_ll_hcchar_set_dir(chan, is_in);
|
||||
usb_dwc_ll_hcchar_set_ep_num(chan, ep_num);
|
||||
usb_dwc_ll_hcchar_set_mps(chan, mps);
|
||||
}
|
||||
|
||||
// ---------------------------- HCINTi Register --------------------------------
|
||||
|
||||
static inline uint32_t usbh_ll_chan_intr_read_and_clear(volatile usb_host_chan_regs_t *chan)
|
||||
static inline uint32_t usb_dwc_ll_hcint_read_and_clear_intrs(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
usb_hcint_reg_t hcint;
|
||||
usb_dwc_hcint_reg_t hcint;
|
||||
hcint.val = chan->hcint_reg.val;
|
||||
chan->hcint_reg.val = hcint.val;
|
||||
return hcint.val;
|
||||
|
@ -758,14 +762,14 @@ static inline uint32_t usbh_ll_chan_intr_read_and_clear(volatile usb_host_chan_r
|
|||
|
||||
// --------------------------- HCINTMSKi Register ------------------------------
|
||||
|
||||
static inline void usbh_ll_chan_set_intr_mask(volatile usb_host_chan_regs_t *chan, uint32_t mask)
|
||||
static inline void usb_dwc_ll_hcintmsk_set_intr_mask(volatile usb_dwc_host_chan_regs_t *chan, uint32_t mask)
|
||||
{
|
||||
chan->hcintmsk_reg.val = mask;
|
||||
}
|
||||
|
||||
// ---------------------- HCTSIZi and HCDMAi Registers -------------------------
|
||||
// ---------------------------- HCTSIZi Register -------------------------------
|
||||
|
||||
static inline void usbh_ll_chan_set_pid(volatile usb_host_chan_regs_t *chan, uint32_t data_pid)
|
||||
static inline void usb_dwc_ll_hctsiz_set_pid(volatile usb_dwc_host_chan_regs_t *chan, uint32_t data_pid)
|
||||
{
|
||||
if (data_pid == 0) {
|
||||
chan->hctsiz_reg.pid = 0;
|
||||
|
@ -774,7 +778,8 @@ static inline void usbh_ll_chan_set_pid(volatile usb_host_chan_regs_t *chan, uin
|
|||
}
|
||||
}
|
||||
|
||||
static inline uint32_t usbh_ll_chan_get_pid(volatile usb_host_chan_regs_t *chan) {
|
||||
static inline uint32_t usb_dwc_ll_hctsiz_get_pid(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
if (chan->hctsiz_reg.pid == 0) {
|
||||
return 0; //DATA0
|
||||
} else {
|
||||
|
@ -782,9 +787,20 @@ static inline uint32_t usbh_ll_chan_get_pid(volatile usb_host_chan_regs_t *chan)
|
|||
}
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_dma_addr_non_iso(volatile usb_host_chan_regs_t *chan,
|
||||
void *dmaaddr,
|
||||
uint32_t qtd_idx)
|
||||
static inline void usb_dwc_ll_hctsiz_set_qtd_list_len(volatile usb_dwc_host_chan_regs_t *chan, int qtd_list_len)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, ntd, qtd_list_len - 1); //Set the length of the descriptor list
|
||||
}
|
||||
|
||||
static inline void usb_dwc_ll_hctsiz_init(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hctsiz_reg.dopng = 0; //Don't do ping
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, sched_info, 0xFF); //Schedinfo is always 0xFF for fullspeed. Not used in Bulk/Ctrl channels
|
||||
}
|
||||
|
||||
// ---------------------------- HCDMAi Register --------------------------------
|
||||
|
||||
static inline void usb_dwc_ll_hcdma_set_qtd_list_addr(volatile usb_dwc_host_chan_regs_t *chan, void *dmaaddr, uint32_t qtd_idx)
|
||||
{
|
||||
//Set HCDMAi
|
||||
chan->hcdma_reg.val = 0;
|
||||
|
@ -792,25 +808,14 @@ static inline void usbh_ll_chan_set_dma_addr_non_iso(volatile usb_host_chan_regs
|
|||
chan->hcdma_reg.non_iso.ctd = qtd_idx;
|
||||
}
|
||||
|
||||
static inline int usbh_ll_chan_get_ctd(usb_host_chan_regs_t *chan)
|
||||
static inline int usb_dwc_ll_hcdam_get_cur_qtd_idx(usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
return chan->hcdma_reg.non_iso.ctd;
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_hctsiz_init(volatile usb_host_chan_regs_t *chan)
|
||||
{
|
||||
chan->hctsiz_reg.dopng = 0; //Don't do ping
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, sched_info, 0xFF); //Schedinfo is always 0xFF for fullspeed. Not used in Bulk/Ctrl channels
|
||||
}
|
||||
|
||||
static inline void usbh_ll_chan_set_qtd_list_len(volatile usb_host_chan_regs_t *chan, int qtd_list_len)
|
||||
{
|
||||
HAL_FORCE_MODIFY_U32_REG_FIELD(chan->hctsiz_reg, ntd, qtd_list_len - 1); //Set the length of the descriptor list
|
||||
}
|
||||
|
||||
// ---------------------------- HCDMABi Register -------------------------------
|
||||
|
||||
static inline void *usbh_ll_chan_get_cur_buff_addr(volatile usb_host_chan_regs_t *chan)
|
||||
static inline void *usb_dwc_ll_hcdmab_get_buff_addr(volatile usb_dwc_host_chan_regs_t *chan)
|
||||
{
|
||||
return (void *)chan->hcdmab_reg.hcdmab;
|
||||
}
|
||||
|
@ -826,20 +831,20 @@ static inline void *usbh_ll_chan_get_cur_buff_addr(volatile usb_host_chan_regs_t
|
|||
*
|
||||
* @param dev Start address of the DWC_OTG registers
|
||||
* @param chan_idx The channel's index
|
||||
* @return usb_host_chan_regs_t* Pointer to channel's registers
|
||||
* @return usb_dwc_host_chan_regs_t* Pointer to channel's registers
|
||||
*/
|
||||
static inline usb_host_chan_regs_t *usbh_ll_get_chan_regs(usbh_dev_t *dev, int chan_idx)
|
||||
static inline usb_dwc_host_chan_regs_t *usb_dwc_ll_chan_get_regs(usb_dwc_dev_t *dev, int chan_idx)
|
||||
{
|
||||
return &dev->host_chans[chan_idx];
|
||||
}
|
||||
|
||||
// ------------------------------ QTD related ----------------------------------
|
||||
|
||||
#define USBH_LL_QTD_STATUS_SUCCESS 0x0 //If QTD was processed, it indicates the data was transmitted/received successfully
|
||||
#define USBH_LL_QTD_STATUS_PKTERR 0x1 //Data trasnmitted/received with errors (CRC/Timeout/Stuff/False EOP/Excessive NAK).
|
||||
#define USB_DWC_LL_QTD_STATUS_SUCCESS 0x0 //If QTD was processed, it indicates the data was transmitted/received successfully
|
||||
#define USB_DWC_LL_QTD_STATUS_PKTERR 0x1 //Data trasnmitted/received with errors (CRC/Timeout/Stuff/False EOP/Excessive NAK).
|
||||
//Note: 0x2 is reserved
|
||||
#define USBH_LL_QTD_STATUS_BUFFER 0x3 //AHB error occurred.
|
||||
#define USBH_LL_QTD_STATUS_NOT_EXECUTED 0x4 //QTD as never processed
|
||||
#define USB_DWC_LL_QTD_STATUS_BUFFER 0x3 //AHB error occurred.
|
||||
#define USB_DWC_LL_QTD_STATUS_NOT_EXECUTED 0x4 //QTD as never processed
|
||||
|
||||
/**
|
||||
* @brief Set a QTD for a non isochronous IN transfer
|
||||
|
@ -850,7 +855,7 @@ static inline usb_host_chan_regs_t *usbh_ll_get_chan_regs(usbh_dev_t *dev, int c
|
|||
* Non zero length must be mulitple of the endpoint's MPS.
|
||||
* @param hoc Halt on complete (will generate an interrupt and halt the channel)
|
||||
*/
|
||||
static inline void usbh_ll_set_qtd_in(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc)
|
||||
static inline void usb_dwc_ll_qtd_set_in(usb_dwc_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc)
|
||||
{
|
||||
qtd->buffer = data_buff; //Set pointer to data buffer
|
||||
qtd->buffer_status_val = 0; //Reset all flags to zero
|
||||
|
@ -873,7 +878,7 @@ static inline void usbh_ll_set_qtd_in(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff
|
|||
* @param is_setup Indicates whether this is a control transfer setup packet or a normal OUT Data transfer.
|
||||
* (As per the USB protocol, setup packets cannot be STALLd or NAKd by the device)
|
||||
*/
|
||||
static inline void usbh_ll_set_qtd_out(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc, bool is_setup)
|
||||
static inline void usb_dwc_ll_qtd_set_out(usb_dwc_ll_dma_qtd_t *qtd, uint8_t *data_buff, int xfer_len, bool hoc, bool is_setup)
|
||||
{
|
||||
qtd->buffer = data_buff; //Set pointer to data buffer
|
||||
qtd->buffer_status_val = 0; //Reset all flags to zero
|
||||
|
@ -896,7 +901,7 @@ static inline void usbh_ll_set_qtd_out(usbh_ll_dma_qtd_t *qtd, uint8_t *data_buf
|
|||
*
|
||||
* @param qtd Pointer to the QTD
|
||||
*/
|
||||
static inline void usbh_ll_set_qtd_null(usbh_ll_dma_qtd_t *qtd)
|
||||
static inline void usb_dwc_ll_qtd_set_null(usb_dwc_ll_dma_qtd_t *qtd)
|
||||
{
|
||||
qtd->buffer = NULL;
|
||||
qtd->buffer_status_val = 0; //Disable qtd by clearing it to zero. Used by interrupt/isoc as an unscheudled frame
|
||||
|
@ -911,12 +916,12 @@ static inline void usbh_ll_set_qtd_null(usbh_ll_dma_qtd_t *qtd)
|
|||
* @param[out] rem_len Number of bytes ramining in the QTD
|
||||
* @param[out] status Status of the QTD
|
||||
*/
|
||||
static inline void usbh_ll_get_qtd_status(usbh_ll_dma_qtd_t *qtd, int *rem_len, int *status)
|
||||
static inline void usb_dwc_ll_qtd_get_status(usb_dwc_ll_dma_qtd_t *qtd, int *rem_len, int *status)
|
||||
{
|
||||
//Status is the same regardless of IN or OUT
|
||||
if (qtd->in_non_iso.active) {
|
||||
//QTD was never processed
|
||||
*status = USBH_LL_QTD_STATUS_NOT_EXECUTED;
|
||||
*status = USB_DWC_LL_QTD_STATUS_NOT_EXECUTED;
|
||||
} else {
|
||||
*status = qtd->in_non_iso.rx_status;
|
||||
}
|
|
@ -8,8 +8,8 @@
|
|||
#include <stdint.h>
|
||||
#include <string.h>
|
||||
#include "sdkconfig.h"
|
||||
#include "hal/usbh_hal.h"
|
||||
#include "hal/usbh_ll.h"
|
||||
#include "hal/usb_dwc_hal.h"
|
||||
#include "hal/usb_dwc_ll.h"
|
||||
#include "hal/assert.h"
|
||||
|
||||
// ------------------------------------------------ Macros and Types ---------------------------------------------------
|
||||
|
@ -30,108 +30,108 @@
|
|||
/**
|
||||
* The following core interrupts will be enabled (listed LSB to MSB). Some of these
|
||||
* interrupts are enabled later than others.
|
||||
* - USB_LL_INTR_CORE_PRTINT
|
||||
* - USB_LL_INTR_CORE_HCHINT
|
||||
* - USB_LL_INTR_CORE_DISCONNINT
|
||||
* - USB_DWC_LL_INTR_CORE_PRTINT
|
||||
* - USB_DWC_LL_INTR_CORE_HCHINT
|
||||
* - USB_DWC_LL_INTR_CORE_DISCONNINT
|
||||
* The following PORT interrupts cannot be masked, listed LSB to MSB
|
||||
* - USBH_LL_INTR_HPRT_PRTCONNDET
|
||||
* - USBH_LL_INTR_HPRT_PRTENCHNG
|
||||
* - USBH_LL_INTR_HPRT_PRTOVRCURRCHNG
|
||||
* - USB_DWC_LL_INTR_HPRT_PRTCONNDET
|
||||
* - USB_DWC_LL_INTR_HPRT_PRTENCHNG
|
||||
* - USB_DWC_LL_INTR_HPRT_PRTOVRCURRCHNG
|
||||
*/
|
||||
#define CORE_INTRS_EN_MSK (USB_LL_INTR_CORE_DISCONNINT)
|
||||
#define CORE_INTRS_EN_MSK (USB_DWC_LL_INTR_CORE_DISCONNINT)
|
||||
|
||||
//Interrupts that pertain to core events
|
||||
#define CORE_EVENTS_INTRS_MSK (USB_LL_INTR_CORE_DISCONNINT | \
|
||||
USB_LL_INTR_CORE_HCHINT)
|
||||
#define CORE_EVENTS_INTRS_MSK (USB_DWC_LL_INTR_CORE_DISCONNINT | \
|
||||
USB_DWC_LL_INTR_CORE_HCHINT)
|
||||
|
||||
//Interrupt that pertain to host port events
|
||||
#define PORT_EVENTS_INTRS_MSK (USBH_LL_INTR_HPRT_PRTCONNDET | \
|
||||
USBH_LL_INTR_HPRT_PRTENCHNG | \
|
||||
USBH_LL_INTR_HPRT_PRTOVRCURRCHNG)
|
||||
#define PORT_EVENTS_INTRS_MSK (USB_DWC_LL_INTR_HPRT_PRTCONNDET | \
|
||||
USB_DWC_LL_INTR_HPRT_PRTENCHNG | \
|
||||
USB_DWC_LL_INTR_HPRT_PRTOVRCURRCHNG)
|
||||
|
||||
/**
|
||||
* The following channel interrupt bits are currently checked (in order LSB to MSB)
|
||||
* - USBH_LL_INTR_CHAN_XFERCOMPL
|
||||
* - USBH_LL_INTR_CHAN_CHHLTD
|
||||
* - USBH_LL_INTR_CHAN_STALL
|
||||
* - USBH_LL_INTR_CHAN_BBLEER
|
||||
* - USBH_LL_INTR_CHAN_BNAINTR
|
||||
* - USBH_LL_INTR_CHAN_XCS_XACT_ERR
|
||||
* - USB_DWC_LL_INTR_CHAN_XFERCOMPL
|
||||
* - USB_DWC_LL_INTR_CHAN_CHHLTD
|
||||
* - USB_DWC_LL_INTR_CHAN_STALL
|
||||
* - USB_DWC_LL_INTR_CHAN_BBLEER
|
||||
* - USB_DWC_LL_INTR_CHAN_BNAINTR
|
||||
* - USB_DWC_LL_INTR_CHAN_XCS_XACT_ERR
|
||||
*
|
||||
* Note the following points about channel interrupts:
|
||||
* - Not all bits are unmaskable under scatter/gather
|
||||
* - Those bits proxy their interrupt through the USBH_LL_INTR_CHAN_CHHLTD bit
|
||||
* - USBH_LL_INTR_CHAN_XCS_XACT_ERR is always unmasked
|
||||
* - When USBH_LL_INTR_CHAN_BNAINTR occurs, USBH_LL_INTR_CHAN_CHHLTD will NOT.
|
||||
* - USBH_LL_INTR_CHAN_AHBERR doesn't actually ever happen on our system (i.e., ESP32-S2, ESP32-S3):
|
||||
* - Those bits proxy their interrupt through the USB_DWC_LL_INTR_CHAN_CHHLTD bit
|
||||
* - USB_DWC_LL_INTR_CHAN_XCS_XACT_ERR is always unmasked
|
||||
* - When USB_DWC_LL_INTR_CHAN_BNAINTR occurs, USB_DWC_LL_INTR_CHAN_CHHLTD will NOT.
|
||||
* - USB_DWC_LL_INTR_CHAN_AHBERR doesn't actually ever happen on our system (i.e., ESP32-S2, ESP32-S3):
|
||||
* - If the QTD list's starting address is an invalid address (e.g., NULL), the core will attempt to fetch that
|
||||
* address for a transfer descriptor and probably gets all zeroes. It will interpret the zero as a bad QTD and
|
||||
* return a USBH_LL_INTR_CHAN_BNAINTR instead.
|
||||
* return a USB_DWC_LL_INTR_CHAN_BNAINTR instead.
|
||||
* - If the QTD's buffer pointer is an invalid address, the core will attempt to read/write data to/from that
|
||||
* invalid buffer address with NO INDICATION OF ERROR. The transfer will be acknowledged and treated as
|
||||
* successful. Bad buffer pointers MUST BE CHECKED FROM HIGHER LAYERS INSTEAD.
|
||||
*/
|
||||
#define CHAN_INTRS_EN_MSK (USBH_LL_INTR_CHAN_XFERCOMPL | \
|
||||
USBH_LL_INTR_CHAN_CHHLTD | \
|
||||
USBH_LL_INTR_CHAN_BNAINTR)
|
||||
#define CHAN_INTRS_EN_MSK (USB_DWC_LL_INTR_CHAN_XFERCOMPL | \
|
||||
USB_DWC_LL_INTR_CHAN_CHHLTD | \
|
||||
USB_DWC_LL_INTR_CHAN_BNAINTR)
|
||||
|
||||
#define CHAN_INTRS_ERROR_MSK (USBH_LL_INTR_CHAN_STALL | \
|
||||
USBH_LL_INTR_CHAN_BBLEER | \
|
||||
USBH_LL_INTR_CHAN_BNAINTR | \
|
||||
USBH_LL_INTR_CHAN_XCS_XACT_ERR)
|
||||
#define CHAN_INTRS_ERROR_MSK (USB_DWC_LL_INTR_CHAN_STALL | \
|
||||
USB_DWC_LL_INTR_CHAN_BBLEER | \
|
||||
USB_DWC_LL_INTR_CHAN_BNAINTR | \
|
||||
USB_DWC_LL_INTR_CHAN_XCS_XACT_ERR)
|
||||
|
||||
// -------------------------------------------------- Core (Global) ----------------------------------------------------
|
||||
|
||||
static void set_defaults(usbh_hal_context_t *hal)
|
||||
static void set_defaults(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//GAHBCFG register
|
||||
usb_ll_en_dma_mode(hal->dev);
|
||||
usb_dwc_ll_gahbcfg_en_dma_mode(hal->dev);
|
||||
#ifdef CONFIG_IDF_TARGET_ESP32S2
|
||||
usb_ll_set_hbstlen(hal->dev, 1); //Use INCR AHB burst. See the ESP32-S2 and later chip ERRATA.
|
||||
usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 1); //Use INCR AHB burst. See the ESP32-S2 and later chip ERRATA.
|
||||
#elif CONFIG_IDF_TARGET_ESP32S3
|
||||
usb_ll_set_hbstlen(hal->dev, 0); //Do not use USB burst INCR mode for the ESP32-S3, to avoid interference with other peripherals.
|
||||
usb_dwc_ll_gahbcfg_set_hbstlen(hal->dev, 0); //Do not use USB burst INCR mode for the ESP32-S3, to avoid interference with other peripherals.
|
||||
#endif
|
||||
//GUSBCFG register
|
||||
usb_ll_dis_hnp_cap(hal->dev); //Disable HNP
|
||||
usb_ll_dis_srp_cap(hal->dev); //Disable SRP
|
||||
usb_dwc_ll_gusbcfg_dis_hnp_cap(hal->dev); //Disable HNP
|
||||
usb_dwc_ll_gusbcfg_dis_srp_cap(hal->dev); //Disable SRP
|
||||
//Enable interruts
|
||||
usb_ll_dis_intrs(hal->dev, 0xFFFFFFFF); //Mask all interrupts first
|
||||
usb_ll_en_intrs(hal->dev, CORE_INTRS_EN_MSK); //Unmask global interrupts
|
||||
usb_ll_intr_read_and_clear(hal->dev); //Clear interrupts
|
||||
usb_ll_en_global_intr(hal->dev); //Enable interrupt signal
|
||||
usb_dwc_ll_gintmsk_dis_intrs(hal->dev, 0xFFFFFFFF); //Mask all interrupts first
|
||||
usb_dwc_ll_gintmsk_en_intrs(hal->dev, CORE_INTRS_EN_MSK); //Unmask global interrupts
|
||||
usb_dwc_ll_gintsts_read_and_clear_intrs(hal->dev); //Clear interrupts
|
||||
usb_dwc_ll_gahbcfg_en_global_intr(hal->dev); //Enable interrupt signal
|
||||
//Enable host mode
|
||||
usb_ll_set_host_mode(hal->dev);
|
||||
usb_dwc_ll_gusbcfg_force_host_mode(hal->dev);
|
||||
}
|
||||
|
||||
void usbh_hal_init(usbh_hal_context_t *hal)
|
||||
void usb_dwc_hal_init(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//Check if a peripheral is alive by reading the core ID registers
|
||||
usbh_dev_t *dev = &USBH;
|
||||
uint32_t core_id = usb_ll_get_controller_core_id(dev);
|
||||
usb_dwc_dev_t *dev = &USB_DWC;
|
||||
uint32_t core_id = usb_dwc_ll_gsnpsid_get_id(dev);
|
||||
HAL_ASSERT(core_id == CORE_REG_GSNPSID);
|
||||
(void) core_id; //Suppress unused variable warning if asserts are disabled
|
||||
//Initialize HAL context
|
||||
memset(hal, 0, sizeof(usbh_hal_context_t));
|
||||
memset(hal, 0, sizeof(usb_dwc_hal_context_t));
|
||||
hal->dev = dev;
|
||||
set_defaults(hal);
|
||||
}
|
||||
|
||||
void usbh_hal_deinit(usbh_hal_context_t *hal)
|
||||
void usb_dwc_hal_deinit(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//Disable and clear global interrupt
|
||||
usb_ll_dis_intrs(hal->dev, 0xFFFFFFFF); //Disable all interrupts
|
||||
usb_ll_intr_read_and_clear(hal->dev); //Clear interrupts
|
||||
usb_ll_dis_global_intr(hal->dev); //Disable interrupt signal
|
||||
usb_dwc_ll_gintmsk_dis_intrs(hal->dev, 0xFFFFFFFF); //Disable all interrupts
|
||||
usb_dwc_ll_gintsts_read_and_clear_intrs(hal->dev); //Clear interrupts
|
||||
usb_dwc_ll_gahbcfg_dis_global_intr(hal->dev); //Disable interrupt signal
|
||||
hal->dev = NULL;
|
||||
}
|
||||
|
||||
void usbh_hal_core_soft_reset(usbh_hal_context_t *hal)
|
||||
void usb_dwc_hal_core_soft_reset(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
usb_ll_core_soft_reset(hal->dev);
|
||||
while (usb_ll_check_core_soft_reset(hal->dev)) {
|
||||
usb_dwc_ll_grstctl_core_soft_reset(hal->dev);
|
||||
while (usb_dwc_ll_grstctl_is_core_soft_reset_in_progress(hal->dev)) {
|
||||
; //Wait until core reset is done
|
||||
}
|
||||
while (!usb_ll_check_ahb_idle(hal->dev)) {
|
||||
while (!usb_dwc_ll_grstctl_is_ahb_idle(hal->dev)) {
|
||||
; //Wait until AHB Master bus is idle before doing any other operations
|
||||
}
|
||||
//Set the default bits
|
||||
|
@ -141,60 +141,60 @@ void usbh_hal_core_soft_reset(usbh_hal_context_t *hal)
|
|||
hal->flags.val = 0;
|
||||
hal->channels.num_allocd = 0;
|
||||
hal->channels.chan_pend_intrs_msk = 0;
|
||||
memset(hal->channels.hdls, 0, sizeof(usbh_hal_chan_t *) * USBH_HAL_NUM_CHAN);
|
||||
memset(hal->channels.hdls, 0, sizeof(usb_dwc_hal_chan_t *) * USB_DWC_HAL_NUM_CHAN);
|
||||
}
|
||||
|
||||
void usbh_hal_set_fifo_size(usbh_hal_context_t *hal, const usbh_hal_fifo_config_t *fifo_config)
|
||||
void usb_dwc_hal_set_fifo_size(usb_dwc_hal_context_t *hal, const usb_dwc_hal_fifo_config_t *fifo_config)
|
||||
{
|
||||
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USBH_HAL_FIFO_TOTAL_USABLE_LINES);
|
||||
HAL_ASSERT((fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines + fifo_config->ptx_fifo_lines) <= USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES);
|
||||
//Check that none of the channels are active
|
||||
for (int i = 0; i < USBH_HAL_NUM_CHAN; i++) {
|
||||
for (int i = 0; i < USB_DWC_HAL_NUM_CHAN; i++) {
|
||||
if (hal->channels.hdls[i] != NULL) {
|
||||
HAL_ASSERT(!hal->channels.hdls[i]->flags.active);
|
||||
}
|
||||
}
|
||||
//Set the new FIFO lengths
|
||||
usb_ll_set_rx_fifo_size(hal->dev, fifo_config->rx_fifo_lines);
|
||||
usb_ll_set_nptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines);
|
||||
usbh_ll_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines);
|
||||
usb_dwc_ll_grxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines);
|
||||
usb_dwc_ll_gnptxfsiz_set_fifo_size(hal->dev, fifo_config->rx_fifo_lines, fifo_config->nptx_fifo_lines);
|
||||
usb_dwc_ll_hptxfsiz_set_ptx_fifo_size(hal->dev, fifo_config->rx_fifo_lines + fifo_config->nptx_fifo_lines, fifo_config->ptx_fifo_lines);
|
||||
//Flush the FIFOs
|
||||
usb_ll_flush_nptx_fifo(hal->dev);
|
||||
usb_ll_flush_ptx_fifo(hal->dev);
|
||||
usb_ll_flush_rx_fifo(hal->dev);
|
||||
usb_dwc_ll_grstctl_flush_nptx_fifo(hal->dev);
|
||||
usb_dwc_ll_grstctl_flush_ptx_fifo(hal->dev);
|
||||
usb_dwc_ll_grstctl_flush_rx_fifo(hal->dev);
|
||||
hal->flags.fifo_sizes_set = 1;
|
||||
}
|
||||
|
||||
// ---------------------------------------------------- Host Port ------------------------------------------------------
|
||||
|
||||
static inline void debounce_lock_enable(usbh_hal_context_t *hal)
|
||||
static inline void debounce_lock_enable(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
//Disable the hprt (connection) and disconnection interrupts to prevent repeated triggerings
|
||||
usb_ll_dis_intrs(hal->dev, USB_LL_INTR_CORE_PRTINT | USB_LL_INTR_CORE_DISCONNINT);
|
||||
usb_dwc_ll_gintmsk_dis_intrs(hal->dev, USB_DWC_LL_INTR_CORE_PRTINT | USB_DWC_LL_INTR_CORE_DISCONNINT);
|
||||
hal->flags.dbnc_lock_enabled = 1;
|
||||
}
|
||||
|
||||
void usbh_hal_port_enable(usbh_hal_context_t *hal)
|
||||
void usb_dwc_hal_port_enable(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
usb_priv_speed_t speed = usbh_ll_hprt_get_speed(hal->dev);
|
||||
usb_priv_speed_t speed = usb_dwc_ll_hprt_get_speed(hal->dev);
|
||||
//Host Configuration
|
||||
usbh_ll_hcfg_set_defaults(hal->dev, speed);
|
||||
usb_dwc_ll_hcfg_set_defaults(hal->dev, speed);
|
||||
//Configure HFIR
|
||||
usbh_ll_hfir_set_defaults(hal->dev, speed);
|
||||
usb_dwc_ll_hfir_set_defaults(hal->dev, speed);
|
||||
}
|
||||
|
||||
// ----------------------------------------------------- Channel -------------------------------------------------------
|
||||
|
||||
// ----------------- Channel Allocation --------------------
|
||||
|
||||
bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, void *chan_ctx)
|
||||
bool usb_dwc_hal_chan_alloc(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj, void *chan_ctx)
|
||||
{
|
||||
HAL_ASSERT(hal->flags.fifo_sizes_set); //FIFO sizes should be set befor attempting to allocate a channel
|
||||
//Attempt to allocate channel
|
||||
if (hal->channels.num_allocd == USBH_HAL_NUM_CHAN) {
|
||||
if (hal->channels.num_allocd == USB_DWC_HAL_NUM_CHAN) {
|
||||
return false; //Out of free channels
|
||||
}
|
||||
int chan_idx = -1;
|
||||
for (int i = 0; i < USBH_HAL_NUM_CHAN; i++) {
|
||||
for (int i = 0; i < USB_DWC_HAL_NUM_CHAN; i++) {
|
||||
if (hal->channels.hdls[i] == NULL) {
|
||||
hal->channels.hdls[i] = chan_obj;
|
||||
chan_idx = i;
|
||||
|
@ -204,21 +204,21 @@ bool usbh_hal_chan_alloc(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, voi
|
|||
}
|
||||
HAL_ASSERT(chan_idx != -1);
|
||||
//Initialize channel object
|
||||
memset(chan_obj, 0, sizeof(usbh_hal_chan_t));
|
||||
memset(chan_obj, 0, sizeof(usb_dwc_hal_chan_t));
|
||||
chan_obj->flags.chan_idx = chan_idx;
|
||||
chan_obj->regs = usbh_ll_get_chan_regs(hal->dev, chan_idx);
|
||||
chan_obj->regs = usb_dwc_ll_chan_get_regs(hal->dev, chan_idx);
|
||||
chan_obj->chan_ctx = chan_ctx;
|
||||
//Note: EP characteristics configured separately
|
||||
//Clean and unmask the channel's interrupt
|
||||
usbh_ll_chan_intr_read_and_clear(chan_obj->regs); //Clear the interrupt bits for that channel
|
||||
usbh_ll_haintmsk_en_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
|
||||
usbh_ll_chan_set_intr_mask(chan_obj->regs, CHAN_INTRS_EN_MSK); //Unmask interrupts for this channel
|
||||
usbh_ll_chan_set_pid(chan_obj->regs, 0); //Set the initial PID to zero
|
||||
usbh_ll_chan_hctsiz_init(chan_obj->regs); //Set the non changing parts of the HCTSIZ registers (e.g., do_ping and sched info)
|
||||
usb_dwc_ll_hcint_read_and_clear_intrs(chan_obj->regs); //Clear the interrupt bits for that channel
|
||||
usb_dwc_ll_haintmsk_en_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
|
||||
usb_dwc_ll_hcintmsk_set_intr_mask(chan_obj->regs, CHAN_INTRS_EN_MSK); //Unmask interrupts for this channel
|
||||
usb_dwc_ll_hctsiz_set_pid(chan_obj->regs, 0); //Set the initial PID to zero
|
||||
usb_dwc_ll_hctsiz_init(chan_obj->regs); //Set the non changing parts of the HCTSIZ registers (e.g., do_ping and sched info)
|
||||
return true;
|
||||
}
|
||||
|
||||
void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj)
|
||||
void usb_dwc_hal_chan_free(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
if (chan_obj->type == USB_PRIV_XFER_TYPE_INTR || chan_obj->type == USB_PRIV_XFER_TYPE_ISOCHRONOUS) {
|
||||
//Unschedule this channel
|
||||
|
@ -229,7 +229,7 @@ void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj)
|
|||
//Can only free a channel when in the disabled state and descriptor list released
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
//Disable channel's interrupt
|
||||
usbh_ll_haintmsk_dis_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
|
||||
usb_dwc_ll_haintmsk_dis_chan_intr(hal->dev, 1 << chan_obj->flags.chan_idx);
|
||||
//Deallocate channel
|
||||
hal->channels.hdls[chan_obj->flags.chan_idx] = NULL;
|
||||
hal->channels.num_allocd--;
|
||||
|
@ -238,12 +238,12 @@ void usbh_hal_chan_free(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj)
|
|||
|
||||
// ---------------- Channel Configuration ------------------
|
||||
|
||||
void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_obj, usbh_hal_ep_char_t *ep_char)
|
||||
void usb_dwc_hal_chan_set_ep_char(usb_dwc_hal_context_t *hal, usb_dwc_hal_chan_t *chan_obj, usb_dwc_hal_ep_char_t *ep_char)
|
||||
{
|
||||
//Cannot change ep_char whilst channel is still active or in error
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
//Set the endpoint characteristics of the pipe
|
||||
usbh_ll_chan_hcchar_init(chan_obj->regs,
|
||||
usb_dwc_ll_hcchar_init(chan_obj->regs,
|
||||
ep_char->dev_addr,
|
||||
ep_char->bEndpointAddress & BENDPOINTADDRESS_NUM_MSK,
|
||||
ep_char->mps,
|
||||
|
@ -266,83 +266,88 @@ void usbh_hal_chan_set_ep_char(usbh_hal_context_t *hal, usbh_hal_chan_t *chan_ob
|
|||
|
||||
// ------------------- Channel Control ---------------------
|
||||
|
||||
void usbh_hal_chan_activate(usbh_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx)
|
||||
void usb_dwc_hal_chan_activate(usb_dwc_hal_chan_t *chan_obj, void *xfer_desc_list, int desc_list_len, int start_idx)
|
||||
{
|
||||
//Cannot activate a channel that has already been enabled or is pending error handling
|
||||
HAL_ASSERT(!chan_obj->flags.active);
|
||||
//Set start address of the QTD list and starting QTD index
|
||||
usbh_ll_chan_set_dma_addr_non_iso(chan_obj->regs, xfer_desc_list, start_idx);
|
||||
usbh_ll_chan_set_qtd_list_len(chan_obj->regs, desc_list_len);
|
||||
usbh_ll_chan_start(chan_obj->regs); //Start the channel
|
||||
usb_dwc_ll_hcdma_set_qtd_list_addr(chan_obj->regs, xfer_desc_list, start_idx);
|
||||
usb_dwc_ll_hctsiz_set_qtd_list_len(chan_obj->regs, desc_list_len);
|
||||
usb_dwc_ll_hcchar_enable_chan(chan_obj->regs); //Start the channel
|
||||
chan_obj->flags.active = 1;
|
||||
}
|
||||
|
||||
bool usbh_hal_chan_request_halt(usbh_hal_chan_t *chan_obj)
|
||||
bool usb_dwc_hal_chan_request_halt(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
//Cannot request halt on a channel that is pending error handling
|
||||
if (usbh_ll_chan_is_active(chan_obj->regs)) {
|
||||
//If the register indicates that the channel is still active, the active flag must have been previously set
|
||||
HAL_ASSERT(chan_obj->flags.active);
|
||||
usbh_ll_chan_halt(chan_obj->regs);
|
||||
if (chan_obj->flags.active) {
|
||||
/*
|
||||
Request a halt so long as the channel's active flag is set.
|
||||
- If the underlying hardware channel is already halted but the channel is pending interrupt handling,
|
||||
disabling the channel will have no effect (i.e., no channel interrupt is generated).
|
||||
- If the underlying channel is currently active, disabling the channel will trigger a channel interrupt.
|
||||
|
||||
Regardless, setting the "halt_requested" should cause "usb_dwc_hal_chan_decode_intr()" to report the
|
||||
USB_DWC_HAL_CHAN_EVENT_HALT_REQ event when channel interrupt is handled (pending or triggered).
|
||||
*/
|
||||
usb_dwc_ll_hcchar_disable_chan(chan_obj->regs);
|
||||
chan_obj->flags.halt_requested = 1;
|
||||
return false;
|
||||
} else {
|
||||
//We just clear the active flag here as it could still be set (if we have a pending channel interrupt)
|
||||
chan_obj->flags.active = 0;
|
||||
//Channel was never active to begin with, simply return true
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
// ------------------------------------------------- Event Handling ----------------------------------------------------
|
||||
|
||||
usbh_hal_port_event_t usbh_hal_decode_intr(usbh_hal_context_t *hal)
|
||||
usb_dwc_hal_port_event_t usb_dwc_hal_decode_intr(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
uint32_t intrs_core = usb_ll_intr_read_and_clear(hal->dev); //Read and clear core interrupts
|
||||
uint32_t intrs_core = usb_dwc_ll_gintsts_read_and_clear_intrs(hal->dev); //Read and clear core interrupts
|
||||
uint32_t intrs_port = 0;
|
||||
if (intrs_core & USB_LL_INTR_CORE_PRTINT) {
|
||||
if (intrs_core & USB_DWC_LL_INTR_CORE_PRTINT) {
|
||||
//There are host port interrupts. Read and clear those as well.
|
||||
intrs_port = usbh_ll_hprt_intr_read_and_clear(hal->dev);
|
||||
intrs_port = usb_dwc_ll_hprt_intr_read_and_clear(hal->dev);
|
||||
}
|
||||
//Note: Do not change order of checks. Regressing events (e.g. enable -> disabled, connected -> connected)
|
||||
//always take precedence. ENABLED < DISABLED < CONN < DISCONN < OVRCUR
|
||||
usbh_hal_port_event_t event = USBH_HAL_PORT_EVENT_NONE;
|
||||
usb_dwc_hal_port_event_t event = USB_DWC_HAL_PORT_EVENT_NONE;
|
||||
|
||||
//Check if this is a core or port event
|
||||
if ((intrs_core & CORE_EVENTS_INTRS_MSK) || (intrs_port & PORT_EVENTS_INTRS_MSK)) {
|
||||
//Do not change the order of the following checks. Some events/interrupts take precedence over others
|
||||
if (intrs_core & USB_LL_INTR_CORE_DISCONNINT) {
|
||||
event = USBH_HAL_PORT_EVENT_DISCONN;
|
||||
if (intrs_core & USB_DWC_LL_INTR_CORE_DISCONNINT) {
|
||||
event = USB_DWC_HAL_PORT_EVENT_DISCONN;
|
||||
debounce_lock_enable(hal);
|
||||
//Mask the port connection and disconnection interrupts to prevent repeated triggering
|
||||
} else if (intrs_port & USBH_LL_INTR_HPRT_PRTOVRCURRCHNG) {
|
||||
} else if (intrs_port & USB_DWC_LL_INTR_HPRT_PRTOVRCURRCHNG) {
|
||||
//Check if this is an overcurrent or an overcurrent cleared
|
||||
if (usbh_ll_hprt_get_port_overcur(hal->dev)) {
|
||||
event = USBH_HAL_PORT_EVENT_OVRCUR;
|
||||
if (usb_dwc_ll_hprt_get_port_overcur(hal->dev)) {
|
||||
event = USB_DWC_HAL_PORT_EVENT_OVRCUR;
|
||||
} else {
|
||||
event = USBH_HAL_PORT_EVENT_OVRCUR_CLR;
|
||||
event = USB_DWC_HAL_PORT_EVENT_OVRCUR_CLR;
|
||||
}
|
||||
} else if (intrs_port & USBH_LL_INTR_HPRT_PRTENCHNG) {
|
||||
if (usbh_ll_hprt_get_port_en(hal->dev)) { //Host port was enabled
|
||||
event = USBH_HAL_PORT_EVENT_ENABLED;
|
||||
} else if (intrs_port & USB_DWC_LL_INTR_HPRT_PRTENCHNG) {
|
||||
if (usb_dwc_ll_hprt_get_port_en(hal->dev)) { //Host port was enabled
|
||||
event = USB_DWC_HAL_PORT_EVENT_ENABLED;
|
||||
} else { //Host port has been disabled
|
||||
event = USBH_HAL_PORT_EVENT_DISABLED;
|
||||
event = USB_DWC_HAL_PORT_EVENT_DISABLED;
|
||||
}
|
||||
} else if (intrs_port & USBH_LL_INTR_HPRT_PRTCONNDET && !hal->flags.dbnc_lock_enabled) {
|
||||
event = USBH_HAL_PORT_EVENT_CONN;
|
||||
} else if (intrs_port & USB_DWC_LL_INTR_HPRT_PRTCONNDET && !hal->flags.dbnc_lock_enabled) {
|
||||
event = USB_DWC_HAL_PORT_EVENT_CONN;
|
||||
debounce_lock_enable(hal);
|
||||
}
|
||||
}
|
||||
//Port events always take precedence over channel events
|
||||
if (event == USBH_HAL_PORT_EVENT_NONE && (intrs_core & USB_LL_INTR_CORE_HCHINT)) {
|
||||
if (event == USB_DWC_HAL_PORT_EVENT_NONE && (intrs_core & USB_DWC_LL_INTR_CORE_HCHINT)) {
|
||||
//One or more channels have pending interrupts. Store the mask of those channels
|
||||
hal->channels.chan_pend_intrs_msk = usbh_ll_get_chan_intrs_msk(hal->dev);
|
||||
event = USBH_HAL_PORT_EVENT_CHAN;
|
||||
hal->channels.chan_pend_intrs_msk = usb_dwc_ll_haint_get_chan_intrs(hal->dev);
|
||||
event = USB_DWC_HAL_PORT_EVENT_CHAN;
|
||||
}
|
||||
|
||||
return event;
|
||||
}
|
||||
|
||||
usbh_hal_chan_t *usbh_hal_get_chan_pending_intr(usbh_hal_context_t *hal)
|
||||
usb_dwc_hal_chan_t *usb_dwc_hal_get_chan_pending_intr(usb_dwc_hal_context_t *hal)
|
||||
{
|
||||
int chan_num = __builtin_ffs(hal->channels.chan_pend_intrs_msk);
|
||||
if (chan_num) {
|
||||
|
@ -353,52 +358,56 @@ usbh_hal_chan_t *usbh_hal_get_chan_pending_intr(usbh_hal_context_t *hal)
|
|||
}
|
||||
}
|
||||
|
||||
usbh_hal_chan_event_t usbh_hal_chan_decode_intr(usbh_hal_chan_t *chan_obj)
|
||||
usb_dwc_hal_chan_event_t usb_dwc_hal_chan_decode_intr(usb_dwc_hal_chan_t *chan_obj)
|
||||
{
|
||||
uint32_t chan_intrs = usbh_ll_chan_intr_read_and_clear(chan_obj->regs);
|
||||
usbh_hal_chan_event_t chan_event;
|
||||
//Note: We don't assert on (chan_obj->flags.active) here as it could have been already cleared by usbh_hal_chan_request_halt()
|
||||
uint32_t chan_intrs = usb_dwc_ll_hcint_read_and_clear_intrs(chan_obj->regs);
|
||||
usb_dwc_hal_chan_event_t chan_event;
|
||||
//Note: We don't assert on (chan_obj->flags.active) here as it could have been already cleared by usb_dwc_hal_chan_request_halt()
|
||||
|
||||
/*
|
||||
Note: Do not change order of checks as some events take precedence over others.
|
||||
Errors > Channel Halt Request > Transfer completed
|
||||
*/
|
||||
if (chan_intrs & CHAN_INTRS_ERROR_MSK) { //Note: Errors are uncommon, so we check against the entire interrupt mask to reduce frequency of entering this call path
|
||||
HAL_ASSERT(chan_intrs & USBH_LL_INTR_CHAN_CHHLTD); //An error should have halted the channel
|
||||
HAL_ASSERT(chan_intrs & USB_DWC_LL_INTR_CHAN_CHHLTD); //An error should have halted the channel
|
||||
//Store the error in hal context
|
||||
usbh_hal_chan_error_t error;
|
||||
if (chan_intrs & USBH_LL_INTR_CHAN_STALL) {
|
||||
error = USBH_HAL_CHAN_ERROR_STALL;
|
||||
} else if (chan_intrs & USBH_LL_INTR_CHAN_BBLEER) {
|
||||
error = USBH_HAL_CHAN_ERROR_PKT_BBL;
|
||||
} else if (chan_intrs & USBH_LL_INTR_CHAN_BNAINTR) {
|
||||
error = USBH_HAL_CHAN_ERROR_BNA;
|
||||
} else { //USBH_LL_INTR_CHAN_XCS_XACT_ERR
|
||||
error = USBH_HAL_CHAN_ERROR_XCS_XACT;
|
||||
usb_dwc_hal_chan_error_t error;
|
||||
if (chan_intrs & USB_DWC_LL_INTR_CHAN_STALL) {
|
||||
error = USB_DWC_HAL_CHAN_ERROR_STALL;
|
||||
} else if (chan_intrs & USB_DWC_LL_INTR_CHAN_BBLEER) {
|
||||
error = USB_DWC_HAL_CHAN_ERROR_PKT_BBL;
|
||||
} else if (chan_intrs & USB_DWC_LL_INTR_CHAN_BNAINTR) {
|
||||
error = USB_DWC_HAL_CHAN_ERROR_BNA;
|
||||
} else { //USB_DWC_LL_INTR_CHAN_XCS_XACT_ERR
|
||||
error = USB_DWC_HAL_CHAN_ERROR_XCS_XACT;
|
||||
}
|
||||
//Update flags
|
||||
chan_obj->error = error;
|
||||
chan_obj->flags.active = 0;
|
||||
//Save the error to be handled later
|
||||
chan_event = USBH_HAL_CHAN_EVENT_ERROR;
|
||||
} else if (chan_intrs & USBH_LL_INTR_CHAN_CHHLTD) {
|
||||
chan_event = USB_DWC_HAL_CHAN_EVENT_ERROR;
|
||||
} else if (chan_intrs & USB_DWC_LL_INTR_CHAN_CHHLTD) {
|
||||
if (chan_obj->flags.halt_requested) {
|
||||
chan_obj->flags.halt_requested = 0;
|
||||
chan_event = USBH_HAL_CHAN_EVENT_HALT_REQ;
|
||||
chan_event = USB_DWC_HAL_CHAN_EVENT_HALT_REQ;
|
||||
} else {
|
||||
//Must have been halted due to QTD HOC
|
||||
chan_event = USBH_HAL_CHAN_EVENT_CPLT;
|
||||
chan_event = USB_DWC_HAL_CHAN_EVENT_CPLT;
|
||||
}
|
||||
chan_obj->flags.active = 0;
|
||||
} else if (chan_intrs & USBH_LL_INTR_CHAN_XFERCOMPL) {
|
||||
} else if (chan_intrs & USB_DWC_LL_INTR_CHAN_XFERCOMPL) {
|
||||
/*
|
||||
A transfer complete interrupt WITHOUT the channel halting only occurs when receiving a short interrupt IN packet
|
||||
and the underlying QTD does not have the HOC bit set. This signifies the last packet of the Interrupt transfer
|
||||
as all interrupt packets must MPS sized except the last.
|
||||
*/
|
||||
//The channel isn't halted yet, so we need to halt it manually to stop the execution of the next QTD/packet
|
||||
usbh_ll_chan_halt(chan_obj->regs);
|
||||
usb_dwc_ll_hcchar_disable_chan(chan_obj->regs);
|
||||
/*
|
||||
After setting the halt bit, this will generate another channel halted interrupt. We treat this interrupt as
|
||||
a NONE event, then cycle back with the channel halted interrupt to handle the CPLT event.
|
||||
*/
|
||||
chan_event = USBH_HAL_CHAN_EVENT_NONE;
|
||||
chan_event = USB_DWC_HAL_CHAN_EVENT_NONE;
|
||||
} else {
|
||||
abort(); //Should never reach this point
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
@ -41,7 +40,7 @@ typedef union {
|
|||
uint32_t reserved10: 10;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gotgctl_reg_t;
|
||||
} usb_dwc_gotgctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -57,7 +56,7 @@ typedef union {
|
|||
uint32_t reserved12: 12;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gotgint_reg_t;
|
||||
} usb_dwc_gotgint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -76,7 +75,7 @@ typedef union {
|
|||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_gahbcfg_reg_t;
|
||||
} usb_dwc_gahbcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -98,7 +97,7 @@ typedef union {
|
|||
uint32_t corrupttxpkt: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gusbcfg_reg_t;
|
||||
} usb_dwc_gusbcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -114,7 +113,7 @@ typedef union {
|
|||
uint32_t ahbidle: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grstctl_reg_t;
|
||||
} usb_dwc_grstctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -151,7 +150,7 @@ typedef union {
|
|||
uint32_t wkupint: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gintsts_reg_t;
|
||||
} usb_dwc_gintsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -188,7 +187,7 @@ typedef union {
|
|||
uint32_t wkupintmsk: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gintmsk_reg_t;
|
||||
} usb_dwc_gintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -200,7 +199,7 @@ typedef union {
|
|||
uint32_t reserved7: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxstsr_reg_t;
|
||||
} usb_dwc_grxstsr_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -212,7 +211,7 @@ typedef union {
|
|||
uint32_t reserved7: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxstsp_reg_t;
|
||||
} usb_dwc_grxstsp_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -220,7 +219,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxfsiz_reg_t;
|
||||
} usb_dwc_grxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -228,7 +227,7 @@ typedef union {
|
|||
uint32_t nptxfdep: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gnptxfsiz_reg_t;
|
||||
} usb_dwc_gnptxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -239,21 +238,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gnptxsts_reg_t;
|
||||
} usb_dwc_gnptxsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t synopsysid;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gsnpsid_reg_t;
|
||||
} usb_dwc_gsnpsid_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t epdir;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg1_reg_t;
|
||||
} usb_dwc_ghwcfg1_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -274,7 +273,7 @@ typedef union {
|
|||
uint32_t reserved1b: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg2_reg_t;
|
||||
} usb_dwc_ghwcfg2_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -292,7 +291,7 @@ typedef union {
|
|||
uint32_t dfifodepth: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg3_reg_t;
|
||||
} usb_dwc_ghwcfg3_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -317,7 +316,7 @@ typedef union {
|
|||
uint32_t g_descdma: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg4_reg_t;
|
||||
} usb_dwc_ghwcfg4_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -326,7 +325,7 @@ typedef union {
|
|||
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gdfifocfg_reg_t;
|
||||
} usb_dwc_gdfifocfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -334,7 +333,7 @@ typedef union {
|
|||
uint32_t ptxfsize: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hptxfsiz_reg_t;
|
||||
} usb_dwc_hptxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -342,7 +341,7 @@ typedef union {
|
|||
uint32_t inep1txfdep: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptxfi_reg_t;
|
||||
} usb_dwc_dieptxfi_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -360,7 +359,7 @@ typedef union {
|
|||
uint32_t modechtimen: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hcfg_reg_t;
|
||||
} usb_dwc_hcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -369,7 +368,7 @@ typedef union {
|
|||
uint32_t reserved15: 15;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hfir_reg_t;
|
||||
} usb_dwc_hfir_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -378,7 +377,7 @@ typedef union {
|
|||
uint32_t frrem: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hfnum_reg_t;
|
||||
} usb_dwc_hfnum_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -388,7 +387,7 @@ typedef union {
|
|||
uint32_t ptxqtop: 8;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hptxsts_reg_t;
|
||||
} usb_dwc_hptxsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -396,7 +395,7 @@ typedef union {
|
|||
uint32_t reserved24: 24;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_haint_reg_t;
|
||||
} usb_dwc_haint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -404,14 +403,14 @@ typedef union {
|
|||
uint32_t reserved24: 24;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_haintmsk_reg_t;
|
||||
} usb_dwc_haintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t hflbaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hflbaddr_reg_t;
|
||||
} usb_dwc_hflbaddr_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -432,7 +431,7 @@ typedef union {
|
|||
uint32_t reserved13: 13;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hprt_reg_t;
|
||||
} usb_dwc_hprt_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -449,8 +448,7 @@ typedef union {
|
|||
uint32_t chena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked with changes
|
||||
} usb_hcchar_reg_t;
|
||||
} usb_dwc_hcchar_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -471,8 +469,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcint_reg_t;
|
||||
} usb_dwc_hcint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -493,8 +490,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcintmsk_reg_t;
|
||||
} usb_dwc_hcintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -506,8 +502,7 @@ typedef union {
|
|||
uint32_t dopng: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hctsiz_reg_t;
|
||||
} usb_dwc_hctsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -520,15 +515,14 @@ typedef union {
|
|||
uint32_t dmaaddr_ctd: 29;
|
||||
} iso;
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcdma_reg_t;
|
||||
} usb_dwc_hcdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t hcdmab;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hcdmab_reg_t;
|
||||
} usb_dwc_hcdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -547,7 +541,7 @@ typedef union {
|
|||
uint32_t resvalid: 6;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dcfg_reg_t;
|
||||
} usb_dwc_dcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -570,7 +564,7 @@ typedef union {
|
|||
uint32_t reserved3: 13;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dctl_reg_t;
|
||||
} usb_dwc_dctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -583,7 +577,7 @@ typedef union {
|
|||
uint32_t reserved8: 8;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dsts_reg_t;
|
||||
} usb_dwc_dsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -602,7 +596,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepmsk_reg_t;
|
||||
} usb_dwc_diepmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -623,7 +617,7 @@ typedef union {
|
|||
uint32_t reserved17: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepmsk_reg_t;
|
||||
} usb_dwc_doepmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -645,7 +639,7 @@ typedef union {
|
|||
uint32_t reserved9b: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_daint_reg_t;
|
||||
} usb_dwc_daint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -667,7 +661,7 @@ typedef union {
|
|||
uint32_t reserved9b: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_daintmsk_reg_t;
|
||||
} usb_dwc_daintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -675,7 +669,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dvbusdis_reg_t;
|
||||
} usb_dwc_dvbusdis_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -683,7 +677,7 @@ typedef union {
|
|||
uint32_t reserved20: 20;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dvbuspulse_reg_t;
|
||||
} usb_dwc_dvbuspulse_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -699,7 +693,7 @@ typedef union {
|
|||
uint32_t reserved4: 4;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dthrctl_reg_t;
|
||||
} usb_dwc_dthrctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -707,7 +701,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepempmsk_reg_t;
|
||||
} usb_dwc_diepempmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -728,7 +722,7 @@ typedef union {
|
|||
uint32_t epena0: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepctl0_reg_t;
|
||||
} usb_dwc_diepctl0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -750,7 +744,7 @@ typedef union {
|
|||
uint32_t reserved17: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepint0_reg_t;
|
||||
} usb_dwc_diepint0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -760,14 +754,14 @@ typedef union {
|
|||
uint32_t reserved11: 11;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptsiz0_reg_t;
|
||||
} usb_dwc_dieptsiz0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdma0_reg_t;
|
||||
} usb_dwc_diepdma0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -775,14 +769,14 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dtxfsts0_reg_t;
|
||||
} usb_dwc_dtxfsts0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdmab0_reg_t;
|
||||
} usb_dwc_diepdmab0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -804,7 +798,7 @@ typedef union {
|
|||
uint32_t epena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepctl_reg_t;
|
||||
} usb_dwc_diepctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -826,7 +820,7 @@ typedef union {
|
|||
uint32_t reserved15: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepint_reg_t;
|
||||
} usb_dwc_diepint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -836,14 +830,14 @@ typedef union {
|
|||
uint32_t reserved11: 11;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptsiz_reg_t;
|
||||
} usb_dwc_dieptsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaddr1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdma_reg_t;
|
||||
} usb_dwc_diepdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -851,14 +845,14 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dtxfsts_reg_t;
|
||||
} usb_dwc_dtxfsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdmab_reg_t;
|
||||
} usb_dwc_diepdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -878,7 +872,7 @@ typedef union {
|
|||
uint32_t epena0: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepctl0_reg_t;
|
||||
} usb_dwc_doepctl0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -901,7 +895,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepint0_reg_t;
|
||||
} usb_dwc_doepint0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -913,21 +907,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doeptsiz0_reg_t;
|
||||
} usb_dwc_doeptsiz0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdma0_reg_t;
|
||||
} usb_dwc_doepdma0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdmab0_reg_t;
|
||||
} usb_dwc_doepdmab0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -948,7 +942,7 @@ typedef union {
|
|||
uint32_t epena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepctl_reg_t;
|
||||
} usb_dwc_doepctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -971,7 +965,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepint_reg_t;
|
||||
} usb_dwc_doepint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -983,21 +977,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doeptsiz_reg_t;
|
||||
} usb_dwc_doeptsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdma_reg_t;
|
||||
} usb_dwc_doepdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdmab_reg_t;
|
||||
} usb_dwc_doepdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -1012,145 +1006,145 @@ typedef union {
|
|||
uint32_t reserved23: 23;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_pcgcctl_reg_t;
|
||||
} usb_dwc_pcgcctl_reg_t;
|
||||
|
||||
/* --------------------------- Register Groups ------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
volatile usb_hcchar_reg_t hcchar_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_hcint_reg_t hcint_reg; //0x08
|
||||
volatile usb_hcintmsk_reg_t hcintmsk_reg; //0x0c
|
||||
volatile usb_hctsiz_reg_t hctsiz_reg; //0x10
|
||||
volatile usb_hcdma_reg_t hcdma_reg; //0x14
|
||||
uint32_t reserved_0x14_0x14[1]; //0x18*
|
||||
volatile usb_hcdmab_reg_t hcdmab_reg; //0x1c
|
||||
} usb_host_chan_regs_t;
|
||||
volatile usb_dwc_hcchar_reg_t hcchar_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_hcint_reg_t hcint_reg; // 0x08
|
||||
volatile usb_dwc_hcintmsk_reg_t hcintmsk_reg; // 0x0c
|
||||
volatile usb_dwc_hctsiz_reg_t hctsiz_reg; // 0x10
|
||||
volatile usb_dwc_hcdma_reg_t hcdma_reg; // 0x14
|
||||
uint32_t reserved_0x14_0x14[1]; // 0x18
|
||||
volatile usb_dwc_hcdmab_reg_t hcdmab_reg; // 0x1c
|
||||
} usb_dwc_host_chan_regs_t;
|
||||
|
||||
typedef struct {
|
||||
volatile usb_diepctl_reg_t diepctl_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_diepint_reg_t diepint_reg; //0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; //0x0c
|
||||
volatile usb_dieptsiz_reg_t dieptsiz_reg; //0x010
|
||||
volatile usb_diepdma_reg_t diepdma_reg; //0x14
|
||||
volatile usb_dtxfsts_reg_t dtxfsts_reg; //0x18
|
||||
volatile usb_diepdmab_reg_t diepdmab_reg; //0x1c
|
||||
} usb_in_ep_regs_t;
|
||||
volatile usb_dwc_diepctl_reg_t diepctl_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_diepint_reg_t diepint_reg; // 0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; // 0x0c
|
||||
volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x010
|
||||
volatile usb_dwc_diepdma_reg_t diepdma_reg; // 0x14
|
||||
volatile usb_dwc_dtxfsts_reg_t dtxfsts_reg; // 0x18
|
||||
volatile usb_dwc_diepdmab_reg_t diepdmab_reg; // 0x1c
|
||||
} usb_dwc_in_ep_regs_t;
|
||||
|
||||
typedef struct {
|
||||
volatile usb_doepctl_reg_t doepctl_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_doepint_reg_t doepint_reg; //0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; //0x0c
|
||||
volatile usb_doeptsiz_reg_t doeptsiz_reg; //0x10
|
||||
volatile usb_doepdma_reg_t doepdma_reg; //0x14
|
||||
uint32_t reserved_0x18_0x1c[1]; //0x18
|
||||
volatile usb_doepdmab_reg_t doepdmab_reg; //0x1c
|
||||
} usb_out_ep_regs_t;
|
||||
volatile usb_dwc_doepctl_reg_t doepctl_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_doepint_reg_t doepint_reg; // 0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; // 0x0c
|
||||
volatile usb_dwc_doeptsiz_reg_t doeptsiz_reg; // 0x10
|
||||
volatile usb_dwc_doepdma_reg_t doepdma_reg; // 0x14
|
||||
uint32_t reserved_0x18_0x1c[1]; // 0x18
|
||||
volatile usb_dwc_doepdmab_reg_t doepdmab_reg; // 0x1c
|
||||
} usb_dwc_out_ep_regs_t;
|
||||
|
||||
/* --------------------------- Register Layout ------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
//Global Registers
|
||||
volatile usb_gotgctl_reg_t gotgctl_reg; //0x0000
|
||||
volatile usb_gotgint_reg_t gotgint_reg; //0x0004
|
||||
volatile usb_gahbcfg_reg_t gahbcfg_reg; //0x0008
|
||||
volatile usb_gusbcfg_reg_t gusbcfg_reg; //0x000c
|
||||
volatile usb_grstctl_reg_t grstctl_reg; //0x0010
|
||||
volatile usb_gintsts_reg_t gintsts_reg; //0x0014
|
||||
volatile usb_gintmsk_reg_t gintmsk_reg; //0x0018
|
||||
volatile usb_grxstsr_reg_t grxstsr_reg; //0x001c
|
||||
volatile usb_grxstsp_reg_t grxstsp_reg; //0x0020
|
||||
volatile usb_grxfsiz_reg_t grxfsiz_reg; //0x0024
|
||||
volatile usb_gnptxfsiz_reg_t gnptxfsiz_reg; //0x0028
|
||||
volatile usb_gnptxsts_reg_t gnptxsts_reg; //0x002c
|
||||
uint32_t reserved_0x0030_0x0040[4]; //0x0030 to 0x0040
|
||||
volatile usb_gsnpsid_reg_t gsnpsid_reg; //0x0040
|
||||
volatile usb_ghwcfg1_reg_t ghwcfg1_reg; //0x0044
|
||||
volatile usb_ghwcfg2_reg_t ghwcfg2_reg; //0x0048
|
||||
volatile usb_ghwcfg3_reg_t ghwcfg3_reg; //0x004c
|
||||
volatile usb_ghwcfg4_reg_t ghwcfg4_reg; //0x0050
|
||||
uint32_t reserved_0x0054_0x005c[2]; //0x0054 to 0x005c
|
||||
volatile usb_dwc_gotgctl_reg_t gotgctl_reg; // 0x0000
|
||||
volatile usb_dwc_gotgint_reg_t gotgint_reg; // 0x0004
|
||||
volatile usb_dwc_gahbcfg_reg_t gahbcfg_reg; // 0x0008
|
||||
volatile usb_dwc_gusbcfg_reg_t gusbcfg_reg; // 0x000c
|
||||
volatile usb_dwc_grstctl_reg_t grstctl_reg; // 0x0010
|
||||
volatile usb_dwc_gintsts_reg_t gintsts_reg; // 0x0014
|
||||
volatile usb_dwc_gintmsk_reg_t gintmsk_reg; // 0x0018
|
||||
volatile usb_dwc_grxstsr_reg_t grxstsr_reg; // 0x001c
|
||||
volatile usb_dwc_grxstsp_reg_t grxstsp_reg; // 0x0020
|
||||
volatile usb_dwc_grxfsiz_reg_t grxfsiz_reg; // 0x0024
|
||||
volatile usb_dwc_gnptxfsiz_reg_t gnptxfsiz_reg; // 0x0028
|
||||
volatile usb_dwc_gnptxsts_reg_t gnptxsts_reg; // 0x002c
|
||||
uint32_t reserved_0x0030_0x0040[4]; // 0x0030 to 0x0040
|
||||
volatile usb_dwc_gsnpsid_reg_t gsnpsid_reg; // 0x0040
|
||||
volatile usb_dwc_ghwcfg1_reg_t ghwcfg1_reg; // 0x0044
|
||||
volatile usb_dwc_ghwcfg2_reg_t ghwcfg2_reg; // 0x0048
|
||||
volatile usb_dwc_ghwcfg3_reg_t ghwcfg3_reg; // 0x004c
|
||||
volatile usb_dwc_ghwcfg4_reg_t ghwcfg4_reg; // 0x0050
|
||||
uint32_t reserved_0x0054_0x005c[2]; // 0x0054 to 0x005c
|
||||
|
||||
//FIFO Configurations
|
||||
volatile usb_gdfifocfg_reg_t gdfifocfg_reg; //0x005c
|
||||
uint32_t reserved_0x0060_0x0100[40]; //0x0060 to 0x0100
|
||||
volatile usb_hptxfsiz_reg_t hptxfsiz_reg; //0x0100
|
||||
volatile usb_dieptxfi_reg_t dieptxfi_regs[4]; //0x0104 to 0x0114
|
||||
usb_dieptxfi_reg_t reserved_0x0114_0x0140[11]; //0x0114 to 0x0140
|
||||
uint32_t reserved_0x140_0x400[176]; //0x0140 to 0x0400
|
||||
volatile usb_dwc_gdfifocfg_reg_t gdfifocfg_reg; // 0x005c
|
||||
uint32_t reserved_0x0060_0x0100[40]; // 0x0060 to 0x0100
|
||||
volatile usb_dwc_hptxfsiz_reg_t hptxfsiz_reg; // 0x0100
|
||||
volatile usb_dwc_dieptxfi_reg_t dieptxfi_regs[4]; // 0x0104 to 0x0114
|
||||
usb_dwc_dieptxfi_reg_t reserved_0x0114_0x0140[11]; // 0x0114 to 0x0140
|
||||
uint32_t reserved_0x140_0x400[176]; // 0x0140 to 0x0400
|
||||
|
||||
//Host Mode Registers
|
||||
volatile usb_hcfg_reg_t hcfg_reg; //0x0400
|
||||
volatile usb_hfir_reg_t hfir_reg; //0x0404
|
||||
volatile usb_hfnum_reg_t hfnum_reg; //0x0408
|
||||
uint32_t reserved_0x40c_0x410[1]; //0x040c to 0x0410
|
||||
volatile usb_hptxsts_reg_t hptxsts_reg; //0x0410
|
||||
volatile usb_haint_reg_t haint_reg; //0x0414
|
||||
volatile usb_haintmsk_reg_t haintmsk_reg; //0x0418
|
||||
volatile usb_hflbaddr_reg_t hflbaddr_reg; //0x041c
|
||||
uint32_t reserved_0x420_0x440[8]; //0x0420 to 0x0440
|
||||
volatile usb_hprt_reg_t hprt_reg; //0x0440
|
||||
uint32_t reserved_0x0444_0x0500[47]; //0x0444 to 0x0500
|
||||
usb_host_chan_regs_t host_chans[8]; //0x0500 to 0x0600
|
||||
usb_host_chan_regs_t reserved_0x0600_0x0700[8]; //0x0600 to 0x0700
|
||||
uint32_t reserved_0x0700_0x0800[64]; //0x0700 to 0x0800
|
||||
volatile usb_dcfg_reg_t dcfg_reg; //0x0800
|
||||
volatile usb_dctl_reg_t dctl_reg; //0x0804
|
||||
volatile usb_dsts_reg_t dsts_reg; //0x0808
|
||||
uint32_t reserved_0x080c_0x0810[1]; //0x080c to 0x0810
|
||||
volatile usb_dwc_hcfg_reg_t hcfg_reg; // 0x0400
|
||||
volatile usb_dwc_hfir_reg_t hfir_reg; // 0x0404
|
||||
volatile usb_dwc_hfnum_reg_t hfnum_reg; // 0x0408
|
||||
uint32_t reserved_0x40c_0x410[1]; // 0x040c to 0x0410
|
||||
volatile usb_dwc_hptxsts_reg_t hptxsts_reg; // 0x0410
|
||||
volatile usb_dwc_haint_reg_t haint_reg; // 0x0414
|
||||
volatile usb_dwc_haintmsk_reg_t haintmsk_reg; // 0x0418
|
||||
volatile usb_dwc_hflbaddr_reg_t hflbaddr_reg; // 0x041c
|
||||
uint32_t reserved_0x420_0x440[8]; // 0x0420 to 0x0440
|
||||
volatile usb_dwc_hprt_reg_t hprt_reg; // 0x0440
|
||||
uint32_t reserved_0x0444_0x0500[47]; // 0x0444 to 0x0500
|
||||
usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x0600
|
||||
usb_dwc_host_chan_regs_t reserved_0x0600_0x0700[8]; // 0x0600 to 0x0700
|
||||
uint32_t reserved_0x0700_0x0800[64]; // 0x0700 to 0x0800
|
||||
volatile usb_dwc_dcfg_reg_t dcfg_reg; // 0x0800
|
||||
volatile usb_dwc_dctl_reg_t dctl_reg; // 0x0804
|
||||
volatile usb_dwc_dsts_reg_t dsts_reg; // 0x0808
|
||||
uint32_t reserved_0x080c_0x0810[1]; // 0x080c to 0x0810
|
||||
|
||||
//Device Mode Registers
|
||||
volatile usb_diepmsk_reg_t diepmsk_reg; //0x810
|
||||
volatile usb_doepmsk_reg_t doepmsk_reg; //0x0814
|
||||
volatile usb_daint_reg_t daint_reg; //0x0818
|
||||
volatile usb_daintmsk_reg_t daintmsk_reg; //0x081c
|
||||
uint32_t reserved_0x0820_0x0828[2]; //0x0820 to 0x0828
|
||||
volatile usb_dvbusdis_reg_t dvbusdis_reg; //0x0828
|
||||
volatile usb_dvbuspulse_reg_t dvbuspulse_reg; //0x082c
|
||||
volatile usb_dthrctl_reg_t dthrctl_reg; //0x0830
|
||||
volatile usb_diepempmsk_reg_t diepempmsk_reg; //0x0834
|
||||
uint32_t reserved_0x0838_0x0900[50]; //0x0838 to 0x0900
|
||||
volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x810
|
||||
volatile usb_dwc_doepmsk_reg_t doepmsk_reg; // 0x0814
|
||||
volatile usb_dwc_daint_reg_t daint_reg; // 0x0818
|
||||
volatile usb_dwc_daintmsk_reg_t daintmsk_reg; // 0x081c
|
||||
uint32_t reserved_0x0820_0x0828[2]; // 0x0820 to 0x0828
|
||||
volatile usb_dwc_dvbusdis_reg_t dvbusdis_reg; // 0x0828
|
||||
volatile usb_dwc_dvbuspulse_reg_t dvbuspulse_reg; // 0x082c
|
||||
volatile usb_dwc_dthrctl_reg_t dthrctl_reg; // 0x0830
|
||||
volatile usb_dwc_diepempmsk_reg_t diepempmsk_reg; // 0x0834
|
||||
uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900
|
||||
|
||||
//Deivce: IN EP0 reigsters
|
||||
volatile usb_diepctl0_reg_t diepctl0_reg; //0x0900
|
||||
uint32_t reserved_0x0904_0x0908[1]; //0x0904 to 0x0908
|
||||
volatile usb_diepint0_reg_t diepint0_reg; //0x0908
|
||||
uint32_t reserved_0x090c_0x0910[1]; //0x090c to 0x0910
|
||||
volatile usb_dieptsiz0_reg_t dieptsiz0_reg; //0x0910
|
||||
volatile usb_diepdma0_reg_t diepdma0_reg; //0x0914
|
||||
volatile usb_dtxfsts0_reg_t dtxfsts0_reg; //0x0918
|
||||
volatile usb_diepdmab0_reg_t diepdmab0_reg; //0x091c
|
||||
volatile usb_dwc_diepctl0_reg_t diepctl0_reg; // 0x0900
|
||||
uint32_t reserved_0x0904_0x0908[1]; // 0x0904 to 0x0908
|
||||
volatile usb_dwc_diepint0_reg_t diepint0_reg; // 0x0908
|
||||
uint32_t reserved_0x090c_0x0910[1]; // 0x090c to 0x0910
|
||||
volatile usb_dwc_dieptsiz0_reg_t dieptsiz0_reg; // 0x0910
|
||||
volatile usb_dwc_diepdma0_reg_t diepdma0_reg; // 0x0914
|
||||
volatile usb_dwc_dtxfsts0_reg_t dtxfsts0_reg; // 0x0918
|
||||
volatile usb_dwc_diepdmab0_reg_t diepdmab0_reg; // 0x091c
|
||||
|
||||
//Deivce: IN EP registers
|
||||
usb_in_ep_regs_t in_eps[6]; //0x0920 to 0x09e0
|
||||
usb_in_ep_regs_t reserved_0x09e0_0x0b00[9]; //0x09e0 to 0x0b00
|
||||
usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09e0
|
||||
usb_dwc_in_ep_regs_t reserved_0x09e0_0x0b00[9]; // 0x09e0 to 0x0b00
|
||||
|
||||
//Device: OUT EP0 reigsters
|
||||
volatile usb_doepctl0_reg_t doepctl0_reg; //0x0b00
|
||||
uint32_t reserved_0x0b04_0x0b08[1]; //0x0b04 to 0x0b08
|
||||
volatile usb_doepint0_reg_t doepint0_reg; //0b0b08
|
||||
uint32_t reserved_0x0b0c_0x0b10[1]; //0x0b0c to 0x0b10
|
||||
volatile usb_doeptsiz0_reg_t doeptsiz0_reg; //0x0b10
|
||||
volatile usb_doepdma0_reg_t doepdma0_reg; //0x0b14
|
||||
uint32_t reserved_0x0b18_0x0b1c[1]; //0x0b18 to 0x0b1c
|
||||
volatile usb_doepdmab0_reg_t doepdmab0_reg; //0x0b1c
|
||||
volatile usb_dwc_doepctl0_reg_t doepctl0_reg; // 0x0b00
|
||||
uint32_t reserved_0x0b04_0x0b08[1]; // 0x0b04 to 0x0b08
|
||||
volatile usb_dwc_doepint0_reg_t doepint0_reg; // 0b0b08
|
||||
uint32_t reserved_0x0b0c_0x0b10[1]; // 0x0b0c to 0x0b10
|
||||
volatile usb_dwc_doeptsiz0_reg_t doeptsiz0_reg; // 0x0b10
|
||||
volatile usb_dwc_doepdma0_reg_t doepdma0_reg; // 0x0b14
|
||||
uint32_t reserved_0x0b18_0x0b1c[1]; // 0x0b18 to 0x0b1c
|
||||
volatile usb_dwc_doepdmab0_reg_t doepdmab0_reg; // 0x0b1c
|
||||
|
||||
//Deivce: OUT EP registers
|
||||
usb_out_ep_regs_t out_eps[6]; //0xb1c
|
||||
usb_out_ep_regs_t reserved_0x0be0_0x0d00[9]; //0x0be0 to 0x0d00
|
||||
uint32_t reserved_0x0d00_0x0e00[64]; //0x0d00 to 0x0e00
|
||||
volatile usb_pcgcctl_reg_t pcgcctl_reg; //0x0e00
|
||||
uint32_t reserved_0x0e04_0x0e08[1]; //0x0d00 to 0x0e00
|
||||
} usbh_dev_t;
|
||||
usb_dwc_out_ep_regs_t out_eps[6]; // 0xb1c
|
||||
usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0d00
|
||||
uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00
|
||||
volatile usb_dwc_pcgcctl_reg_t pcgcctl_reg; // 0x0e00
|
||||
uint32_t reserved_0x0e04_0x0e08[1]; // 0x0d00 to 0x0e00
|
||||
} usb_dwc_dev_t;
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(usbh_dev_t) == 0xe08, "USB new struct should be 0xe08 large");
|
||||
_Static_assert(sizeof(usb_dwc_dev_t) == 0xe08, "Invalid size of usb_dwc_dev_t structure");
|
||||
#endif
|
||||
|
||||
extern usbh_dev_t USBH;
|
||||
extern usb_dwc_dev_t USB_DWC;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
|
@ -35,5 +35,5 @@ PROVIDE ( TWAI = 0x3f42B000 );
|
|||
PROVIDE ( APB_SARADC = 0x3f440000 );
|
||||
PROVIDE ( DEDIC_GPIO = 0x3f4cf000 );
|
||||
PROVIDE ( USB0 = 0x60080000 );
|
||||
PROVIDE ( USBH = 0x60080000 );
|
||||
PROVIDE ( USB_DWC = 0x60080000 );
|
||||
PROVIDE ( USB_WRAP = 0x3f439000 );
|
||||
|
|
|
@ -40,7 +40,7 @@ typedef union {
|
|||
uint32_t reserved10: 10;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gotgctl_reg_t;
|
||||
} usb_dwc_gotgctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -56,7 +56,7 @@ typedef union {
|
|||
uint32_t reserved12: 12;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gotgint_reg_t;
|
||||
} usb_dwc_gotgint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -75,7 +75,7 @@ typedef union {
|
|||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_gahbcfg_reg_t;
|
||||
} usb_dwc_gahbcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -97,7 +97,7 @@ typedef union {
|
|||
uint32_t corrupttxpkt: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gusbcfg_reg_t;
|
||||
} usb_dwc_gusbcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -113,7 +113,7 @@ typedef union {
|
|||
uint32_t ahbidle: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grstctl_reg_t;
|
||||
} usb_dwc_grstctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -150,7 +150,7 @@ typedef union {
|
|||
uint32_t wkupint: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gintsts_reg_t;
|
||||
} usb_dwc_gintsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -187,7 +187,7 @@ typedef union {
|
|||
uint32_t wkupintmsk: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gintmsk_reg_t;
|
||||
} usb_dwc_gintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -199,7 +199,7 @@ typedef union {
|
|||
uint32_t reserved7: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxstsr_reg_t;
|
||||
} usb_dwc_grxstsr_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -211,7 +211,7 @@ typedef union {
|
|||
uint32_t reserved7: 7;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxstsp_reg_t;
|
||||
} usb_dwc_grxstsp_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -219,7 +219,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_grxfsiz_reg_t;
|
||||
} usb_dwc_grxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -227,7 +227,7 @@ typedef union {
|
|||
uint32_t nptxfdep: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gnptxfsiz_reg_t;
|
||||
} usb_dwc_gnptxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -238,21 +238,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gnptxsts_reg_t;
|
||||
} usb_dwc_gnptxsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t synopsysid;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gsnpsid_reg_t;
|
||||
} usb_dwc_gsnpsid_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t epdir;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg1_reg_t;
|
||||
} usb_dwc_ghwcfg1_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -273,7 +273,7 @@ typedef union {
|
|||
uint32_t reserved1b: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg2_reg_t;
|
||||
} usb_dwc_ghwcfg2_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -291,7 +291,7 @@ typedef union {
|
|||
uint32_t dfifodepth: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg3_reg_t;
|
||||
} usb_dwc_ghwcfg3_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -316,7 +316,7 @@ typedef union {
|
|||
uint32_t g_descdma: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_ghwcfg4_reg_t;
|
||||
} usb_dwc_ghwcfg4_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -325,7 +325,7 @@ typedef union {
|
|||
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_gdfifocfg_reg_t;
|
||||
} usb_dwc_gdfifocfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -333,7 +333,7 @@ typedef union {
|
|||
uint32_t ptxfsize: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hptxfsiz_reg_t;
|
||||
} usb_dwc_hptxfsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -341,7 +341,7 @@ typedef union {
|
|||
uint32_t inep1txfdep: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptxfi_reg_t;
|
||||
} usb_dwc_dieptxfi_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -359,7 +359,7 @@ typedef union {
|
|||
uint32_t modechtimen: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hcfg_reg_t;
|
||||
} usb_dwc_hcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -368,7 +368,7 @@ typedef union {
|
|||
uint32_t reserved15: 15;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hfir_reg_t;
|
||||
} usb_dwc_hfir_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -377,7 +377,7 @@ typedef union {
|
|||
uint32_t frrem: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hfnum_reg_t;
|
||||
} usb_dwc_hfnum_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -387,7 +387,7 @@ typedef union {
|
|||
uint32_t ptxqtop: 8;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hptxsts_reg_t;
|
||||
} usb_dwc_hptxsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -395,7 +395,7 @@ typedef union {
|
|||
uint32_t reserved24: 24;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_haint_reg_t;
|
||||
} usb_dwc_haint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -403,14 +403,14 @@ typedef union {
|
|||
uint32_t reserved24: 24;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_haintmsk_reg_t;
|
||||
} usb_dwc_haintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t hflbaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hflbaddr_reg_t;
|
||||
} usb_dwc_hflbaddr_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -431,7 +431,7 @@ typedef union {
|
|||
uint32_t reserved13: 13;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hprt_reg_t;
|
||||
} usb_dwc_hprt_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -448,8 +448,7 @@ typedef union {
|
|||
uint32_t chena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked with changes
|
||||
} usb_hcchar_reg_t;
|
||||
} usb_dwc_hcchar_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -470,8 +469,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcint_reg_t;
|
||||
} usb_dwc_hcint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -492,8 +490,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcintmsk_reg_t;
|
||||
} usb_dwc_hcintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -505,8 +502,7 @@ typedef union {
|
|||
uint32_t dopng: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hctsiz_reg_t;
|
||||
} usb_dwc_hctsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -519,15 +515,14 @@ typedef union {
|
|||
uint32_t dmaaddr_ctd: 29;
|
||||
} iso;
|
||||
uint32_t val;
|
||||
//Checked
|
||||
} usb_hcdma_reg_t;
|
||||
} usb_dwc_hcdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t hcdmab;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_hcdmab_reg_t;
|
||||
} usb_dwc_hcdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -546,7 +541,7 @@ typedef union {
|
|||
uint32_t resvalid: 6;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dcfg_reg_t;
|
||||
} usb_dwc_dcfg_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -569,7 +564,7 @@ typedef union {
|
|||
uint32_t reserved3: 13;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dctl_reg_t;
|
||||
} usb_dwc_dctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -582,7 +577,7 @@ typedef union {
|
|||
uint32_t reserved8: 8;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dsts_reg_t;
|
||||
} usb_dwc_dsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -601,7 +596,7 @@ typedef union {
|
|||
uint32_t reserved18: 18;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepmsk_reg_t;
|
||||
} usb_dwc_diepmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -622,7 +617,7 @@ typedef union {
|
|||
uint32_t reserved17: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepmsk_reg_t;
|
||||
} usb_dwc_doepmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -644,7 +639,7 @@ typedef union {
|
|||
uint32_t reserved9b: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_daint_reg_t;
|
||||
} usb_dwc_daint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -666,7 +661,7 @@ typedef union {
|
|||
uint32_t reserved9b: 9;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_daintmsk_reg_t;
|
||||
} usb_dwc_daintmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -674,7 +669,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dvbusdis_reg_t;
|
||||
} usb_dwc_dvbusdis_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -682,7 +677,7 @@ typedef union {
|
|||
uint32_t reserved20: 20;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dvbuspulse_reg_t;
|
||||
} usb_dwc_dvbuspulse_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -698,7 +693,7 @@ typedef union {
|
|||
uint32_t reserved4: 4;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dthrctl_reg_t;
|
||||
} usb_dwc_dthrctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -706,7 +701,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepempmsk_reg_t;
|
||||
} usb_dwc_diepempmsk_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -727,7 +722,7 @@ typedef union {
|
|||
uint32_t epena0: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepctl0_reg_t;
|
||||
} usb_dwc_diepctl0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -749,7 +744,7 @@ typedef union {
|
|||
uint32_t reserved17: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepint0_reg_t;
|
||||
} usb_dwc_diepint0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -759,14 +754,14 @@ typedef union {
|
|||
uint32_t reserved11: 11;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptsiz0_reg_t;
|
||||
} usb_dwc_dieptsiz0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdma0_reg_t;
|
||||
} usb_dwc_diepdma0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -774,14 +769,14 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dtxfsts0_reg_t;
|
||||
} usb_dwc_dtxfsts0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdmab0_reg_t;
|
||||
} usb_dwc_diepdmab0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -803,7 +798,7 @@ typedef union {
|
|||
uint32_t epena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepctl_reg_t;
|
||||
} usb_dwc_diepctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -825,7 +820,7 @@ typedef union {
|
|||
uint32_t reserved15: 17;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepint_reg_t;
|
||||
} usb_dwc_diepint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -835,14 +830,14 @@ typedef union {
|
|||
uint32_t reserved11: 11;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dieptsiz_reg_t;
|
||||
} usb_dwc_dieptsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaddr1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdma_reg_t;
|
||||
} usb_dwc_diepdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -850,14 +845,14 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_dtxfsts_reg_t;
|
||||
} usb_dwc_dtxfsts_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_diepdmab_reg_t;
|
||||
} usb_dwc_diepdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -877,7 +872,7 @@ typedef union {
|
|||
uint32_t epena0: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepctl0_reg_t;
|
||||
} usb_dwc_doepctl0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -900,7 +895,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepint0_reg_t;
|
||||
} usb_dwc_doepint0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -912,21 +907,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doeptsiz0_reg_t;
|
||||
} usb_dwc_doeptsiz0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdma0_reg_t;
|
||||
} usb_dwc_doepdma0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr0;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdmab0_reg_t;
|
||||
} usb_dwc_doepdmab0_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -947,7 +942,7 @@ typedef union {
|
|||
uint32_t epena: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepctl_reg_t;
|
||||
} usb_dwc_doepctl_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -970,7 +965,7 @@ typedef union {
|
|||
uint32_t reserved16: 16;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepint_reg_t;
|
||||
} usb_dwc_doepint_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -982,21 +977,21 @@ typedef union {
|
|||
uint32_t reserved1: 1;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doeptsiz_reg_t;
|
||||
} usb_dwc_doeptsiz_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmaaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdma_reg_t;
|
||||
} usb_dwc_doepdma_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t dmabufferaddr;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_doepdmab_reg_t;
|
||||
} usb_dwc_doepdmab_reg_t;
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
|
@ -1011,145 +1006,145 @@ typedef union {
|
|||
uint32_t reserved23: 23;
|
||||
};
|
||||
uint32_t val;
|
||||
} usb_pcgcctl_reg_t;
|
||||
} usb_dwc_pcgcctl_reg_t;
|
||||
|
||||
/* --------------------------- Register Groups ------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
volatile usb_hcchar_reg_t hcchar_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_hcint_reg_t hcint_reg; //0x08
|
||||
volatile usb_hcintmsk_reg_t hcintmsk_reg; //0x0c
|
||||
volatile usb_hctsiz_reg_t hctsiz_reg; //0x10
|
||||
volatile usb_hcdma_reg_t hcdma_reg; //0x14
|
||||
uint32_t reserved_0x14_0x14[1]; //0x18*
|
||||
volatile usb_hcdmab_reg_t hcdmab_reg; //0x1c
|
||||
} usb_host_chan_regs_t;
|
||||
volatile usb_dwc_hcchar_reg_t hcchar_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_hcint_reg_t hcint_reg; // 0x08
|
||||
volatile usb_dwc_hcintmsk_reg_t hcintmsk_reg; // 0x0c
|
||||
volatile usb_dwc_hctsiz_reg_t hctsiz_reg; // 0x10
|
||||
volatile usb_dwc_hcdma_reg_t hcdma_reg; // 0x14
|
||||
uint32_t reserved_0x14_0x14[1]; // 0x18
|
||||
volatile usb_dwc_hcdmab_reg_t hcdmab_reg; // 0x1c
|
||||
} usb_dwc_host_chan_regs_t;
|
||||
|
||||
typedef struct {
|
||||
volatile usb_diepctl_reg_t diepctl_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_diepint_reg_t diepint_reg; //0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; //0x0c
|
||||
volatile usb_dieptsiz_reg_t dieptsiz_reg; //0x010
|
||||
volatile usb_diepdma_reg_t diepdma_reg; //0x14
|
||||
volatile usb_dtxfsts_reg_t dtxfsts_reg; //0x18
|
||||
volatile usb_diepdmab_reg_t diepdmab_reg; //0x1c
|
||||
} usb_in_ep_regs_t;
|
||||
volatile usb_dwc_diepctl_reg_t diepctl_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_diepint_reg_t diepint_reg; // 0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; // 0x0c
|
||||
volatile usb_dwc_dieptsiz_reg_t dieptsiz_reg; // 0x010
|
||||
volatile usb_dwc_diepdma_reg_t diepdma_reg; // 0x14
|
||||
volatile usb_dwc_dtxfsts_reg_t dtxfsts_reg; // 0x18
|
||||
volatile usb_dwc_diepdmab_reg_t diepdmab_reg; // 0x1c
|
||||
} usb_dwc_in_ep_regs_t;
|
||||
|
||||
typedef struct {
|
||||
volatile usb_doepctl_reg_t doepctl_reg; //0x00
|
||||
uint32_t reserved_0x04_0x08[1]; //0x04
|
||||
volatile usb_doepint_reg_t doepint_reg; //0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; //0x0c
|
||||
volatile usb_doeptsiz_reg_t doeptsiz_reg; //0x10
|
||||
volatile usb_doepdma_reg_t doepdma_reg; //0x14
|
||||
uint32_t reserved_0x18_0x1c[1]; //0x18
|
||||
volatile usb_doepdmab_reg_t doepdmab_reg; //0x1c
|
||||
} usb_out_ep_regs_t;
|
||||
volatile usb_dwc_doepctl_reg_t doepctl_reg; // 0x00
|
||||
uint32_t reserved_0x04_0x08[1]; // 0x04
|
||||
volatile usb_dwc_doepint_reg_t doepint_reg; // 0x08
|
||||
uint32_t reserved_0x0c_0x10[1]; // 0x0c
|
||||
volatile usb_dwc_doeptsiz_reg_t doeptsiz_reg; // 0x10
|
||||
volatile usb_dwc_doepdma_reg_t doepdma_reg; // 0x14
|
||||
uint32_t reserved_0x18_0x1c[1]; // 0x18
|
||||
volatile usb_dwc_doepdmab_reg_t doepdmab_reg; // 0x1c
|
||||
} usb_dwc_out_ep_regs_t;
|
||||
|
||||
/* --------------------------- Register Layout ------------------------------ */
|
||||
|
||||
typedef struct {
|
||||
//Global Registers
|
||||
volatile usb_gotgctl_reg_t gotgctl_reg; //0x0000
|
||||
volatile usb_gotgint_reg_t gotgint_reg; //0x0004
|
||||
volatile usb_gahbcfg_reg_t gahbcfg_reg; //0x0008
|
||||
volatile usb_gusbcfg_reg_t gusbcfg_reg; //0x000c
|
||||
volatile usb_grstctl_reg_t grstctl_reg; //0x0010
|
||||
volatile usb_gintsts_reg_t gintsts_reg; //0x0014
|
||||
volatile usb_gintmsk_reg_t gintmsk_reg; //0x0018
|
||||
volatile usb_grxstsr_reg_t grxstsr_reg; //0x001c
|
||||
volatile usb_grxstsp_reg_t grxstsp_reg; //0x0020
|
||||
volatile usb_grxfsiz_reg_t grxfsiz_reg; //0x0024
|
||||
volatile usb_gnptxfsiz_reg_t gnptxfsiz_reg; //0x0028
|
||||
volatile usb_gnptxsts_reg_t gnptxsts_reg; //0x002c
|
||||
uint32_t reserved_0x0030_0x0040[4]; //0x0030 to 0x0040
|
||||
volatile usb_gsnpsid_reg_t gsnpsid_reg; //0x0040
|
||||
volatile usb_ghwcfg1_reg_t ghwcfg1_reg; //0x0044
|
||||
volatile usb_ghwcfg2_reg_t ghwcfg2_reg; //0x0048
|
||||
volatile usb_ghwcfg3_reg_t ghwcfg3_reg; //0x004c
|
||||
volatile usb_ghwcfg4_reg_t ghwcfg4_reg; //0x0050
|
||||
uint32_t reserved_0x0054_0x005c[2]; //0x0054 to 0x005c
|
||||
volatile usb_dwc_gotgctl_reg_t gotgctl_reg; // 0x0000
|
||||
volatile usb_dwc_gotgint_reg_t gotgint_reg; // 0x0004
|
||||
volatile usb_dwc_gahbcfg_reg_t gahbcfg_reg; // 0x0008
|
||||
volatile usb_dwc_gusbcfg_reg_t gusbcfg_reg; // 0x000c
|
||||
volatile usb_dwc_grstctl_reg_t grstctl_reg; // 0x0010
|
||||
volatile usb_dwc_gintsts_reg_t gintsts_reg; // 0x0014
|
||||
volatile usb_dwc_gintmsk_reg_t gintmsk_reg; // 0x0018
|
||||
volatile usb_dwc_grxstsr_reg_t grxstsr_reg; // 0x001c
|
||||
volatile usb_dwc_grxstsp_reg_t grxstsp_reg; // 0x0020
|
||||
volatile usb_dwc_grxfsiz_reg_t grxfsiz_reg; // 0x0024
|
||||
volatile usb_dwc_gnptxfsiz_reg_t gnptxfsiz_reg; // 0x0028
|
||||
volatile usb_dwc_gnptxsts_reg_t gnptxsts_reg; // 0x002c
|
||||
uint32_t reserved_0x0030_0x0040[4]; // 0x0030 to 0x0040
|
||||
volatile usb_dwc_gsnpsid_reg_t gsnpsid_reg; // 0x0040
|
||||
volatile usb_dwc_ghwcfg1_reg_t ghwcfg1_reg; // 0x0044
|
||||
volatile usb_dwc_ghwcfg2_reg_t ghwcfg2_reg; // 0x0048
|
||||
volatile usb_dwc_ghwcfg3_reg_t ghwcfg3_reg; // 0x004c
|
||||
volatile usb_dwc_ghwcfg4_reg_t ghwcfg4_reg; // 0x0050
|
||||
uint32_t reserved_0x0054_0x005c[2]; // 0x0054 to 0x005c
|
||||
|
||||
//FIFO Configurations
|
||||
volatile usb_gdfifocfg_reg_t gdfifocfg_reg; //0x005c
|
||||
uint32_t reserved_0x0060_0x0100[40]; //0x0060 to 0x0100
|
||||
volatile usb_hptxfsiz_reg_t hptxfsiz_reg; //0x0100
|
||||
volatile usb_dieptxfi_reg_t dieptxfi_regs[4]; //0x0104 to 0x0114
|
||||
usb_dieptxfi_reg_t reserved_0x0114_0x0140[11]; //0x0114 to 0x0140
|
||||
uint32_t reserved_0x140_0x400[176]; //0x0140 to 0x0400
|
||||
volatile usb_dwc_gdfifocfg_reg_t gdfifocfg_reg; // 0x005c
|
||||
uint32_t reserved_0x0060_0x0100[40]; // 0x0060 to 0x0100
|
||||
volatile usb_dwc_hptxfsiz_reg_t hptxfsiz_reg; // 0x0100
|
||||
volatile usb_dwc_dieptxfi_reg_t dieptxfi_regs[4]; // 0x0104 to 0x0114
|
||||
usb_dwc_dieptxfi_reg_t reserved_0x0114_0x0140[11]; // 0x0114 to 0x0140
|
||||
uint32_t reserved_0x140_0x400[176]; // 0x0140 to 0x0400
|
||||
|
||||
//Host Mode Registers
|
||||
volatile usb_hcfg_reg_t hcfg_reg; //0x0400
|
||||
volatile usb_hfir_reg_t hfir_reg; //0x0404
|
||||
volatile usb_hfnum_reg_t hfnum_reg; //0x0408
|
||||
uint32_t reserved_0x40c_0x410[1]; //0x040c to 0x0410
|
||||
volatile usb_hptxsts_reg_t hptxsts_reg; //0x0410
|
||||
volatile usb_haint_reg_t haint_reg; //0x0414
|
||||
volatile usb_haintmsk_reg_t haintmsk_reg; //0x0418
|
||||
volatile usb_hflbaddr_reg_t hflbaddr_reg; //0x041c
|
||||
uint32_t reserved_0x420_0x440[8]; //0x0420 to 0x0440
|
||||
volatile usb_hprt_reg_t hprt_reg; //0x0440
|
||||
uint32_t reserved_0x0444_0x0500[47]; //0x0444 to 0x0500
|
||||
usb_host_chan_regs_t host_chans[8]; //0x0500 to 0x0600
|
||||
usb_host_chan_regs_t reserved_0x0600_0x0700[8]; //0x0600 to 0x0700
|
||||
uint32_t reserved_0x0700_0x0800[64]; //0x0700 to 0x0800
|
||||
volatile usb_dcfg_reg_t dcfg_reg; //0x0800
|
||||
volatile usb_dctl_reg_t dctl_reg; //0x0804
|
||||
volatile usb_dsts_reg_t dsts_reg; //0x0808
|
||||
uint32_t reserved_0x080c_0x0810[1]; //0x080c to 0x0810
|
||||
volatile usb_dwc_hcfg_reg_t hcfg_reg; // 0x0400
|
||||
volatile usb_dwc_hfir_reg_t hfir_reg; // 0x0404
|
||||
volatile usb_dwc_hfnum_reg_t hfnum_reg; // 0x0408
|
||||
uint32_t reserved_0x40c_0x410[1]; // 0x040c to 0x0410
|
||||
volatile usb_dwc_hptxsts_reg_t hptxsts_reg; // 0x0410
|
||||
volatile usb_dwc_haint_reg_t haint_reg; // 0x0414
|
||||
volatile usb_dwc_haintmsk_reg_t haintmsk_reg; // 0x0418
|
||||
volatile usb_dwc_hflbaddr_reg_t hflbaddr_reg; // 0x041c
|
||||
uint32_t reserved_0x420_0x440[8]; // 0x0420 to 0x0440
|
||||
volatile usb_dwc_hprt_reg_t hprt_reg; // 0x0440
|
||||
uint32_t reserved_0x0444_0x0500[47]; // 0x0444 to 0x0500
|
||||
usb_dwc_host_chan_regs_t host_chans[8]; // 0x0500 to 0x0600
|
||||
usb_dwc_host_chan_regs_t reserved_0x0600_0x0700[8]; // 0x0600 to 0x0700
|
||||
uint32_t reserved_0x0700_0x0800[64]; // 0x0700 to 0x0800
|
||||
volatile usb_dwc_dcfg_reg_t dcfg_reg; // 0x0800
|
||||
volatile usb_dwc_dctl_reg_t dctl_reg; // 0x0804
|
||||
volatile usb_dwc_dsts_reg_t dsts_reg; // 0x0808
|
||||
uint32_t reserved_0x080c_0x0810[1]; // 0x080c to 0x0810
|
||||
|
||||
//Device Mode Registers
|
||||
volatile usb_diepmsk_reg_t diepmsk_reg; //0x810
|
||||
volatile usb_doepmsk_reg_t doepmsk_reg; //0x0814
|
||||
volatile usb_daint_reg_t daint_reg; //0x0818
|
||||
volatile usb_daintmsk_reg_t daintmsk_reg; //0x081c
|
||||
uint32_t reserved_0x0820_0x0828[2]; //0x0820 to 0x0828
|
||||
volatile usb_dvbusdis_reg_t dvbusdis_reg; //0x0828
|
||||
volatile usb_dvbuspulse_reg_t dvbuspulse_reg; //0x082c
|
||||
volatile usb_dthrctl_reg_t dthrctl_reg; //0x0830
|
||||
volatile usb_diepempmsk_reg_t diepempmsk_reg; //0x0834
|
||||
uint32_t reserved_0x0838_0x0900[50]; //0x0838 to 0x0900
|
||||
volatile usb_dwc_diepmsk_reg_t diepmsk_reg; // 0x810
|
||||
volatile usb_dwc_doepmsk_reg_t doepmsk_reg; // 0x0814
|
||||
volatile usb_dwc_daint_reg_t daint_reg; // 0x0818
|
||||
volatile usb_dwc_daintmsk_reg_t daintmsk_reg; // 0x081c
|
||||
uint32_t reserved_0x0820_0x0828[2]; // 0x0820 to 0x0828
|
||||
volatile usb_dwc_dvbusdis_reg_t dvbusdis_reg; // 0x0828
|
||||
volatile usb_dwc_dvbuspulse_reg_t dvbuspulse_reg; // 0x082c
|
||||
volatile usb_dwc_dthrctl_reg_t dthrctl_reg; // 0x0830
|
||||
volatile usb_dwc_diepempmsk_reg_t diepempmsk_reg; // 0x0834
|
||||
uint32_t reserved_0x0838_0x0900[50]; // 0x0838 to 0x0900
|
||||
|
||||
//Deivce: IN EP0 reigsters
|
||||
volatile usb_diepctl0_reg_t diepctl0_reg; //0x0900
|
||||
uint32_t reserved_0x0904_0x0908[1]; //0x0904 to 0x0908
|
||||
volatile usb_diepint0_reg_t diepint0_reg; //0x0908
|
||||
uint32_t reserved_0x090c_0x0910[1]; //0x090c to 0x0910
|
||||
volatile usb_dieptsiz0_reg_t dieptsiz0_reg; //0x0910
|
||||
volatile usb_diepdma0_reg_t diepdma0_reg; //0x0914
|
||||
volatile usb_dtxfsts0_reg_t dtxfsts0_reg; //0x0918
|
||||
volatile usb_diepdmab0_reg_t diepdmab0_reg; //0x091c
|
||||
volatile usb_dwc_diepctl0_reg_t diepctl0_reg; // 0x0900
|
||||
uint32_t reserved_0x0904_0x0908[1]; // 0x0904 to 0x0908
|
||||
volatile usb_dwc_diepint0_reg_t diepint0_reg; // 0x0908
|
||||
uint32_t reserved_0x090c_0x0910[1]; // 0x090c to 0x0910
|
||||
volatile usb_dwc_dieptsiz0_reg_t dieptsiz0_reg; // 0x0910
|
||||
volatile usb_dwc_diepdma0_reg_t diepdma0_reg; // 0x0914
|
||||
volatile usb_dwc_dtxfsts0_reg_t dtxfsts0_reg; // 0x0918
|
||||
volatile usb_dwc_diepdmab0_reg_t diepdmab0_reg; // 0x091c
|
||||
|
||||
//Deivce: IN EP registers
|
||||
usb_in_ep_regs_t in_eps[6]; //0x0920 to 0x09e0
|
||||
usb_in_ep_regs_t reserved_0x09e0_0x0b00[9]; //0x09e0 to 0x0b00
|
||||
usb_dwc_in_ep_regs_t in_eps[6]; // 0x0920 to 0x09e0
|
||||
usb_dwc_in_ep_regs_t reserved_0x09e0_0x0b00[9]; // 0x09e0 to 0x0b00
|
||||
|
||||
//Device: OUT EP0 reigsters
|
||||
volatile usb_doepctl0_reg_t doepctl0_reg; //0x0b00
|
||||
uint32_t reserved_0x0b04_0x0b08[1]; //0x0b04 to 0x0b08
|
||||
volatile usb_doepint0_reg_t doepint0_reg; //0b0b08
|
||||
uint32_t reserved_0x0b0c_0x0b10[1]; //0x0b0c to 0x0b10
|
||||
volatile usb_doeptsiz0_reg_t doeptsiz0_reg; //0x0b10
|
||||
volatile usb_doepdma0_reg_t doepdma0_reg; //0x0b14
|
||||
uint32_t reserved_0x0b18_0x0b1c[1]; //0x0b18 to 0x0b1c
|
||||
volatile usb_doepdmab0_reg_t doepdmab0_reg; //0x0b1c
|
||||
volatile usb_dwc_doepctl0_reg_t doepctl0_reg; // 0x0b00
|
||||
uint32_t reserved_0x0b04_0x0b08[1]; // 0x0b04 to 0x0b08
|
||||
volatile usb_dwc_doepint0_reg_t doepint0_reg; // 0b0b08
|
||||
uint32_t reserved_0x0b0c_0x0b10[1]; // 0x0b0c to 0x0b10
|
||||
volatile usb_dwc_doeptsiz0_reg_t doeptsiz0_reg; // 0x0b10
|
||||
volatile usb_dwc_doepdma0_reg_t doepdma0_reg; // 0x0b14
|
||||
uint32_t reserved_0x0b18_0x0b1c[1]; // 0x0b18 to 0x0b1c
|
||||
volatile usb_dwc_doepdmab0_reg_t doepdmab0_reg; // 0x0b1c
|
||||
|
||||
//Deivce: OUT EP registers
|
||||
usb_out_ep_regs_t out_eps[6]; //0xb1c
|
||||
usb_out_ep_regs_t reserved_0x0be0_0x0d00[9]; //0x0be0 to 0x0d00
|
||||
uint32_t reserved_0x0d00_0x0e00[64]; //0x0d00 to 0x0e00
|
||||
volatile usb_pcgcctl_reg_t pcgcctl_reg; //0x0e00
|
||||
uint32_t reserved_0x0e04_0x0e08[1]; //0x0d00 to 0x0e00
|
||||
} usbh_dev_t;
|
||||
usb_dwc_out_ep_regs_t out_eps[6]; // 0xb1c
|
||||
usb_dwc_out_ep_regs_t reserved_0x0be0_0x0d00[9]; // 0x0be0 to 0x0d00
|
||||
uint32_t reserved_0x0d00_0x0e00[64]; // 0x0d00 to 0x0e00
|
||||
volatile usb_dwc_pcgcctl_reg_t pcgcctl_reg; // 0x0e00
|
||||
uint32_t reserved_0x0e04_0x0e08[1]; // 0x0d00 to 0x0e00
|
||||
} usb_dwc_dev_t;
|
||||
|
||||
|
||||
#ifndef __cplusplus
|
||||
_Static_assert(sizeof(usbh_dev_t) == 0xe08, "USB new struct should be 0xe08 large");
|
||||
_Static_assert(sizeof(usb_dwc_dev_t) == 0xe08, "Invalid size of usb_dwc_dev_t structure");
|
||||
#endif
|
||||
|
||||
extern usbh_dev_t USBH;
|
||||
extern usb_dwc_dev_t USB_DWC;
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
|
@ -45,6 +45,6 @@ PROVIDE ( APB_SARADC = 0x60040000 );
|
|||
PROVIDE ( LCD_CAM = 0x60041000 );
|
||||
PROVIDE ( USB_SERIAL_JTAG = 0x60038000 );
|
||||
PROVIDE ( USB0 = 0x60080000 );
|
||||
PROVIDE ( USBH = 0x60080000 );
|
||||
PROVIDE ( USB_DWC = 0x60080000 );
|
||||
PROVIDE ( USB_WRAP = 0x60039000 );
|
||||
PROVIDE ( WORLD_CONTROLLER = 0x600D0000 );
|
||||
|
|
|
@ -0,0 +1,5 @@
|
|||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
components/usb/test_apps:
|
||||
enable:
|
||||
- if: SOC_USB_OTG_SUPPORTED == 1
|
|
@ -7,7 +7,7 @@ set(priv_include)
|
|||
set(priv_require driver) # usb_phy driver relies on gpio driver API
|
||||
|
||||
if(CONFIG_USB_OTG_SUPPORTED)
|
||||
list(APPEND srcs "hcd.c"
|
||||
list(APPEND srcs "hcd_dwc.c"
|
||||
"hub.c"
|
||||
"usb_helpers.c"
|
||||
"usb_host.c"
|
||||
|
|
|
@ -14,7 +14,7 @@
|
|||
#include "esp_intr_alloc.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_rom_gpio.h"
|
||||
#include "hal/usbh_hal.h"
|
||||
#include "hal/usb_dwc_hal.h"
|
||||
#include "hal/usb_types_private.h"
|
||||
#include "soc/gpio_pins.h"
|
||||
#include "soc/gpio_sig_map.h"
|
||||
|
@ -52,7 +52,7 @@ typedef struct {
|
|||
*
|
||||
* RXFIFO
|
||||
* - Recommended: ((LPS/4) * 2) + 2
|
||||
* - Actual: Whatever leftover size: USBH_HAL_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
|
||||
* - Actual: Whatever leftover size: USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES(200) - 48 - 48 = 104
|
||||
* - Worst case can accommodate two packets of 204 bytes, or one packet of 408
|
||||
* NPTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
|
@ -63,7 +63,7 @@ typedef struct {
|
|||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 3 = 48
|
||||
* - Worst case can accommodate three packets of 64 bytes or one packet of 192
|
||||
*/
|
||||
const usbh_hal_fifo_config_t fifo_config_default = {
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_default = {
|
||||
.rx_fifo_lines = 104,
|
||||
.nptx_fifo_lines = 48,
|
||||
.ptx_fifo_lines = 48,
|
||||
|
@ -80,7 +80,7 @@ const fifo_mps_limits_t mps_limits_default = {
|
|||
*
|
||||
* RXFIFO
|
||||
* - Recommended: ((LPS/4) * 2) + 2
|
||||
* - Actual: Whatever leftover size: USBH_HAL_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
|
||||
* - Actual: Whatever leftover size: USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES(200) - 32 - 16 = 152
|
||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||
* NPTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
|
@ -91,7 +91,7 @@ const fifo_mps_limits_t mps_limits_default = {
|
|||
* - Actual: Assume LPS is 64, and 3 packets: (64/4) * 2 = 32
|
||||
* - Worst case can accommodate two packets of 64 bytes or one packet of 128
|
||||
*/
|
||||
const usbh_hal_fifo_config_t fifo_config_bias_rx = {
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_rx = {
|
||||
.rx_fifo_lines = 152,
|
||||
.nptx_fifo_lines = 16,
|
||||
.ptx_fifo_lines = 32,
|
||||
|
@ -116,10 +116,10 @@ const fifo_mps_limits_t mps_limits_bias_rx = {
|
|||
* - Worst case can accommodate one packet of 64 bytes
|
||||
* PTXFIFO
|
||||
* - Recommended: (LPS/4) * 2
|
||||
* - Actual: Whatever leftover size: USBH_HAL_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
|
||||
* - Actual: Whatever leftover size: USB_DWC_HAL_FIFO_TOTAL_USABLE_LINES(200) - 34 - 16 = 150
|
||||
* - Worst case can accommodate two packets of 300 bytes or one packet of 600 bytes
|
||||
*/
|
||||
const usbh_hal_fifo_config_t fifo_config_bias_ptx = {
|
||||
const usb_dwc_hal_fifo_config_t fifo_config_bias_ptx = {
|
||||
.rx_fifo_lines = 34,
|
||||
.nptx_fifo_lines = 16,
|
||||
.ptx_fifo_lines = 150,
|
||||
|
@ -248,8 +248,8 @@ struct pipe_obj {
|
|||
uint32_t val;
|
||||
} multi_buffer_control;
|
||||
//HAL related
|
||||
usbh_hal_chan_t *chan_obj;
|
||||
usbh_hal_ep_char_t ep_char;
|
||||
usb_dwc_hal_chan_t *chan_obj;
|
||||
usb_dwc_hal_ep_char_t ep_char;
|
||||
//Port related
|
||||
port_t *port; //The port to which this pipe is routed through
|
||||
TAILQ_ENTRY(pipe_obj) tailq_entry; //TailQ entry for port's list of pipes
|
||||
|
@ -278,7 +278,7 @@ struct pipe_obj {
|
|||
* @brief Object representing a port in the HCD layer
|
||||
*/
|
||||
struct port_obj {
|
||||
usbh_hal_context_t *hal;
|
||||
usb_dwc_hal_context_t *hal;
|
||||
void *frame_list;
|
||||
//Pipes routed through this port
|
||||
TAILQ_HEAD(tailhead_pipes_idle, pipe_obj) pipes_idle_tailq;
|
||||
|
@ -304,7 +304,7 @@ struct port_obj {
|
|||
} flags;
|
||||
bool initialized;
|
||||
//FIFO biasing related
|
||||
const usbh_hal_fifo_config_t *fifo_config;
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
||||
const fifo_mps_limits_t *fifo_mps_limits;
|
||||
//Port callback and context
|
||||
hcd_port_callback_t callback;
|
||||
|
@ -389,7 +389,7 @@ static void _buffer_exec(pipe_t *pipe);
|
|||
/**
|
||||
* @brief Check if a buffer as completed execution
|
||||
*
|
||||
* This should only be called after receiving a USBH_HAL_CHAN_EVENT_CPLT event to check if a buffer is actually
|
||||
* This should only be called after receiving a USB_DWC_HAL_CHAN_EVENT_CPLT event to check if a buffer is actually
|
||||
* done.
|
||||
*
|
||||
* @param pipe Pipe object
|
||||
|
@ -489,7 +489,7 @@ static bool _buffer_flush_all(pipe_t *pipe, bool canceled);
|
|||
* @param chan_error The HAL channel error
|
||||
* @return hcd_pipe_event_t The corresponding pipe error event
|
||||
*/
|
||||
static inline hcd_pipe_event_t pipe_decode_error_event(usbh_hal_chan_error_t chan_error);
|
||||
static inline hcd_pipe_event_t pipe_decode_error_event(usb_dwc_hal_chan_error_t chan_error);
|
||||
|
||||
/**
|
||||
* @brief Halt a pipe
|
||||
|
@ -764,30 +764,30 @@ static bool _internal_pipe_event_notify(pipe_t *pipe, bool from_isr)
|
|||
* @param[out] yield Set to true if a yield is required as a result of handling the interrupt
|
||||
* @return hcd_port_event_t Returns a port event, or HCD_PORT_EVENT_NONE if no port event occurred
|
||||
*/
|
||||
static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usbh_hal_port_event_t hal_port_event, bool *yield)
|
||||
static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usb_dwc_hal_port_event_t hal_port_event, bool *yield)
|
||||
{
|
||||
hcd_port_event_t port_event = HCD_PORT_EVENT_NONE;
|
||||
switch (hal_port_event) {
|
||||
case USBH_HAL_PORT_EVENT_CONN: {
|
||||
case USB_DWC_HAL_PORT_EVENT_CONN: {
|
||||
//Don't update state immediately, we still need to debounce.
|
||||
port_event = HCD_PORT_EVENT_CONNECTION;
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_PORT_EVENT_DISCONN: {
|
||||
case USB_DWC_HAL_PORT_EVENT_DISCONN: {
|
||||
port->state = HCD_PORT_STATE_RECOVERY;
|
||||
port_event = HCD_PORT_EVENT_DISCONNECTION;
|
||||
port->flags.conn_dev_ena = 0;
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_PORT_EVENT_ENABLED: {
|
||||
usbh_hal_port_enable(port->hal); //Initialize remaining host port registers
|
||||
port->speed = (usbh_hal_port_get_conn_speed(port->hal) == USB_PRIV_SPEED_FULL) ? USB_SPEED_FULL : USB_SPEED_LOW;
|
||||
case USB_DWC_HAL_PORT_EVENT_ENABLED: {
|
||||
usb_dwc_hal_port_enable(port->hal); //Initialize remaining host port registers
|
||||
port->speed = (usb_dwc_hal_port_get_conn_speed(port->hal) == USB_PRIV_SPEED_FULL) ? USB_SPEED_FULL : USB_SPEED_LOW;
|
||||
port->state = HCD_PORT_STATE_ENABLED;
|
||||
port->flags.conn_dev_ena = 1;
|
||||
//This was triggered by a command, so no event needs to be propagated.
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_PORT_EVENT_DISABLED: {
|
||||
case USB_DWC_HAL_PORT_EVENT_DISABLED: {
|
||||
port->flags.conn_dev_ena = 0;
|
||||
//Disabled could be due to a disable request or reset request, or due to a port error
|
||||
if (port->state != HCD_PORT_STATE_RESETTING) { //Ignore the disable event if it's due to a reset request
|
||||
|
@ -804,11 +804,11 @@ static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usbh_hal_port_event_t hal_
|
|||
}
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_PORT_EVENT_OVRCUR:
|
||||
case USBH_HAL_PORT_EVENT_OVRCUR_CLR: { //Could occur if a quick overcurrent then clear happens
|
||||
case USB_DWC_HAL_PORT_EVENT_OVRCUR:
|
||||
case USB_DWC_HAL_PORT_EVENT_OVRCUR_CLR: { //Could occur if a quick overcurrent then clear happens
|
||||
if (port->state != HCD_PORT_STATE_NOT_POWERED) {
|
||||
//We need to power OFF the port to protect it
|
||||
usbh_hal_port_toggle_power(port->hal, false);
|
||||
usb_dwc_hal_port_toggle_power(port->hal, false);
|
||||
port->state = HCD_PORT_STATE_RECOVERY;
|
||||
port_event = HCD_PORT_EVENT_OVERCURRENT;
|
||||
}
|
||||
|
@ -834,13 +834,13 @@ static hcd_port_event_t _intr_hdlr_hprt(port_t *port, usbh_hal_port_event_t hal_
|
|||
* @param[out] yield Set to true if a yield is required as a result of handling the interrupt
|
||||
* @return hcd_pipe_event_t The pipe event
|
||||
*/
|
||||
static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usbh_hal_chan_t *chan_obj, bool *yield)
|
||||
static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usb_dwc_hal_chan_t *chan_obj, bool *yield)
|
||||
{
|
||||
usbh_hal_chan_event_t chan_event = usbh_hal_chan_decode_intr(chan_obj);
|
||||
usb_dwc_hal_chan_event_t chan_event = usb_dwc_hal_chan_decode_intr(chan_obj);
|
||||
hcd_pipe_event_t event = HCD_PIPE_EVENT_NONE;
|
||||
|
||||
switch (chan_event) {
|
||||
case USBH_HAL_CHAN_EVENT_CPLT: {
|
||||
case USB_DWC_HAL_CHAN_EVENT_CPLT: {
|
||||
if (!_buffer_check_done(pipe)) {
|
||||
_buffer_exec_cont(pipe);
|
||||
break;
|
||||
|
@ -848,7 +848,7 @@ static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usbh_hal_chan_t *chan_obj,
|
|||
pipe->last_event = HCD_PIPE_EVENT_URB_DONE;
|
||||
event = pipe->last_event;
|
||||
//Mark the buffer as done
|
||||
int stop_idx = usbh_hal_chan_get_qtd_idx(chan_obj);
|
||||
int stop_idx = usb_dwc_hal_chan_get_qtd_idx(chan_obj);
|
||||
_buffer_done(pipe, stop_idx, pipe->last_event, false);
|
||||
//First check if there is another buffer we can execute. But we only want to execute if there's still a valid device
|
||||
if (_buffer_can_exec(pipe) && pipe->port->flags.conn_dev_ena) {
|
||||
|
@ -864,27 +864,27 @@ static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usbh_hal_chan_t *chan_obj,
|
|||
}
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_CHAN_EVENT_ERROR: {
|
||||
case USB_DWC_HAL_CHAN_EVENT_ERROR: {
|
||||
//Get and store the pipe error event
|
||||
usbh_hal_chan_error_t chan_error = usbh_hal_chan_get_error(chan_obj);
|
||||
usb_dwc_hal_chan_error_t chan_error = usb_dwc_hal_chan_get_error(chan_obj);
|
||||
pipe->last_event = pipe_decode_error_event(chan_error);
|
||||
event = pipe->last_event;
|
||||
pipe->state = HCD_PIPE_STATE_HALTED;
|
||||
//Mark the buffer as done with an error
|
||||
int stop_idx = usbh_hal_chan_get_qtd_idx(chan_obj);
|
||||
int stop_idx = usb_dwc_hal_chan_get_qtd_idx(chan_obj);
|
||||
_buffer_done(pipe, stop_idx, pipe->last_event, false);
|
||||
//Parse the buffer
|
||||
_buffer_parse(pipe);
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_CHAN_EVENT_HALT_REQ: {
|
||||
case USB_DWC_HAL_CHAN_EVENT_HALT_REQ: {
|
||||
assert(pipe->cs_flags.waiting_halt);
|
||||
//We've halted a transfer, so we need to trigger the pipe callback
|
||||
pipe->last_event = HCD_PIPE_EVENT_URB_DONE;
|
||||
event = pipe->last_event;
|
||||
//Halt request event is triggered when packet is successful completed. But just treat all halted transfers as errors
|
||||
pipe->state = HCD_PIPE_STATE_HALTED;
|
||||
int stop_idx = usbh_hal_chan_get_qtd_idx(chan_obj);
|
||||
int stop_idx = usb_dwc_hal_chan_get_qtd_idx(chan_obj);
|
||||
_buffer_done(pipe, stop_idx, HCD_PIPE_EVENT_NONE, true);
|
||||
//Parse the buffer
|
||||
_buffer_parse(pipe);
|
||||
|
@ -892,7 +892,7 @@ static hcd_pipe_event_t _intr_hdlr_chan(pipe_t *pipe, usbh_hal_chan_t *chan_obj,
|
|||
*yield |= _internal_pipe_event_notify(pipe, true);
|
||||
break;
|
||||
}
|
||||
case USBH_HAL_CHAN_EVENT_NONE: {
|
||||
case USB_DWC_HAL_CHAN_EVENT_NONE: {
|
||||
break; //Nothing to do
|
||||
}
|
||||
default:
|
||||
|
@ -919,12 +919,12 @@ static void intr_hdlr_main(void *arg)
|
|||
bool yield = false;
|
||||
|
||||
HCD_ENTER_CRITICAL_ISR();
|
||||
usbh_hal_port_event_t hal_port_evt = usbh_hal_decode_intr(port->hal);
|
||||
if (hal_port_evt == USBH_HAL_PORT_EVENT_CHAN) {
|
||||
usb_dwc_hal_port_event_t hal_port_evt = usb_dwc_hal_decode_intr(port->hal);
|
||||
if (hal_port_evt == USB_DWC_HAL_PORT_EVENT_CHAN) {
|
||||
//Channel event. Cycle through each pending channel
|
||||
usbh_hal_chan_t *chan_obj = usbh_hal_get_chan_pending_intr(port->hal);
|
||||
usb_dwc_hal_chan_t *chan_obj = usb_dwc_hal_get_chan_pending_intr(port->hal);
|
||||
while (chan_obj != NULL) {
|
||||
pipe_t *pipe = (pipe_t *)usbh_hal_chan_get_context(chan_obj);
|
||||
pipe_t *pipe = (pipe_t *)usb_dwc_hal_chan_get_context(chan_obj);
|
||||
hcd_pipe_event_t event = _intr_hdlr_chan(pipe, chan_obj, &yield);
|
||||
//Run callback if a pipe event has occurred and the pipe also has a callback
|
||||
if (event != HCD_PIPE_EVENT_NONE && pipe->callback != NULL) {
|
||||
|
@ -933,9 +933,9 @@ static void intr_hdlr_main(void *arg)
|
|||
HCD_ENTER_CRITICAL_ISR();
|
||||
}
|
||||
//Check for more channels with pending interrupts. Returns NULL if there are no more
|
||||
chan_obj = usbh_hal_get_chan_pending_intr(port->hal);
|
||||
chan_obj = usb_dwc_hal_get_chan_pending_intr(port->hal);
|
||||
}
|
||||
} else if (hal_port_evt != USBH_HAL_PORT_EVENT_NONE) { //Port event
|
||||
} else if (hal_port_evt != USB_DWC_HAL_PORT_EVENT_NONE) { //Port event
|
||||
hcd_port_event_t port_event = _intr_hdlr_hprt(port, hal_port_evt, &yield);
|
||||
if (port_event != HCD_PORT_EVENT_NONE) {
|
||||
port->last_event = port_event;
|
||||
|
@ -959,8 +959,8 @@ static void intr_hdlr_main(void *arg)
|
|||
static port_t *port_obj_alloc(void)
|
||||
{
|
||||
port_t *port = calloc(1, sizeof(port_t));
|
||||
usbh_hal_context_t *hal = malloc(sizeof(usbh_hal_context_t));
|
||||
void *frame_list = heap_caps_aligned_calloc(USBH_HAL_FRAME_LIST_MEM_ALIGN, FRAME_LIST_LEN,sizeof(uint32_t), MALLOC_CAP_DMA);
|
||||
usb_dwc_hal_context_t *hal = malloc(sizeof(usb_dwc_hal_context_t));
|
||||
void *frame_list = heap_caps_aligned_calloc(USB_DWC_HAL_FRAME_LIST_MEM_ALIGN, FRAME_LIST_LEN,sizeof(uint32_t), MALLOC_CAP_DMA);
|
||||
SemaphoreHandle_t port_mux = xSemaphoreCreateMutex();
|
||||
if (port == NULL || hal == NULL || frame_list == NULL || port_mux == NULL) {
|
||||
free(port);
|
||||
|
@ -1081,7 +1081,7 @@ static bool _port_persist_all_pipes(port_t *port)
|
|||
}
|
||||
TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) {
|
||||
pipe->cs_flags.reset_lock = 1;
|
||||
usbh_hal_chan_free(port->hal, pipe->chan_obj);
|
||||
usb_dwc_hal_chan_free(port->hal, pipe->chan_obj);
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
@ -1092,8 +1092,8 @@ static void _port_recover_all_pipes(port_t *port)
|
|||
TAILQ_FOREACH(pipe, &port->pipes_idle_tailq, tailq_entry) {
|
||||
pipe->cs_flags.persist = 0;
|
||||
pipe->cs_flags.reset_lock = 0;
|
||||
usbh_hal_chan_alloc(port->hal, pipe->chan_obj, (void *)pipe);
|
||||
usbh_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
usb_dwc_hal_chan_alloc(port->hal, pipe->chan_obj, (void *)pipe);
|
||||
usb_dwc_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -1126,14 +1126,14 @@ static bool _port_debounce(port_t *port)
|
|||
vTaskDelay(pdMS_TO_TICKS(DEBOUNCE_DELAY_MS));
|
||||
HCD_ENTER_CRITICAL();
|
||||
//Check the post-debounce state of the bus (i.e., whether it's actually connected/disconnected)
|
||||
bool is_connected = usbh_hal_port_check_if_connected(port->hal);
|
||||
bool is_connected = usb_dwc_hal_port_check_if_connected(port->hal);
|
||||
if (is_connected) {
|
||||
port->state = HCD_PORT_STATE_DISABLED;
|
||||
} else {
|
||||
port->state = HCD_PORT_STATE_DISCONNECTED;
|
||||
}
|
||||
//Disable debounce lock
|
||||
usbh_hal_disable_debounce_lock(port->hal);
|
||||
usb_dwc_hal_disable_debounce_lock(port->hal);
|
||||
return is_connected;
|
||||
}
|
||||
|
||||
|
@ -1145,8 +1145,8 @@ static esp_err_t _port_cmd_power_on(port_t *port)
|
|||
//Port can only be powered on if it's currently unpowered
|
||||
if (port->state == HCD_PORT_STATE_NOT_POWERED) {
|
||||
port->state = HCD_PORT_STATE_DISCONNECTED;
|
||||
usbh_hal_port_init(port->hal);
|
||||
usbh_hal_port_toggle_power(port->hal, true);
|
||||
usb_dwc_hal_port_init(port->hal);
|
||||
usb_dwc_hal_port_toggle_power(port->hal, true);
|
||||
ret = ESP_OK;
|
||||
} else {
|
||||
ret = ESP_ERR_INVALID_STATE;
|
||||
|
@ -1160,8 +1160,8 @@ static esp_err_t _port_cmd_power_off(port_t *port)
|
|||
//Port can only be unpowered if already powered
|
||||
if (port->state != HCD_PORT_STATE_NOT_POWERED) {
|
||||
port->state = HCD_PORT_STATE_NOT_POWERED;
|
||||
usbh_hal_port_deinit(port->hal);
|
||||
usbh_hal_port_toggle_power(port->hal, false);
|
||||
usb_dwc_hal_port_deinit(port->hal);
|
||||
usb_dwc_hal_port_toggle_power(port->hal, false);
|
||||
//If a device is currently connected, this should trigger a disconnect event
|
||||
ret = ESP_OK;
|
||||
} else {
|
||||
|
@ -1187,7 +1187,7 @@ static esp_err_t _port_cmd_reset(port_t *port)
|
|||
//All pipes (if any_) are guaranteed to be persistent at this point. Proceed to resetting the bus
|
||||
port->state = HCD_PORT_STATE_RESETTING;
|
||||
//Put and hold the bus in the reset state. If the port was previously enabled, a disabled event will occur after this
|
||||
usbh_hal_port_toggle_reset(port->hal, true);
|
||||
usb_dwc_hal_port_toggle_reset(port->hal, true);
|
||||
HCD_EXIT_CRITICAL();
|
||||
vTaskDelay(pdMS_TO_TICKS(RESET_HOLD_MS));
|
||||
HCD_ENTER_CRITICAL();
|
||||
|
@ -1197,7 +1197,7 @@ static esp_err_t _port_cmd_reset(port_t *port)
|
|||
goto bailout;
|
||||
}
|
||||
//Return the bus to the idle state and hold it for the required reset recovery time. Port enabled event should occur
|
||||
usbh_hal_port_toggle_reset(port->hal, false);
|
||||
usb_dwc_hal_port_toggle_reset(port->hal, false);
|
||||
HCD_EXIT_CRITICAL();
|
||||
vTaskDelay(pdMS_TO_TICKS(RESET_RECOVERY_MS));
|
||||
HCD_ENTER_CRITICAL();
|
||||
|
@ -1207,10 +1207,10 @@ static esp_err_t _port_cmd_reset(port_t *port)
|
|||
goto bailout;
|
||||
}
|
||||
//Set FIFO sizes based on the selected biasing
|
||||
usbh_hal_set_fifo_size(port->hal, port->fifo_config);
|
||||
usb_dwc_hal_set_fifo_size(port->hal, port->fifo_config);
|
||||
//We start periodic scheduling only after a RESET command since SOFs only start after a reset
|
||||
usbh_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN);
|
||||
usbh_hal_port_periodic_enable(port->hal);
|
||||
usb_dwc_hal_port_set_frame_list(port->hal, port->frame_list, FRAME_LIST_LEN);
|
||||
usb_dwc_hal_port_periodic_enable(port->hal);
|
||||
ret = ESP_OK;
|
||||
bailout:
|
||||
if (is_runtime_reset) {
|
||||
|
@ -1229,7 +1229,7 @@ static esp_err_t _port_cmd_bus_suspend(port_t *port)
|
|||
goto exit;
|
||||
}
|
||||
//All pipes are guaranteed halted at this point. Proceed to suspend the port
|
||||
usbh_hal_port_suspend(port->hal);
|
||||
usb_dwc_hal_port_suspend(port->hal);
|
||||
port->state = HCD_PORT_STATE_SUSPENDED;
|
||||
ret = ESP_OK;
|
||||
exit:
|
||||
|
@ -1245,13 +1245,13 @@ static esp_err_t _port_cmd_bus_resume(port_t *port)
|
|||
goto exit;
|
||||
}
|
||||
//Put and hold the bus in the K state.
|
||||
usbh_hal_port_toggle_resume(port->hal, true);
|
||||
usb_dwc_hal_port_toggle_resume(port->hal, true);
|
||||
port->state = HCD_PORT_STATE_RESUMING;
|
||||
HCD_EXIT_CRITICAL();
|
||||
vTaskDelay(pdMS_TO_TICKS(RESUME_HOLD_MS));
|
||||
HCD_ENTER_CRITICAL();
|
||||
//Return and hold the bus to the J state (as port of the LS EOP)
|
||||
usbh_hal_port_toggle_resume(port->hal, false);
|
||||
usb_dwc_hal_port_toggle_resume(port->hal, false);
|
||||
if (port->state != HCD_PORT_STATE_RESUMING || !port->flags.conn_dev_ena) {
|
||||
//Port state unexpectedly changed
|
||||
ret = ESP_ERR_INVALID_RESPONSE;
|
||||
|
@ -1285,7 +1285,7 @@ static esp_err_t _port_cmd_disable(port_t *port)
|
|||
}
|
||||
//All pipes are guaranteed to be halted or freed at this point. Proceed to disable the port
|
||||
port->flags.disable_requested = 1;
|
||||
usbh_hal_port_disable(port->hal);
|
||||
usb_dwc_hal_port_disable(port->hal);
|
||||
_internal_port_event_wait(port);
|
||||
if (port->state != HCD_PORT_STATE_DISABLED) {
|
||||
//Port state unexpectedly changed
|
||||
|
@ -1305,7 +1305,7 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
|
|||
HCD_CHECK(port_number <= NUM_PORTS, ESP_ERR_NOT_FOUND);
|
||||
|
||||
//Get a pointer to the correct FIFO bias constant values
|
||||
const usbh_hal_fifo_config_t *fifo_config;
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
||||
const fifo_mps_limits_t *mps_limits;
|
||||
switch (port_config->fifo_bias) {
|
||||
case HCD_PORT_FIFO_BIAS_BALANCED:
|
||||
|
@ -1340,7 +1340,7 @@ esp_err_t hcd_port_init(int port_number, const hcd_port_config_t *port_config, h
|
|||
port_obj->callback = port_config->callback;
|
||||
port_obj->callback_arg = port_config->callback_arg;
|
||||
port_obj->context = port_config->context;
|
||||
usbh_hal_init(port_obj->hal);
|
||||
usb_dwc_hal_init(port_obj->hal);
|
||||
port_obj->initialized = true;
|
||||
//Clear the frame list. We set the frame list register and enable periodic scheduling after a successful reset
|
||||
memset(port_obj->frame_list, 0, FRAME_LIST_LEN * sizeof(uint32_t));
|
||||
|
@ -1364,7 +1364,7 @@ esp_err_t hcd_port_deinit(hcd_port_handle_t port_hdl)
|
|||
ESP_ERR_INVALID_STATE);
|
||||
port->initialized = false;
|
||||
esp_intr_disable(s_hcd_obj->isr_hdl);
|
||||
usbh_hal_deinit(port->hal);
|
||||
usb_dwc_hal_deinit(port->hal);
|
||||
HCD_EXIT_CRITICAL();
|
||||
|
||||
return ESP_OK;
|
||||
|
@ -1428,7 +1428,7 @@ esp_err_t hcd_port_get_speed(hcd_port_handle_t port_hdl, usb_speed_t *speed)
|
|||
HCD_ENTER_CRITICAL();
|
||||
//Device speed is only valid if there is device connected to the port that has been reset
|
||||
HCD_CHECK_FROM_CRIT(port->flags.conn_dev_ena, ESP_ERR_INVALID_STATE);
|
||||
usb_priv_speed_t hal_speed = usbh_hal_port_get_conn_speed(port->hal);
|
||||
usb_priv_speed_t hal_speed = usb_dwc_hal_port_get_conn_speed(port->hal);
|
||||
if (hal_speed == USB_PRIV_SPEED_FULL) {
|
||||
*speed = USB_SPEED_FULL;
|
||||
} else {
|
||||
|
@ -1483,12 +1483,12 @@ esp_err_t hcd_port_recover(hcd_port_handle_t port_hdl)
|
|||
ESP_ERR_INVALID_STATE);
|
||||
//We are about to do a soft reset on the peripheral. Disable the peripheral throughout
|
||||
esp_intr_disable(s_hcd_obj->isr_hdl);
|
||||
usbh_hal_core_soft_reset(port->hal);
|
||||
usb_dwc_hal_core_soft_reset(port->hal);
|
||||
port->state = HCD_PORT_STATE_NOT_POWERED;
|
||||
port->last_event = HCD_PORT_EVENT_NONE;
|
||||
port->flags.val = 0;
|
||||
//Soft reset wipes all registers so we need to reinitialize the HAL
|
||||
usbh_hal_init(port->hal);
|
||||
usb_dwc_hal_init(port->hal);
|
||||
//Clear the frame list. We set the frame list register and enable periodic scheduling after a successful reset
|
||||
memset(port->frame_list, 0, FRAME_LIST_LEN * sizeof(uint32_t));
|
||||
esp_intr_enable(s_hcd_obj->isr_hdl);
|
||||
|
@ -1510,7 +1510,7 @@ esp_err_t hcd_port_set_fifo_bias(hcd_port_handle_t port_hdl, hcd_port_fifo_bias_
|
|||
{
|
||||
esp_err_t ret;
|
||||
//Get a pointer to the correct FIFO bias constant values
|
||||
const usbh_hal_fifo_config_t *fifo_config;
|
||||
const usb_dwc_hal_fifo_config_t *fifo_config;
|
||||
const fifo_mps_limits_t *mps_limits;
|
||||
switch (bias) {
|
||||
case HCD_PORT_FIFO_BIAS_BALANCED:
|
||||
|
@ -1537,7 +1537,7 @@ esp_err_t hcd_port_set_fifo_bias(hcd_port_handle_t port_hdl, hcd_port_fifo_bias_
|
|||
HCD_ENTER_CRITICAL();
|
||||
//Check that port is in the correct state to update FIFO sizes
|
||||
if (port->initialized && !port->flags.event_pending && port->num_pipes_idle == 0 && port->num_pipes_queued == 0) {
|
||||
usbh_hal_set_fifo_size(port->hal, fifo_config);
|
||||
usb_dwc_hal_set_fifo_size(port->hal, fifo_config);
|
||||
port->fifo_config = fifo_config;
|
||||
port->fifo_mps_limits = mps_limits;
|
||||
ret = ESP_OK;
|
||||
|
@ -1553,20 +1553,20 @@ esp_err_t hcd_port_set_fifo_bias(hcd_port_handle_t port_hdl, hcd_port_fifo_bias_
|
|||
|
||||
// ----------------------- Private -------------------------
|
||||
|
||||
static inline hcd_pipe_event_t pipe_decode_error_event(usbh_hal_chan_error_t chan_error)
|
||||
static inline hcd_pipe_event_t pipe_decode_error_event(usb_dwc_hal_chan_error_t chan_error)
|
||||
{
|
||||
hcd_pipe_event_t event = HCD_PIPE_EVENT_NONE;
|
||||
switch (chan_error) {
|
||||
case USBH_HAL_CHAN_ERROR_XCS_XACT:
|
||||
case USB_DWC_HAL_CHAN_ERROR_XCS_XACT:
|
||||
event = HCD_PIPE_EVENT_ERROR_XFER;
|
||||
break;
|
||||
case USBH_HAL_CHAN_ERROR_BNA:
|
||||
case USB_DWC_HAL_CHAN_ERROR_BNA:
|
||||
event = HCD_PIPE_EVENT_ERROR_URB_NOT_AVAIL;
|
||||
break;
|
||||
case USBH_HAL_CHAN_ERROR_PKT_BBL:
|
||||
case USB_DWC_HAL_CHAN_ERROR_PKT_BBL:
|
||||
event = HCD_PIPE_EVENT_ERROR_OVERFLOW;
|
||||
break;
|
||||
case USBH_HAL_CHAN_ERROR_STALL:
|
||||
case USB_DWC_HAL_CHAN_ERROR_STALL:
|
||||
event = HCD_PIPE_EVENT_ERROR_STALL;
|
||||
break;
|
||||
}
|
||||
|
@ -1591,7 +1591,7 @@ static dma_buffer_block_t *buffer_block_alloc(usb_transfer_type_t type)
|
|||
break;
|
||||
}
|
||||
dma_buffer_block_t *buffer = calloc(1, sizeof(dma_buffer_block_t));
|
||||
void *xfer_desc_list = heap_caps_aligned_calloc(USBH_HAL_DMA_MEM_ALIGN, desc_list_len, sizeof(usbh_ll_dma_qtd_t), MALLOC_CAP_DMA);
|
||||
void *xfer_desc_list = heap_caps_aligned_calloc(USB_DWC_HAL_DMA_MEM_ALIGN, desc_list_len, sizeof(usb_dwc_ll_dma_qtd_t), MALLOC_CAP_DMA);
|
||||
if (buffer == NULL || xfer_desc_list == NULL) {
|
||||
free(buffer);
|
||||
heap_caps_free(xfer_desc_list);
|
||||
|
@ -1649,7 +1649,7 @@ static bool pipe_alloc_check_args(const hcd_pipe_config_t *pipe_config, usb_spee
|
|||
return (pipe_config->ep_desc->wMaxPacketSize <= limit);
|
||||
}
|
||||
|
||||
static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_type_t type, bool is_default_pipe, int pipe_idx, usb_speed_t port_speed, usbh_hal_ep_char_t *ep_char)
|
||||
static void pipe_set_ep_char(const hcd_pipe_config_t *pipe_config, usb_transfer_type_t type, bool is_default_pipe, int pipe_idx, usb_speed_t port_speed, usb_dwc_hal_ep_char_t *ep_char)
|
||||
{
|
||||
//Initialize EP characteristics
|
||||
usb_priv_xfer_type_t hal_xfer_type;
|
||||
|
@ -1722,7 +1722,7 @@ static esp_err_t _pipe_cmd_halt(pipe_t *pipe)
|
|||
}
|
||||
//If the pipe's port is invalid, we just mark the pipe as halted without needing to halt the underlying channel
|
||||
if (pipe->port->flags.conn_dev_ena //Skip halting the underlying channel if the port is invalid
|
||||
&& !usbh_hal_chan_request_halt(pipe->chan_obj)) { //Check if the channel is already halted
|
||||
&& !usb_dwc_hal_chan_request_halt(pipe->chan_obj)) { //Check if the channel is already halted
|
||||
//Channel is not halted, we need to request and wait for a haltWe need to wait for channel to be halted.
|
||||
pipe->cs_flags.waiting_halt = 1;
|
||||
_internal_pipe_event_wait(pipe);
|
||||
|
@ -1730,7 +1730,7 @@ static esp_err_t _pipe_cmd_halt(pipe_t *pipe)
|
|||
assert(pipe->state == HCD_PIPE_STATE_HALTED);
|
||||
} else {
|
||||
//We are already halted, just need to update the state
|
||||
usbh_hal_chan_mark_halted(pipe->chan_obj);
|
||||
usb_dwc_hal_chan_mark_halted(pipe->chan_obj);
|
||||
pipe->state = HCD_PIPE_STATE_HALTED;
|
||||
}
|
||||
ret = ESP_OK;
|
||||
|
@ -1842,7 +1842,7 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||
esp_err_t ret;
|
||||
//Allocate the pipe resources
|
||||
pipe_t *pipe = calloc(1, sizeof(pipe_t));
|
||||
usbh_hal_chan_t *chan_obj = calloc(1, sizeof(usbh_hal_chan_t));
|
||||
usb_dwc_hal_chan_t *chan_obj = calloc(1, sizeof(usb_dwc_hal_chan_t));
|
||||
dma_buffer_block_t *buffers[NUM_BUFFERS] = {0};
|
||||
if (pipe == NULL|| chan_obj == NULL) {
|
||||
ret = ESP_ERR_NO_MEM;
|
||||
|
@ -1865,9 +1865,9 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||
pipe->multi_buffer_control.buffer_num_to_fill = NUM_BUFFERS;
|
||||
pipe->port = port;
|
||||
pipe->chan_obj = chan_obj;
|
||||
usbh_hal_ep_char_t ep_char;
|
||||
usb_dwc_hal_ep_char_t ep_char;
|
||||
pipe_set_ep_char(pipe_config, type, is_default, pipe_idx, port_speed, &ep_char);
|
||||
memcpy(&pipe->ep_char, &ep_char, sizeof(usbh_hal_ep_char_t));
|
||||
memcpy(&pipe->ep_char, &ep_char, sizeof(usb_dwc_hal_ep_char_t));
|
||||
pipe->state = HCD_PIPE_STATE_ACTIVE;
|
||||
pipe->callback = pipe_config->callback;
|
||||
pipe->callback_arg = pipe_config->callback_arg;
|
||||
|
@ -1880,13 +1880,13 @@ esp_err_t hcd_pipe_alloc(hcd_port_handle_t port_hdl, const hcd_pipe_config_t *pi
|
|||
ret = ESP_ERR_INVALID_STATE;
|
||||
goto err;
|
||||
}
|
||||
bool chan_allocated = usbh_hal_chan_alloc(port->hal, pipe->chan_obj, (void *) pipe);
|
||||
bool chan_allocated = usb_dwc_hal_chan_alloc(port->hal, pipe->chan_obj, (void *) pipe);
|
||||
if (!chan_allocated) {
|
||||
HCD_EXIT_CRITICAL();
|
||||
ret = ESP_ERR_NOT_SUPPORTED;
|
||||
goto err;
|
||||
}
|
||||
usbh_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
usb_dwc_hal_chan_set_ep_char(port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
//Add the pipe to the list of idle pipes in the port object
|
||||
TAILQ_INSERT_TAIL(&port->pipes_idle_tailq, pipe, tailq_entry);
|
||||
port->num_pipes_idle++;
|
||||
|
@ -1916,7 +1916,7 @@ esp_err_t hcd_pipe_free(hcd_pipe_handle_t pipe_hdl)
|
|||
//Remove pipe from the list of idle pipes (it must be in the idle list because it should have no queued URBs)
|
||||
TAILQ_REMOVE(&pipe->port->pipes_idle_tailq, pipe, tailq_entry);
|
||||
pipe->port->num_pipes_idle--;
|
||||
usbh_hal_chan_free(pipe->port->hal, pipe->chan_obj);
|
||||
usb_dwc_hal_chan_free(pipe->port->hal, pipe->chan_obj);
|
||||
HCD_EXIT_CRITICAL();
|
||||
|
||||
//Free pipe resources
|
||||
|
@ -1939,7 +1939,7 @@ esp_err_t hcd_pipe_update_mps(hcd_pipe_handle_t pipe_hdl, int mps)
|
|||
ESP_ERR_INVALID_STATE);
|
||||
pipe->ep_char.mps = mps;
|
||||
//Update the underlying channel's registers
|
||||
usbh_hal_chan_set_ep_char(pipe->port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
usb_dwc_hal_chan_set_ep_char(pipe->port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
HCD_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -1955,7 +1955,7 @@ esp_err_t hcd_pipe_update_dev_addr(hcd_pipe_handle_t pipe_hdl, uint8_t dev_addr)
|
|||
ESP_ERR_INVALID_STATE);
|
||||
pipe->ep_char.dev_addr = dev_addr;
|
||||
//Update the underlying channel's registers
|
||||
usbh_hal_chan_set_ep_char(pipe->port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
usb_dwc_hal_chan_set_ep_char(pipe->port->hal, pipe->chan_obj, &pipe->ep_char);
|
||||
HCD_EXIT_CRITICAL();
|
||||
return ESP_OK;
|
||||
}
|
||||
|
@ -2060,20 +2060,20 @@ static inline void _buffer_fill_ctrl(dma_buffer_block_t *buffer, usb_transfer_t
|
|||
bool data_stg_in = (setup_pkt->bmRequestType & USB_BM_REQUEST_TYPE_DIR_IN);
|
||||
bool data_stg_skip = (setup_pkt->wLength == 0);
|
||||
//Fill setup stage
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, sizeof(usb_setup_packet_t),
|
||||
USBH_HAL_XFER_DESC_FLAG_SETUP | USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, sizeof(usb_setup_packet_t),
|
||||
USB_DWC_HAL_XFER_DESC_FLAG_SETUP | USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
//Fill data stage
|
||||
if (data_stg_skip) {
|
||||
//Not data stage. Fill with an empty descriptor
|
||||
usbh_hal_xfer_desc_clear(buffer->xfer_desc_list, 1);
|
||||
usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, 1);
|
||||
} else {
|
||||
//Fill data stage. Note that we still fill with transfer->num_bytes instead of setup_pkt->wLength as it's possible to require more bytes than wLength
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 1, transfer->data_buffer + sizeof(usb_setup_packet_t), transfer->num_bytes - sizeof(usb_setup_packet_t),
|
||||
((data_stg_in) ? USBH_HAL_XFER_DESC_FLAG_IN : 0) | USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 1, transfer->data_buffer + sizeof(usb_setup_packet_t), transfer->num_bytes - sizeof(usb_setup_packet_t),
|
||||
((data_stg_in) ? USB_DWC_HAL_XFER_DESC_FLAG_IN : 0) | USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
}
|
||||
//Fill status stage (i.e., a zero length packet). If data stage is skipped, the status stage is always IN.
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 2, NULL, 0,
|
||||
((data_stg_in && !data_stg_skip) ? 0 : USBH_HAL_XFER_DESC_FLAG_IN) | USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 2, NULL, 0,
|
||||
((data_stg_in && !data_stg_skip) ? 0 : USB_DWC_HAL_XFER_DESC_FLAG_IN) | USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
//Update buffer flags
|
||||
buffer->flags.ctrl.data_stg_in = data_stg_in;
|
||||
buffer->flags.ctrl.data_stg_skip = data_stg_skip;
|
||||
|
@ -2086,16 +2086,16 @@ static inline void _buffer_fill_bulk(dma_buffer_block_t *buffer, usb_transfer_t
|
|||
//Minor optimization: Do the mod operation last
|
||||
bool zero_len_packet = !is_in && (transfer->flags & USB_TRANSFER_FLAG_ZERO_PACK) && (transfer->num_bytes % mps == 0);
|
||||
if (is_in) {
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes,
|
||||
USBH_HAL_XFER_DESC_FLAG_IN | USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes,
|
||||
USB_DWC_HAL_XFER_DESC_FLAG_IN | USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
} else { //OUT
|
||||
if (zero_len_packet) {
|
||||
//Adding a zero length packet, so two descriptors are used.
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes, 0);
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 1, NULL, 0, USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes, 0);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 1, NULL, 0, USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
} else {
|
||||
//Zero length packet not required. One descriptor is enough
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes, USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, 0, transfer->data_buffer, transfer->num_bytes, USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
}
|
||||
}
|
||||
//Update buffer flags
|
||||
|
@ -2119,24 +2119,24 @@ static inline void _buffer_fill_intr(dma_buffer_block_t *buffer, usb_transfer_t
|
|||
}
|
||||
assert((zero_len_packet) ? num_qtds + 1 : num_qtds <= XFER_LIST_LEN_INTR); //Check that the number of QTDs doesn't exceed the QTD list's length
|
||||
|
||||
uint32_t xfer_desc_flags = (is_in) ? USBH_HAL_XFER_DESC_FLAG_IN : 0;
|
||||
uint32_t xfer_desc_flags = (is_in) ? USB_DWC_HAL_XFER_DESC_FLAG_IN : 0;
|
||||
int bytes_filled = 0;
|
||||
//Fill all but last QTD
|
||||
for (int i = 0; i < num_qtds - 1; i++) {
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, i, &transfer->data_buffer[bytes_filled], mps, xfer_desc_flags);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, i, &transfer->data_buffer[bytes_filled], mps, xfer_desc_flags);
|
||||
bytes_filled += mps;
|
||||
}
|
||||
//Fill last QTD and zero length packet
|
||||
if (zero_len_packet) {
|
||||
//Fill in last data packet without HOC flag
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds - 1, &transfer->data_buffer[bytes_filled], transfer->num_bytes - bytes_filled,
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds - 1, &transfer->data_buffer[bytes_filled], transfer->num_bytes - bytes_filled,
|
||||
xfer_desc_flags);
|
||||
//HOC flag goes to zero length packet instead
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds, NULL, 0, USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds, NULL, 0, USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
} else {
|
||||
//Zero length packet not required. Fill in last QTD with HOC flag
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds - 1, &transfer->data_buffer[bytes_filled], transfer->num_bytes - bytes_filled,
|
||||
xfer_desc_flags | USBH_HAL_XFER_DESC_FLAG_HOC);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, num_qtds - 1, &transfer->data_buffer[bytes_filled], transfer->num_bytes - bytes_filled,
|
||||
xfer_desc_flags | USB_DWC_HAL_XFER_DESC_FLAG_HOC);
|
||||
}
|
||||
|
||||
//Update buffer members and flags
|
||||
|
@ -2154,19 +2154,19 @@ static inline void _buffer_fill_isoc(dma_buffer_block_t *buffer, usb_transfer_t
|
|||
//For each packet, fill in a descriptor and a interval-1 blank descriptor after it
|
||||
for (int pkt_idx = 0; pkt_idx < transfer->num_isoc_packets; pkt_idx++) {
|
||||
int xfer_len = transfer->isoc_packet_desc[pkt_idx].num_bytes;
|
||||
uint32_t flags = (is_in) ? USBH_HAL_XFER_DESC_FLAG_IN : 0;
|
||||
uint32_t flags = (is_in) ? USB_DWC_HAL_XFER_DESC_FLAG_IN : 0;
|
||||
if (pkt_idx == transfer->num_isoc_packets - 1) {
|
||||
//Last packet, set the the HOC flag
|
||||
flags |= USBH_HAL_XFER_DESC_FLAG_HOC;
|
||||
flags |= USB_DWC_HAL_XFER_DESC_FLAG_HOC;
|
||||
}
|
||||
usbh_hal_xfer_desc_fill(buffer->xfer_desc_list, desc_idx, &transfer->data_buffer[bytes_filled], xfer_len, flags);
|
||||
usb_dwc_hal_xfer_desc_fill(buffer->xfer_desc_list, desc_idx, &transfer->data_buffer[bytes_filled], xfer_len, flags);
|
||||
bytes_filled += xfer_len;
|
||||
if (++desc_idx >= XFER_LIST_LEN_ISOC) {
|
||||
desc_idx = 0;
|
||||
}
|
||||
//Clear descriptors for unscheduled frames
|
||||
for (int i = 0; i < interval - 1; i++) {
|
||||
usbh_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx);
|
||||
usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx);
|
||||
if (++desc_idx >= XFER_LIST_LEN_ISOC) {
|
||||
desc_idx = 0;
|
||||
}
|
||||
|
@ -2204,7 +2204,7 @@ static void _buffer_fill(pipe_t *pipe)
|
|||
uint32_t start_idx;
|
||||
if (pipe->multi_buffer_control.buffer_num_to_exec == 0) {
|
||||
//There are no more previously filled buffers to execute. We need to calculate a new start index based on HFNUM and the pipe's schedule
|
||||
uint32_t cur_frame_num = usbh_hal_port_get_cur_frame_num(pipe->port->hal);
|
||||
uint32_t cur_frame_num = usb_dwc_hal_port_get_cur_frame_num(pipe->port->hal);
|
||||
uint32_t cur_mod_idx_no_offset = (cur_frame_num - pipe->ep_char.periodic.phase_offset_frames) & (XFER_LIST_LEN_ISOC - 1); //Get the modulated index (i.e., the Nth desc in the descriptor list)
|
||||
//This is the non-offset modulated QTD index of the last scheduled interval
|
||||
uint32_t last_interval_mod_idx_no_offset = (cur_mod_idx_no_offset / pipe->ep_char.periodic.interval) * pipe->ep_char.periodic.interval; //Floor divide and the multiply again
|
||||
|
@ -2260,8 +2260,8 @@ static void _buffer_exec(pipe_t *pipe)
|
|||
start_idx = 0;
|
||||
desc_list_len = XFER_LIST_LEN_CTRL;
|
||||
//Set the channel's direction to OUT and PID to 0 respectively for the the setup stage
|
||||
usbh_hal_chan_set_dir(pipe->chan_obj, false); //Setup stage is always OUT
|
||||
usbh_hal_chan_set_pid(pipe->chan_obj, 0); //Setup stage always has a PID of DATA0
|
||||
usb_dwc_hal_chan_set_dir(pipe->chan_obj, false); //Setup stage is always OUT
|
||||
usb_dwc_hal_chan_set_pid(pipe->chan_obj, 0); //Setup stage always has a PID of DATA0
|
||||
break;
|
||||
}
|
||||
case USB_PRIV_XFER_TYPE_ISOCHRONOUS: {
|
||||
|
@ -2289,7 +2289,7 @@ static void _buffer_exec(pipe_t *pipe)
|
|||
//Update buffer and multi buffer flags
|
||||
buffer_to_exec->status_flags.executing = 1;
|
||||
pipe->multi_buffer_control.buffer_is_executing = 1;
|
||||
usbh_hal_chan_activate(pipe->chan_obj, buffer_to_exec->xfer_desc_list, desc_list_len, start_idx);
|
||||
usb_dwc_hal_chan_activate(pipe->chan_obj, buffer_to_exec->xfer_desc_list, desc_list_len, start_idx);
|
||||
}
|
||||
|
||||
static void _buffer_exec_cont(pipe_t *pipe)
|
||||
|
@ -2318,9 +2318,9 @@ static void _buffer_exec_cont(pipe_t *pipe)
|
|||
buffer_inflight->flags.ctrl.cur_stg = 2;
|
||||
}
|
||||
//Continue the control transfer
|
||||
usbh_hal_chan_set_dir(pipe->chan_obj, next_dir_is_in);
|
||||
usbh_hal_chan_set_pid(pipe->chan_obj, next_pid);
|
||||
usbh_hal_chan_activate(pipe->chan_obj, buffer_inflight->xfer_desc_list, XFER_LIST_LEN_CTRL, buffer_inflight->flags.ctrl.cur_stg);
|
||||
usb_dwc_hal_chan_set_dir(pipe->chan_obj, next_dir_is_in);
|
||||
usb_dwc_hal_chan_set_pid(pipe->chan_obj, next_pid);
|
||||
usb_dwc_hal_chan_activate(pipe->chan_obj, buffer_inflight->xfer_desc_list, XFER_LIST_LEN_CTRL, buffer_inflight->flags.ctrl.cur_stg);
|
||||
}
|
||||
|
||||
static inline void _buffer_parse_ctrl(dma_buffer_block_t *buffer)
|
||||
|
@ -2334,15 +2334,15 @@ static inline void _buffer_parse_ctrl(dma_buffer_block_t *buffer)
|
|||
//Parse the data stage for the remaining length
|
||||
int rem_len;
|
||||
int desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, 1, &rem_len, &desc_status);
|
||||
assert(desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, 1, &rem_len, &desc_status);
|
||||
assert(desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
assert(rem_len <= (transfer->num_bytes - sizeof(usb_setup_packet_t)));
|
||||
transfer->actual_num_bytes = transfer->num_bytes - rem_len;
|
||||
}
|
||||
//Update URB status
|
||||
transfer->status = USB_TRANSFER_STATUS_COMPLETED;
|
||||
//Clear the descriptor list
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_CTRL * sizeof(usbh_ll_dma_qtd_t));
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_CTRL * sizeof(usb_dwc_ll_dma_qtd_t));
|
||||
}
|
||||
|
||||
static inline void _buffer_parse_bulk(dma_buffer_block_t *buffer)
|
||||
|
@ -2351,14 +2351,14 @@ static inline void _buffer_parse_bulk(dma_buffer_block_t *buffer)
|
|||
//Update URB's actual number of bytes
|
||||
int rem_len;
|
||||
int desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, 0, &rem_len, &desc_status);
|
||||
assert(desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, 0, &rem_len, &desc_status);
|
||||
assert(desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
assert(rem_len <= transfer->num_bytes);
|
||||
transfer->actual_num_bytes = transfer->num_bytes - rem_len;
|
||||
//Update URB's status
|
||||
transfer->status = USB_TRANSFER_STATUS_COMPLETED;
|
||||
//Clear the descriptor list
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_BULK * sizeof(usbh_ll_dma_qtd_t));
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_BULK * sizeof(usb_dwc_ll_dma_qtd_t));
|
||||
}
|
||||
|
||||
static inline void _buffer_parse_intr(dma_buffer_block_t *buffer, bool is_in, int mps)
|
||||
|
@ -2371,12 +2371,12 @@ static inline void _buffer_parse_intr(dma_buffer_block_t *buffer, bool is_in, in
|
|||
int rem_len;
|
||||
int desc_status;
|
||||
for (int i = 0; i < intr_stop_idx - 1; i++) { //Check all packets before the short
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
}
|
||||
//Check the short packet
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, intr_stop_idx - 1, &rem_len, &desc_status);
|
||||
assert(rem_len > 0 && desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, intr_stop_idx - 1, &rem_len, &desc_status);
|
||||
assert(rem_len > 0 && desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
//Update actual bytes
|
||||
transfer->actual_num_bytes = (mps * intr_stop_idx - 2) + (mps - rem_len);
|
||||
} else {
|
||||
|
@ -2384,14 +2384,14 @@ static inline void _buffer_parse_intr(dma_buffer_block_t *buffer, bool is_in, in
|
|||
for (int i = 0; i < buffer->flags.intr.num_qtds - 1; i++) {
|
||||
int rem_len;
|
||||
int desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
}
|
||||
//Check the last packet
|
||||
int last_packet_rem_len;
|
||||
int last_packet_desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, buffer->flags.intr.num_qtds - 1, &last_packet_rem_len, &last_packet_desc_status);
|
||||
assert(last_packet_desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, buffer->flags.intr.num_qtds - 1, &last_packet_rem_len, &last_packet_desc_status);
|
||||
assert(last_packet_desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
//All packets except last MUST be MPS. So just deduct the remaining length of the last packet to get actual number of bytes
|
||||
transfer->actual_num_bytes = transfer->num_bytes - last_packet_rem_len;
|
||||
}
|
||||
|
@ -2400,15 +2400,15 @@ static inline void _buffer_parse_intr(dma_buffer_block_t *buffer, bool is_in, in
|
|||
for (int i = 0 ; i < buffer->flags.intr.num_qtds; i++) {
|
||||
int rem_len;
|
||||
int desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, i, &rem_len, &desc_status);
|
||||
assert(rem_len == 0 && desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS);
|
||||
}
|
||||
transfer->actual_num_bytes = transfer->num_bytes;
|
||||
}
|
||||
//Update URB's status
|
||||
transfer->status = USB_TRANSFER_STATUS_COMPLETED;
|
||||
//Clear the descriptor list
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_INTR * sizeof(usbh_ll_dma_qtd_t));
|
||||
memset(buffer->xfer_desc_list, 0, XFER_LIST_LEN_INTR * sizeof(usb_dwc_ll_dma_qtd_t));
|
||||
}
|
||||
|
||||
static inline void _buffer_parse_isoc(dma_buffer_block_t *buffer, bool is_in)
|
||||
|
@ -2420,15 +2420,15 @@ static inline void _buffer_parse_isoc(dma_buffer_block_t *buffer, bool is_in)
|
|||
//Clear the filled descriptor
|
||||
int rem_len;
|
||||
int desc_status;
|
||||
usbh_hal_xfer_desc_parse(buffer->xfer_desc_list, desc_idx, &rem_len, &desc_status);
|
||||
usbh_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx);
|
||||
usb_dwc_hal_xfer_desc_parse(buffer->xfer_desc_list, desc_idx, &rem_len, &desc_status);
|
||||
usb_dwc_hal_xfer_desc_clear(buffer->xfer_desc_list, desc_idx);
|
||||
assert(rem_len == 0 || is_in);
|
||||
assert(desc_status == USBH_HAL_XFER_DESC_STS_SUCCESS || USBH_HAL_XFER_DESC_STS_NOT_EXECUTED);
|
||||
assert(desc_status == USB_DWC_HAL_XFER_DESC_STS_SUCCESS || USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED);
|
||||
assert(rem_len <= transfer->isoc_packet_desc[pkt_idx].num_bytes); //Check for DMA errata
|
||||
//Update ISO packet actual length and status
|
||||
transfer->isoc_packet_desc[pkt_idx].actual_num_bytes = transfer->isoc_packet_desc[pkt_idx].num_bytes - rem_len;
|
||||
total_actual_num_bytes += transfer->isoc_packet_desc[pkt_idx].actual_num_bytes;
|
||||
transfer->isoc_packet_desc[pkt_idx].status = (desc_status == USBH_HAL_XFER_DESC_STS_NOT_EXECUTED) ? USB_TRANSFER_STATUS_SKIPPED : USB_TRANSFER_STATUS_COMPLETED;
|
||||
transfer->isoc_packet_desc[pkt_idx].status = (desc_status == USB_DWC_HAL_XFER_DESC_STS_NOT_EXECUTED) ? USB_TRANSFER_STATUS_SKIPPED : USB_TRANSFER_STATUS_COMPLETED;
|
||||
//A descriptor is also allocated for unscheduled frames. We need to skip over them
|
||||
desc_idx += buffer->flags.isoc.interval;
|
||||
if (desc_idx >= XFER_LIST_LEN_INTR) {
|
|
@ -1,12 +0,0 @@
|
|||
idf_build_get_property(target IDF_TARGET)
|
||||
|
||||
#USB Host is currently only supported on ESP32-S2, ESP32S3 chips
|
||||
if(NOT "${target}" MATCHES "^esp32s[2-3]")
|
||||
return()
|
||||
endif()
|
||||
|
||||
idf_component_register(
|
||||
SRC_DIRS "common" "hcd" "usb_host"
|
||||
PRIV_INCLUDE_DIRS "../private_include" "common" "hcd" "usb_host"
|
||||
PRIV_REQUIRES cmock usb test_utils
|
||||
)
|
|
@ -1,132 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include "usb/usb_types_ch9.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
const char *MSC_CLIENT_TAG = "MSC Client";
|
||||
|
||||
const uint8_t mock_msc_scsi_dev_desc[] = {
|
||||
0x12, 0x01, 0x00, 0x02, 0x00, 0x00, 0x00, 0x40, 0x5F, 0x12, 0x8A, 0xC0, 0x00, 0x01, 0x01, 0x02, 0x03, 0x01,
|
||||
};
|
||||
|
||||
const uint8_t mock_msc_scsi_config_desc[] = {
|
||||
0x09, 0x02, 0x20, 0x00, 0x01, 0x01, 0x00, 0x80, 0xF0, 0x09, 0x04, 0x00, 0x00, 0x02, 0x08, 0x06, 0x50, 0x00, 0x07,
|
||||
0x05, 0x01, 0x02, 0x40, 0x00, 0x01, 0x07, 0x05, 0x82, 0x02, 0x40, 0x00, 0x01,
|
||||
};
|
||||
|
||||
|
||||
const uint8_t mock_msc_scsi_str_desc_manu[] = {
|
||||
0x0c, 0x03, 0x41, 0x00, 0x44, 0x00, 0x41, 0x00, 0x54, 0x00, 0x41, 0x00,
|
||||
};
|
||||
|
||||
const uint8_t mock_msc_scsi_str_desc_prod[] = {
|
||||
0x2c, 0x03, 0x41, 0x00, 0x44, 0x00, 0x41, 0x00, 0x54, 0x00, 0x41, 0x00, 0x20, 0x00, 0x55, 0x00, 0x53, 0x00, 0x42,
|
||||
0x00, 0x20, 0x00, 0x46, 0x00, 0x6c, 0x00, 0x61, 0x00, 0x73, 0x00, 0x68, 0x00, 0x20, 0x00, 0x44, 0x00, 0x72, 0x00,
|
||||
0x69, 0x00, 0x76, 0x00, 0x65, 0x00,
|
||||
};
|
||||
|
||||
const uint8_t mock_msc_scsi_str_desc_ser_num[] = {
|
||||
0x22, 0x03, 0x31, 0x00, 0x33, 0x00, 0x43, 0x00, 0x32, 0x00, 0x38, 0x00, 0x31, 0x00, 0x36, 0x00, 0x35, 0x00, 0x38,
|
||||
0x00, 0x32, 0x00, 0x31, 0x00, 0x38, 0x00, 0x30, 0x00, 0x30, 0x00, 0x38, 0x00, 0x45, 0x00,
|
||||
};
|
||||
|
||||
const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x01, //EP 1 OUT
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x82, //EP 2 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = 64, //MPS of 64 bytes
|
||||
.bInterval = 1,
|
||||
};
|
||||
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag)
|
||||
{
|
||||
cbw->dCBWSignature = 0x43425355; //Fixed value
|
||||
cbw->dCBWTag = tag; //Random value that is echoed back
|
||||
cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE;
|
||||
cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag
|
||||
cbw->bCBWLUN = MOCK_MSC_SCSI_LUN;
|
||||
cbw->bCBWCBLength = 10; //The length of the SCSI command
|
||||
//Initialize SCSI CMD as READ10 or WRITE 10
|
||||
cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; //SCSI CMD READ10 or WRITE10
|
||||
cbw->CBWCB.flags = 0;
|
||||
cbw->CBWCB.lba_3 = (offset >> 24);
|
||||
cbw->CBWCB.lba_2 = (offset >> 16);
|
||||
cbw->CBWCB.lba_1 = (offset >> 8);
|
||||
cbw->CBWCB.lba_0 = (offset >> 0);
|
||||
cbw->CBWCB.group = 0;
|
||||
cbw->CBWCB.len_1 = (num_sectors >> 8);
|
||||
cbw->CBWCB.len_0 = (num_sectors >> 0);
|
||||
cbw->CBWCB.control = 0;
|
||||
}
|
||||
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect)
|
||||
{
|
||||
bool no_issues = true;
|
||||
if (csw->dCSWSignature != 0x53425355) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw signature corrupt (0x%"PRIX32")\n", csw->dCSWSignature);
|
||||
}
|
||||
if (csw->dCSWTag != tag_expect) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw tag unexpected! Expected %"PRIu32" got %"PRIu32"\n", tag_expect, csw->dCSWTag);
|
||||
}
|
||||
if (csw->dCSWDataResidue) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates data residue of %"PRIu32" bytes!\n", csw->dCSWDataResidue);
|
||||
}
|
||||
if (csw->bCSWStatus) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus);
|
||||
}
|
||||
return no_issues;
|
||||
}
|
||||
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
const usb_ep_desc_t mock_hid_mouse_in_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = 0x81, //EP 1 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
|
||||
.wMaxPacketSize = 4, //MPS of 4 bytes
|
||||
.bInterval = 10, //Interval of 10ms
|
||||
};
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter)
|
||||
{
|
||||
static int x_pos = 0;
|
||||
static int y_pos = 0;
|
||||
//Update X position
|
||||
if (report->x_movement & 0x80) { //Positive movement
|
||||
x_pos += report->x_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
x_pos -= report->x_movement & 0x7F;
|
||||
}
|
||||
//Update Y position
|
||||
if (report->y_movement & 0x80) { //Positive movement
|
||||
y_pos += report->y_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
y_pos -= report->y_movement & 0x7F;
|
||||
}
|
||||
printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter);
|
||||
}
|
|
@ -1,290 +0,0 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB
|
||||
Host stack.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_assert.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
extern const char *MSC_CLIENT_TAG;
|
||||
|
||||
/*
|
||||
Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should...
|
||||
|
||||
- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
|
||||
- It's configuration 1 should have the following endpoints
|
||||
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 0
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 64
|
||||
idVendor 0x125f
|
||||
idProduct 0xc08a
|
||||
bcdDevice 1.00
|
||||
iManufacturer 1
|
||||
iProduct 2
|
||||
iSerial 3
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 0x0020
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0x80
|
||||
(Bus Powered)
|
||||
MaxPower 480mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 2
|
||||
bInterfaceClass 8 Mass Storage
|
||||
bInterfaceSubClass 6 SCSI
|
||||
bInterfaceProtocol 80 Bulk-Only
|
||||
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 1
|
||||
Endpoint Descriptor:
|
||||
bLength 7
|
||||
bDescriptorType 5
|
||||
bEndpointAddress 0x82 EP 2 IN
|
||||
bmAttributes 2
|
||||
Transfer Type Bulk
|
||||
Synch Type None
|
||||
Usage Type Data
|
||||
wMaxPacketSize 0x0040 1x 64 bytes
|
||||
bInterval 1
|
||||
|
||||
If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
|
||||
*/
|
||||
|
||||
//Constant descriptors
|
||||
extern const uint8_t mock_msc_scsi_dev_desc[];
|
||||
extern const uint8_t mock_msc_scsi_config_desc[];
|
||||
extern const uint8_t mock_msc_scsi_str_desc_manu[];
|
||||
extern const uint8_t mock_msc_scsi_str_desc_prod[];
|
||||
extern const uint8_t mock_msc_scsi_str_desc_ser_num[];
|
||||
extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc;
|
||||
extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
|
||||
|
||||
#define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x125F
|
||||
#define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0xc08A
|
||||
#define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64
|
||||
#define MOCK_MSC_SCSI_SECTOR_SIZE 512
|
||||
#define MOCK_MSC_SCSI_LUN 0
|
||||
#define MOCK_MSC_SCSI_INTF_NUMBER 0
|
||||
#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
|
||||
#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x01
|
||||
#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x82
|
||||
#define MOCK_MSC_SCSI_BULK_EP_MPS 64
|
||||
|
||||
#define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \
|
||||
(setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \
|
||||
(setup_pkt_ptr)->bRequest = 0xFF; \
|
||||
(setup_pkt_ptr)->wValue = 0; \
|
||||
(setup_pkt_ptr)->wIndex = (intf_num); \
|
||||
(setup_pkt_ptr)->wLength = 0; \
|
||||
})
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
|
||||
uint8_t flags;
|
||||
uint8_t lba_3;
|
||||
uint8_t lba_2;
|
||||
uint8_t lba_1;
|
||||
uint8_t lba_0;
|
||||
uint8_t group;
|
||||
uint8_t len_1;
|
||||
uint8_t len_0;
|
||||
uint8_t control;
|
||||
} mock_scsi_cmd10_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
mock_scsi_cmd10_t CBWCB;
|
||||
uint8_t padding[6];
|
||||
} mock_msc_bulk_cbw_t;
|
||||
|
||||
// USB Bulk Transfer Command Status Wrapper data
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bCSWStatus;
|
||||
} mock_msc_bulk_csw_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command
|
||||
*
|
||||
* @param cbw CBW structure
|
||||
* @param is_read Is a read command
|
||||
* @param offset Block offset
|
||||
* @param num_sectors Number of sectors to read
|
||||
* @param tag Tag (this is simply echoed back
|
||||
*/
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag);
|
||||
|
||||
/**
|
||||
* @brief Check that returned Command Status Wrapper (CSW) is valid
|
||||
*
|
||||
* @param csw CSW structure
|
||||
* @param tag_expect Expected tag
|
||||
* @return true CSW is valid
|
||||
* @return false CSW is not valid
|
||||
*/
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect);
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should...
|
||||
|
||||
- Be implement the HID with standard report format used by mice
|
||||
- It's configuration 1 should have the following endpoint
|
||||
|
||||
Device Descriptor:
|
||||
bLength 18
|
||||
bDescriptorType 1
|
||||
bcdUSB 2.00
|
||||
bDeviceClass 0
|
||||
bDeviceSubClass 0
|
||||
bDeviceProtocol 0
|
||||
bMaxPacketSize0 8
|
||||
idVendor 0x413c Dell Computer Corp.
|
||||
idProduct 0x301a
|
||||
bcdDevice 1.00
|
||||
iManufacturer 1
|
||||
iProduct 2
|
||||
iSerial 0
|
||||
bNumConfigurations 1
|
||||
Configuration Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 2
|
||||
wTotalLength 0x0022
|
||||
bNumInterfaces 1
|
||||
bConfigurationValue 1
|
||||
iConfiguration 0
|
||||
bmAttributes 0xa0
|
||||
(Bus Powered)
|
||||
Remote Wakeup
|
||||
MaxPower 100mA
|
||||
Interface Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 4
|
||||
bInterfaceNumber 0
|
||||
bAlternateSetting 0
|
||||
bNumEndpoints 1
|
||||
bInterfaceClass 3 Human Interface Device
|
||||
bInterfaceSubClass 1 Boot Interface Subclass
|
||||
bInterfaceProtocol 2 Mouse
|
||||
iInterface 0
|
||||
HID Device Descriptor:
|
||||
bLength 9
|
||||
bDescriptorType 33
|
||||
bcdHID 1.11
|
||||
bCountryCode 0 Not supported
|
||||
bNumDescriptors 1
|
||||
bDescriptorType 34 Report
|
||||
wDescriptorLength 46
|
||||
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
|
||||
|
||||
If you're using another mice with different endpoints, modify the endpoint descriptor below
|
||||
*/
|
||||
|
||||
extern const usb_ep_desc_t mock_hid_mouse_in_ep_desc;
|
||||
|
||||
#define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x413C
|
||||
#define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x301A
|
||||
#define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8
|
||||
#define MOCK_HID_MOUSE_INTF_NUMBER 0
|
||||
#define MOCK_HID_MOUSE_INTF_ALT_SETTING 0
|
||||
#define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81
|
||||
#define MOCK_HID_MOUSE_INTR_IN_MPS 0x04
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t left_button: 1;
|
||||
uint32_t right_button: 1;
|
||||
uint32_t middle_button: 1;
|
||||
uint32_t reserved5: 5;
|
||||
uint8_t x_movement;
|
||||
uint8_t y_movement;
|
||||
} __attribute__((packed));
|
||||
uint8_t val[3];
|
||||
} mock_hid_mouse_report_t;
|
||||
ESP_STATIC_ASSERT(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect");
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter);
|
||||
|
||||
// ---------------------------------------------------- Mock ISOC ------------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for
|
||||
ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below:
|
||||
*/
|
||||
|
||||
#define MOCK_ISOC_EP_NUM 2
|
||||
#define MOCK_ISOC_EP_MPS 512
|
||||
|
||||
|
||||
static const usb_ep_desc_t mock_isoc_out_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_ISOC_EP_NUM,
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
|
||||
.wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
|
||||
.bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,3 @@
|
|||
idf_component_register(SRCS "test_usb_common.c" "test_usb_mock_msc.c" "test_usb_mock_hid.c"
|
||||
INCLUDE_DIRS "."
|
||||
REQUIRES usb unity)
|
|
@ -11,6 +11,7 @@
|
|||
#include "hal/usb_phy_types.h"
|
||||
#include "esp_private/usb_phy.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "unity.h"
|
||||
|
||||
static usb_phy_handle_t phy_hdl = NULL;
|
||||
|
||||
|
@ -25,13 +26,13 @@ void test_usb_init_phy(void)
|
|||
.ext_io_conf = NULL,
|
||||
.otg_io_conf = NULL,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_new_phy(&phy_config, &phy_hdl));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_new_phy(&phy_config, &phy_hdl), "Failed to init USB PHY");
|
||||
}
|
||||
|
||||
void test_usb_deinit_phy(void)
|
||||
{
|
||||
//Deinitialize the internal USB PHY
|
||||
ESP_ERROR_CHECK(usb_del_phy(phy_hdl));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_del_phy(phy_hdl), "Failed to delete PHY");
|
||||
phy_hdl = NULL;
|
||||
}
|
||||
|
|
@ -13,7 +13,7 @@
|
|||
void test_usb_init_phy(void);
|
||||
|
||||
/**
|
||||
* @brief Deinitalize the internal USB PHY and USB Controller after USB Host testing
|
||||
* @brief Deinitialize the internal USB PHY and USB Controller after USB Host testing
|
||||
*/
|
||||
void test_usb_deinit_phy(void);
|
||||
|
|
@ -0,0 +1,42 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "usb/usb_types_ch9.h"
|
||||
#include "test_usb_mock_hid.h"
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
const usb_ep_desc_t mock_hid_mouse_in_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_HID_MOUSE_INTR_IN_EP_ADDR, //EP 1 IN
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_INT,
|
||||
.wMaxPacketSize = MOCK_HID_MOUSE_INTR_IN_MPS,
|
||||
.bInterval = 10, //Interval of 10ms
|
||||
};
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter)
|
||||
{
|
||||
static int x_pos = 0;
|
||||
static int y_pos = 0;
|
||||
//Update X position
|
||||
if (report->x_movement & 0x80) { //Positive movement
|
||||
x_pos += report->x_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
x_pos -= report->x_movement & 0x7F;
|
||||
}
|
||||
//Update Y position
|
||||
if (report->y_movement & 0x80) { //Positive movement
|
||||
y_pos += report->y_movement & 0x7F;
|
||||
} else { //Negative movement
|
||||
y_pos -= report->y_movement & 0x7F;
|
||||
}
|
||||
printf("\rX:%d\tY:%d\tIter: %d\n", x_pos, y_pos, iter);
|
||||
}
|
|
@ -0,0 +1,113 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB
|
||||
Host stack.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_assert.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------- HID Mouse ------------------------------------------------------
|
||||
|
||||
|
||||
/*
|
||||
Note: The mock HID mouse tests require that USB low speed mouse be connected. The mouse should...
|
||||
|
||||
- Be implement the HID with standard report format used by mice
|
||||
- It's configuration 1 should have the following endpoint
|
||||
|
||||
------------------ Configuration Descriptor -------------------
|
||||
bLength : 0x09 (9 bytes)
|
||||
bDescriptorType : 0x02 (Configuration Descriptor)
|
||||
wTotalLength : 0x003B (59 bytes)
|
||||
bNumInterfaces : 0x02 (2 Interfaces)
|
||||
bConfigurationValue : 0x01 (Configuration 1)
|
||||
iConfiguration : 0x00 (No String Descriptor)
|
||||
bmAttributes : 0xA0
|
||||
D7: Reserved, set 1 : 0x01
|
||||
D6: Self Powered : 0x00 (no)
|
||||
D5: Remote Wakeup : 0x01 (yes)
|
||||
D4..0: Reserved, set 0 : 0x00
|
||||
MaxPower : 0x32 (100 mA)
|
||||
Data (HexDump) : 09 02 3B 00 02 01 00 A0 32 09 04 00 00 01 03 01
|
||||
02 00 09 21 00 02 00 01 22 4D 00 07 05 81 03 08
|
||||
00 0A 09 04 01 00 01 03 01 01 00 09 21 00 02 00
|
||||
01 22 31 00 07 05 82 03 08 00 0A
|
||||
|
||||
---------------- Interface Descriptor -----------------
|
||||
bLength : 0x09 (9 bytes)
|
||||
bDescriptorType : 0x04 (Interface Descriptor)
|
||||
bInterfaceNumber : 0x00
|
||||
bAlternateSetting : 0x00
|
||||
bNumEndpoints : 0x01 (1 Endpoint)
|
||||
bInterfaceClass : 0x03 (HID - Human Interface Device)
|
||||
bInterfaceSubClass : 0x01 (Boot Interface)
|
||||
bInterfaceProtocol : 0x02 (Mouse)
|
||||
iInterface : 0x00 (No String Descriptor)
|
||||
Data (HexDump) : 09 04 00 00 01 03 01 02 00
|
||||
|
||||
------------------- HID Descriptor --------------------
|
||||
bLength : 0x09 (9 bytes)
|
||||
bDescriptorType : 0x21 (HID Descriptor)
|
||||
bcdHID : 0x0200 (HID Version 2.00)
|
||||
bCountryCode : 0x00 (00 = not localized)
|
||||
bNumDescriptors : 0x01
|
||||
Data (HexDump) : 09 21 00 02 00 01 22 4D 00
|
||||
Descriptor 1:
|
||||
bDescriptorType : 0x22 (Class=Report)
|
||||
wDescriptorLength : 0x004D (77 bytes)
|
||||
Error reading descriptor : ERROR_INVALID_PARAMETER (due to a obscure limitation of the Win32 USB API, see UsbTreeView.txt)
|
||||
|
||||
----------------- Endpoint Descriptor -----------------
|
||||
bLength : 0x07 (7 bytes)
|
||||
bDescriptorType : 0x05 (Endpoint Descriptor)
|
||||
bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
|
||||
bmAttributes : 0x03 (TransferType=Interrupt)
|
||||
wMaxPacketSize : 0x0008
|
||||
bInterval : 0x0A (10 ms)
|
||||
Data (HexDump) : 07 05 81 03 08 00 0A
|
||||
|
||||
If you're using another mice with different endpoints, modify the endpoint descriptor below
|
||||
*/
|
||||
|
||||
extern const usb_ep_desc_t mock_hid_mouse_in_ep_desc;
|
||||
|
||||
#define MOCK_HID_MOUSE_DEV_ID_VENDOR 0x03F0
|
||||
#define MOCK_HID_MOUSE_DEV_ID_PRODUCT 0x1198
|
||||
#define MOCK_HID_MOUSE_DEV_DFLT_EP_MPS 8
|
||||
#define MOCK_HID_MOUSE_INTF_NUMBER 0
|
||||
#define MOCK_HID_MOUSE_INTF_ALT_SETTING 0
|
||||
#define MOCK_HID_MOUSE_INTR_IN_EP_ADDR 0x81
|
||||
#define MOCK_HID_MOUSE_INTR_IN_MPS 8
|
||||
|
||||
typedef union {
|
||||
struct {
|
||||
uint32_t left_button: 1;
|
||||
uint32_t right_button: 1;
|
||||
uint32_t middle_button: 1;
|
||||
uint32_t reserved5: 5;
|
||||
uint8_t x_movement;
|
||||
uint8_t y_movement;
|
||||
} __attribute__((packed));
|
||||
uint8_t val[3];
|
||||
} mock_hid_mouse_report_t;
|
||||
ESP_STATIC_ASSERT(sizeof(mock_hid_mouse_report_t) == 3, "Size of HID mouse report incorrect");
|
||||
|
||||
void mock_hid_process_report(mock_hid_mouse_report_t *report, int iter);
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,158 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <inttypes.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "usb/usb_types_ch9.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
const char *MSC_CLIENT_TAG = "MSC Client";
|
||||
|
||||
const usb_device_desc_t mock_msc_scsi_dev_desc = {
|
||||
.bLength = USB_DEVICE_DESC_SIZE,
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_DEVICE,
|
||||
.bcdUSB = MOCK_MSC_SCSI_USB_VERSION,
|
||||
.bDeviceClass = USB_CLASS_PER_INTERFACE,
|
||||
.bDeviceSubClass = 0,
|
||||
.bDeviceProtocol = 0,
|
||||
.bMaxPacketSize0 = MOCK_MSC_SCSI_DEV_DFLT_EP_MPS,
|
||||
.idVendor = MOCK_MSC_SCSI_DEV_ID_VENDOR,
|
||||
.idProduct = MOCK_MSC_SCSI_DEV_ID_PRODUCT,
|
||||
.bcdDevice = MOCK_MSC_SCSI_DEV_VERSION,
|
||||
.iManufacturer = 1,
|
||||
.iProduct = 2,
|
||||
.iSerialNumber = 3,
|
||||
.bNumConfigurations = 1,
|
||||
};
|
||||
|
||||
#define MOCK_MSC_SCSI_WTOTALLENGTH (USB_CONFIG_DESC_SIZE + USB_INTF_DESC_SIZE + 2*USB_EP_DESC_SIZE)
|
||||
static const usb_config_desc_t mock_msc_config_desc = {
|
||||
.bLength = USB_CONFIG_DESC_SIZE,
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_CONFIGURATION,
|
||||
.wTotalLength = MOCK_MSC_SCSI_WTOTALLENGTH,
|
||||
.bNumInterfaces = 1,
|
||||
.bConfigurationValue = 1,
|
||||
.iConfiguration = 0,
|
||||
.bmAttributes = 0x80,
|
||||
.bMaxPower = 0x70, //224mA
|
||||
};
|
||||
|
||||
static const usb_intf_desc_t mock_msc_intf_desc = {
|
||||
.bLength = USB_INTF_DESC_SIZE,
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_INTERFACE,
|
||||
.bInterfaceNumber = MOCK_MSC_SCSI_INTF_NUMBER,
|
||||
.bAlternateSetting = MOCK_MSC_SCSI_INTF_ALT_SETTING,
|
||||
.bNumEndpoints = 2,
|
||||
.bInterfaceClass = USB_CLASS_MASS_STORAGE,
|
||||
.bInterfaceSubClass = 0x06, //SCSI
|
||||
.bInterfaceProtocol = 0x50, //Bulk only
|
||||
.iInterface = 0,
|
||||
};
|
||||
|
||||
uint8_t mock_msc_scsi_config_desc[255];
|
||||
uint16_t mock_msc_scsi_str_desc_manu[128];
|
||||
uint16_t mock_msc_scsi_str_desc_prod[128];
|
||||
uint16_t mock_msc_scsi_str_desc_ser_num[128];
|
||||
|
||||
const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_MSC_SCSI_BULK_OUT_EP_ADDR, //EP 1 OUT
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS, //MPS of 64 bytes
|
||||
.bInterval = 0,
|
||||
};
|
||||
|
||||
const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_MSC_SCSI_BULK_IN_EP_ADDR,
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_BULK,
|
||||
.wMaxPacketSize = MOCK_MSC_SCSI_BULK_EP_MPS, //MPS of 64 bytes
|
||||
.bInterval = 0,
|
||||
};
|
||||
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag)
|
||||
{
|
||||
cbw->dCBWSignature = 0x43425355; //Fixed value
|
||||
cbw->dCBWTag = tag; //Random value that is echoed back
|
||||
cbw->dCBWDataTransferLength = num_sectors * MOCK_MSC_SCSI_SECTOR_SIZE;
|
||||
cbw->bmCBWFlags = (is_read) ? (1 << 7) : 0; //If this is a read, set the direction flag
|
||||
cbw->bCBWLUN = MOCK_MSC_SCSI_LUN;
|
||||
cbw->bCBWCBLength = 10; //The length of the SCSI command
|
||||
//Initialize SCSI CMD as READ10 or WRITE 10
|
||||
cbw->CBWCB.opcode = (is_read) ? 0x28 : 0x2A; //SCSI CMD READ10 or WRITE10
|
||||
cbw->CBWCB.flags = 0;
|
||||
cbw->CBWCB.lba_3 = (offset >> 24);
|
||||
cbw->CBWCB.lba_2 = (offset >> 16);
|
||||
cbw->CBWCB.lba_1 = (offset >> 8);
|
||||
cbw->CBWCB.lba_0 = (offset >> 0);
|
||||
cbw->CBWCB.group = 0;
|
||||
cbw->CBWCB.len_1 = (num_sectors >> 8);
|
||||
cbw->CBWCB.len_0 = (num_sectors >> 0);
|
||||
cbw->CBWCB.control = 0;
|
||||
}
|
||||
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect)
|
||||
{
|
||||
bool no_issues = true;
|
||||
if (csw->dCSWSignature != 0x53425355) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw signature corrupt (0x%"PRIX32")\n", csw->dCSWSignature);
|
||||
}
|
||||
if (csw->dCSWTag != tag_expect) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw tag unexpected! Expected %"PRIu32" got %"PRIu32"\n", tag_expect, csw->dCSWTag);
|
||||
}
|
||||
if (csw->dCSWDataResidue) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates data residue of %"PRIu32" bytes!\n", csw->dCSWDataResidue);
|
||||
}
|
||||
if (csw->bCSWStatus) {
|
||||
no_issues = false;
|
||||
printf("Warning: csw indicates non-good status %d!\n", csw->bCSWStatus);
|
||||
}
|
||||
return no_issues;
|
||||
}
|
||||
|
||||
void mock_msc_scsi_init_reference_descriptors(void)
|
||||
{
|
||||
// Configuration descriptor
|
||||
uint8_t *dest_ptr = mock_msc_scsi_config_desc;
|
||||
memcpy(dest_ptr, (void*)&mock_msc_config_desc, sizeof(mock_msc_config_desc));
|
||||
dest_ptr += USB_CONFIG_DESC_SIZE;
|
||||
memcpy(dest_ptr, (void*)&mock_msc_intf_desc, sizeof(mock_msc_intf_desc));
|
||||
dest_ptr += USB_INTF_DESC_SIZE;
|
||||
memcpy(dest_ptr, (void*)&mock_msc_scsi_bulk_in_ep_desc, sizeof(mock_msc_scsi_bulk_in_ep_desc));
|
||||
dest_ptr += USB_EP_DESC_SIZE;
|
||||
memcpy(dest_ptr, (void*)&mock_msc_scsi_bulk_out_ep_desc, sizeof(mock_msc_scsi_bulk_out_ep_desc));
|
||||
|
||||
// String descriptors
|
||||
const char *str = MOCK_MSC_SCSI_STRING_1;
|
||||
uint8_t chr_count = strlen(str);
|
||||
mock_msc_scsi_str_desc_manu[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
mock_msc_scsi_str_desc_manu[1 + i] = str[i];
|
||||
}
|
||||
|
||||
str = MOCK_MSC_SCSI_STRING_2;
|
||||
chr_count = strlen(str);
|
||||
mock_msc_scsi_str_desc_prod[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
mock_msc_scsi_str_desc_prod[1 + i] = str[i];
|
||||
}
|
||||
|
||||
str = MOCK_MSC_SCSI_STRING_3;
|
||||
chr_count = strlen(str);
|
||||
mock_msc_scsi_str_desc_ser_num[0] = (USB_B_DESCRIPTOR_TYPE_STRING << 8 ) | (2 * chr_count + 2); // first byte is length (including header), second byte is string type
|
||||
for (uint8_t i = 0; i < chr_count; i++) {
|
||||
mock_msc_scsi_str_desc_ser_num[1 + i] = str[i];
|
||||
}
|
||||
}
|
|
@ -0,0 +1,196 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2015-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
/*
|
||||
This header contains bare-bone mock implementations of some device classes in order to test various layers of the USB
|
||||
Host stack.
|
||||
*/
|
||||
|
||||
#pragma once
|
||||
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "esp_assert.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
|
||||
#ifdef __cplusplus
|
||||
extern "C" {
|
||||
#endif
|
||||
|
||||
// ---------------------------------------------------- MSC SCSI -------------------------------------------------------
|
||||
|
||||
extern const char *MSC_CLIENT_TAG;
|
||||
|
||||
/*
|
||||
Note: The mock MSC SCSI tests requires that USB flash drive be connected. The flash drive should...
|
||||
|
||||
- Be implement the Mass Storage class supporting BULK only transfers using SCSI commands
|
||||
- It's configuration 1 should have the following endpoints
|
||||
|
||||
------------------ Configuration Descriptor -------------------
|
||||
bLength : 0x09 (9 bytes)
|
||||
bDescriptorType : 0x02 (Configuration Descriptor)
|
||||
wTotalLength : 0x0020 (32 bytes)
|
||||
bNumInterfaces : 0x01 (1 Interface)
|
||||
bConfigurationValue : 0x01 (Configuration 1)
|
||||
iConfiguration : 0x00 (No String Descriptor)
|
||||
bmAttributes : 0x80
|
||||
D7: Reserved, set 1 : 0x01
|
||||
D6: Self Powered : 0x00 (no)
|
||||
D5: Remote Wakeup : 0x00 (no)
|
||||
D4..0: Reserved, set 0 : 0x00
|
||||
MaxPower : 0x70 (224 mA)
|
||||
Data (HexDump) : 09 02 20 00 01 01 00 80 70 09 04 00 00 02 08 06
|
||||
50 00 07 05 81 02 00 02 00 07 05 02 02 00 02 00
|
||||
|
||||
---------------- Interface Descriptor -----------------
|
||||
bLength : 0x09 (9 bytes)
|
||||
bDescriptorType : 0x04 (Interface Descriptor)
|
||||
bInterfaceNumber : 0x00
|
||||
bAlternateSetting : 0x00
|
||||
bNumEndpoints : 0x02 (2 Endpoints)
|
||||
bInterfaceClass : 0x08 (Mass Storage)
|
||||
bInterfaceSubClass : 0x06 (SCSI transparent command set)
|
||||
bInterfaceProtocol : 0x50 (Bulk-Only Transport)
|
||||
iInterface : 0x00 (No String Descriptor)
|
||||
Data (HexDump) : 09 04 00 00 02 08 06 50 00
|
||||
|
||||
----------------- Endpoint Descriptor -----------------
|
||||
bLength : 0x07 (7 bytes)
|
||||
bDescriptorType : 0x05 (Endpoint Descriptor)
|
||||
bEndpointAddress : 0x81 (Direction=IN EndpointID=1)
|
||||
bmAttributes : 0x02 (TransferType=Bulk)
|
||||
wMaxPacketSize : 0x0040 (max 64 bytes)
|
||||
bInterval : 0x00 (never NAKs)
|
||||
Data (HexDump) : 07 05 81 02 40 00 00
|
||||
|
||||
----------------- Endpoint Descriptor -----------------
|
||||
bLength : 0x07 (7 bytes)
|
||||
bDescriptorType : 0x05 (Endpoint Descriptor)
|
||||
bEndpointAddress : 0x02 (Direction=OUT EndpointID=2)
|
||||
bmAttributes : 0x02 (TransferType=Bulk)
|
||||
wMaxPacketSize : 0x0040 (max 64 bytes)
|
||||
bInterval : 0x00 (never NAKs)
|
||||
Data (HexDump) : 07 05 02 02 40 00 00
|
||||
|
||||
If you're using a flash driver with different endpoints, modify the endpoint descriptors below.
|
||||
*/
|
||||
|
||||
//Constant descriptors
|
||||
extern const usb_device_desc_t mock_msc_scsi_dev_desc;
|
||||
extern uint8_t mock_msc_scsi_config_desc[255];
|
||||
extern uint16_t mock_msc_scsi_str_desc_manu[128];
|
||||
extern uint16_t mock_msc_scsi_str_desc_prod[128];
|
||||
extern uint16_t mock_msc_scsi_str_desc_ser_num[128];
|
||||
extern const usb_ep_desc_t mock_msc_scsi_bulk_out_ep_desc;
|
||||
extern const usb_ep_desc_t mock_msc_scsi_bulk_in_ep_desc;
|
||||
|
||||
#define MOCK_MSC_SCSI_DEV_ID_VENDOR 0x0781 // Western Digital, Sandisk
|
||||
#define MOCK_MSC_SCSI_DEV_ID_PRODUCT 0x5595
|
||||
#define MOCK_MSC_SCSI_DEV_VERSION 0x0100 //1.00
|
||||
#define MOCK_MSC_SCSI_USB_VERSION 0x0210 //2.10
|
||||
#define MOCK_MSC_SCSI_DEV_DFLT_EP_MPS 64
|
||||
#define MOCK_MSC_SCSI_SECTOR_SIZE 512
|
||||
#define MOCK_MSC_SCSI_LUN 0
|
||||
#define MOCK_MSC_SCSI_INTF_NUMBER 0
|
||||
#define MOCK_MSC_SCSI_INTF_ALT_SETTING 0
|
||||
#define MOCK_MSC_SCSI_BULK_OUT_EP_ADDR 0x02
|
||||
#define MOCK_MSC_SCSI_BULK_IN_EP_ADDR 0x81
|
||||
#define MOCK_MSC_SCSI_BULK_EP_MPS 64
|
||||
#define MOCK_MSC_SCSI_STRING_1 (" USB")
|
||||
#define MOCK_MSC_SCSI_STRING_2 (" SanDisk 3.2Gen1")
|
||||
#define MOCK_MSC_SCSI_STRING_3 ("0101cdd1e856b427bbb796f870561a4b2b817af9da9872c8d75217cccdd5d5eccb3a0000000000000000000096abe1a3ff83610095558107aea948b4") // This string is NOT checked by the enum test
|
||||
|
||||
#define MOCK_MSC_SCSI_REQ_INIT_RESET(setup_pkt_ptr, intf_num) ({ \
|
||||
(setup_pkt_ptr)->bmRequestType = USB_BM_REQUEST_TYPE_DIR_OUT | USB_BM_REQUEST_TYPE_TYPE_CLASS | USB_BM_REQUEST_TYPE_RECIP_INTERFACE; \
|
||||
(setup_pkt_ptr)->bRequest = 0xFF; \
|
||||
(setup_pkt_ptr)->wValue = 0; \
|
||||
(setup_pkt_ptr)->wIndex = (intf_num); \
|
||||
(setup_pkt_ptr)->wLength = 0; \
|
||||
})
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint8_t opcode; //0x28 = read(10), 0x2A=write(10)
|
||||
uint8_t flags;
|
||||
uint8_t lba_3;
|
||||
uint8_t lba_2;
|
||||
uint8_t lba_1;
|
||||
uint8_t lba_0;
|
||||
uint8_t group;
|
||||
uint8_t len_1;
|
||||
uint8_t len_0;
|
||||
uint8_t control;
|
||||
} mock_scsi_cmd10_t;
|
||||
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCBWSignature;
|
||||
uint32_t dCBWTag;
|
||||
uint32_t dCBWDataTransferLength;
|
||||
uint8_t bmCBWFlags;
|
||||
uint8_t bCBWLUN;
|
||||
uint8_t bCBWCBLength;
|
||||
mock_scsi_cmd10_t CBWCB;
|
||||
uint8_t padding[6];
|
||||
} mock_msc_bulk_cbw_t;
|
||||
|
||||
// USB Bulk Transfer Command Status Wrapper data
|
||||
typedef struct __attribute__((packed)) {
|
||||
uint32_t dCSWSignature;
|
||||
uint32_t dCSWTag;
|
||||
uint32_t dCSWDataResidue;
|
||||
uint8_t bCSWStatus;
|
||||
} mock_msc_bulk_csw_t;
|
||||
|
||||
/**
|
||||
* @brief Initialize a MSC Command Block Wrapper (CBW) as an SCSI command
|
||||
*
|
||||
* @param cbw CBW structure
|
||||
* @param is_read Is a read command
|
||||
* @param offset Block offset
|
||||
* @param num_sectors Number of sectors to read
|
||||
* @param tag Tag (this is simply echoed back
|
||||
*/
|
||||
void mock_msc_scsi_init_cbw(mock_msc_bulk_cbw_t *cbw, bool is_read, int offset, int num_sectors, uint32_t tag);
|
||||
|
||||
/**
|
||||
* @brief Check that returned Command Status Wrapper (CSW) is valid
|
||||
*
|
||||
* @param csw CSW structure
|
||||
* @param tag_expect Expected tag
|
||||
* @return true CSW is valid
|
||||
* @return false CSW is not valid
|
||||
*/
|
||||
bool mock_msc_scsi_check_csw(mock_msc_bulk_csw_t *csw, uint32_t tag_expect);
|
||||
|
||||
/**
|
||||
* @brief Construct configuration and string descriptors
|
||||
*/
|
||||
void mock_msc_scsi_init_reference_descriptors(void);
|
||||
|
||||
// ---------------------------------------------------- Mock ISOC ------------------------------------------------------
|
||||
|
||||
/*
|
||||
Note: ISOC test rely on communicating with a non existent endpoint using ISOC OUT transfers. Since no ACK is given for
|
||||
ISOC, transferring to a non-existent endpoint should work. The non-existent endpoint descriptor is described below:
|
||||
*/
|
||||
|
||||
#define MOCK_ISOC_EP_NUM 2
|
||||
#define MOCK_ISOC_EP_MPS 512
|
||||
|
||||
|
||||
static const usb_ep_desc_t mock_isoc_out_ep_desc = {
|
||||
.bLength = sizeof(usb_ep_desc_t),
|
||||
.bDescriptorType = USB_B_DESCRIPTOR_TYPE_ENDPOINT,
|
||||
.bEndpointAddress = MOCK_ISOC_EP_NUM,
|
||||
.bmAttributes = USB_BM_ATTRIBUTES_XFER_ISOC,
|
||||
.wMaxPacketSize = MOCK_ISOC_EP_MPS, //MPS of 512 bytes
|
||||
.bInterval = 1, //Isoc interval is (2 ^ (bInterval - 1)) which means an interval of 1ms
|
||||
};
|
||||
|
||||
|
||||
#ifdef __cplusplus
|
||||
}
|
||||
#endif
|
|
@ -0,0 +1,6 @@
|
|||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(EXTRA_COMPONENT_DIRS "../common")
|
||||
project(test_app_usb_host)
|
|
@ -0,0 +1,10 @@
|
|||
| Supported Targets | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- |
|
||||
|
||||
# USB: Host test application
|
||||
|
||||
There are two sets of tests in this application:
|
||||
1. Low-speed: Expects low-speed USB mouse with interrupt endpoint to be connected
|
||||
2. Full-speed: Expects full-speed USB flash disk with 2 bulk endpoints to be connected
|
||||
|
||||
For running these tests locally, you will have to update device definitions (VID, PID, ...) in [test_usb_mock_classes.h](../common/test_usb_mock_classes.h).
|
|
@ -0,0 +1,6 @@
|
|||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "../../../private_include" "."
|
||||
REQUIRES usb unity common
|
||||
WHOLE_ARCHIVE)
|
|
@ -0,0 +1,48 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "unity_test_utils_memory.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
unity_utils_record_free_mem();
|
||||
port_hdl = test_hcd_setup();
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
test_hcd_teardown(port_hdl);
|
||||
port_hdl = NULL;
|
||||
unity_utils_evaluate_leaks();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// ____ ___ ___________________ __ __
|
||||
// | | \/ _____/\______ \ _/ |_ ____ _______/ |_
|
||||
// | | /\_____ \ | | _/ \ __\/ __ \ / ___/\ __\.
|
||||
// | | / / \ | | \ | | \ ___/ \___ \ | |
|
||||
// |______/ /_______ / |______ / |__| \___ >____ > |__|
|
||||
// \/ \/ \/ \/
|
||||
printf(" ____ ___ ___________________ __ __ \r\n");
|
||||
printf("| | \\/ _____/\\______ \\ _/ |_ ____ _______/ |_ \r\n");
|
||||
printf("| | /\\_____ \\ | | _/ \\ __\\/ __ \\ / ___/\\ __\\\r\n");
|
||||
printf("| | / / \\ | | \\ | | \\ ___/ \\___ \\ | | \r\n");
|
||||
printf("|______/ /_______ / |______ / |__| \\___ >____ > |__| \r\n");
|
||||
printf(" \\/ \\/ \\/ \\/ \r\n");
|
||||
|
||||
unity_utils_setup_heap_record(80);
|
||||
unity_utils_set_leak_level(128);
|
||||
unity_run_menu();
|
||||
}
|
|
@ -9,8 +9,7 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
@ -25,8 +24,8 @@ static void mock_msc_reset_req(hcd_pipe_handle_t default_pipe)
|
|||
//Enqueue, wait, dequeue, and check URB
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb));
|
||||
test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_PTR(urb, hcd_urb_dequeue(default_pipe));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
//Free URB
|
||||
test_hcd_free_urb(urb);
|
||||
}
|
||||
|
@ -53,9 +52,8 @@ Procedure:
|
|||
#define TEST_NUM_SECTORS_TOTAL 10
|
||||
#define TEST_NUM_SECTORS_PER_XFER 2
|
||||
|
||||
TEST_CASE("Test HCD bulk pipe URBs", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD bulk pipe URBs", "[bulk][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -80,20 +78,20 @@ TEST_CASE("Test HCD bulk pipe URBs", "[hcd][ignore]")
|
|||
mock_msc_scsi_init_cbw((mock_msc_bulk_cbw_t *)urb_cbw->transfer.data_buffer, true, block_num, TEST_NUM_SECTORS_PER_XFER, 0xAAAAAAAA);
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_out_pipe, urb_cbw));
|
||||
test_hcd_expect_pipe_event(bulk_out_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb_cbw, hcd_urb_dequeue(bulk_out_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb_cbw->transfer.status);
|
||||
TEST_ASSERT_EQUAL_PTR(urb_cbw, hcd_urb_dequeue(bulk_out_pipe));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_cbw->transfer.status, "Transfer NOT completed");
|
||||
//Read data through BULK IN pipe
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_in_pipe, urb_data));
|
||||
test_hcd_expect_pipe_event(bulk_in_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb_data, hcd_urb_dequeue(bulk_in_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status);
|
||||
TEST_ASSERT_EQUAL_PTR(urb_data, hcd_urb_dequeue(bulk_in_pipe));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status, "Transfer NOT completed");
|
||||
//Read the CSW through BULK IN pipe
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(bulk_in_pipe, urb_csw));
|
||||
test_hcd_expect_pipe_event(bulk_in_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb_csw, hcd_urb_dequeue(bulk_in_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status);
|
||||
TEST_ASSERT_EQUAL_PTR(urb_csw, hcd_urb_dequeue(bulk_in_pipe));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb_data->transfer.status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_csw_t), urb_csw->transfer.actual_num_bytes);
|
||||
TEST_ASSERT_EQUAL(true, mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)urb_csw->transfer.data_buffer, 0xAAAAAAAA));
|
||||
TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)urb_csw->transfer.data_buffer, 0xAAAAAAAA));
|
||||
//Print the read data
|
||||
printf("Block %d to %d:\n", block_num, block_num + TEST_NUM_SECTORS_PER_XFER);
|
||||
for (int i = 0; i < urb_data->transfer.actual_num_bytes; i++) {
|
||||
|
@ -110,5 +108,4 @@ TEST_CASE("Test HCD bulk pipe URBs", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
|
@ -8,7 +8,7 @@
|
|||
#include <string.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "test_utils.h"
|
||||
#include "freertos/task.h"
|
||||
#include "soc/usb_wrap_struct.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "esp_err.h"
|
||||
|
@ -19,6 +19,7 @@
|
|||
#include "usb/usb_types_ch9.h"
|
||||
#include "test_hcd_common.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "unity.h"
|
||||
|
||||
#define PORT_NUM 1
|
||||
#define EVENT_QUEUE_LEN 5
|
||||
|
@ -35,6 +36,8 @@ typedef struct {
|
|||
hcd_pipe_event_t pipe_event;
|
||||
} pipe_event_msg_t;
|
||||
|
||||
hcd_port_handle_t port_hdl = NULL;
|
||||
|
||||
// ---------------------------------------------------- Private --------------------------------------------------------
|
||||
|
||||
/**
|
||||
|
@ -52,7 +55,7 @@ static bool port_callback(hcd_port_handle_t port_hdl, hcd_port_event_t port_even
|
|||
//We store the port's queue handle in the port's context variable
|
||||
void *port_ctx = hcd_port_get_context(port_hdl);
|
||||
QueueHandle_t port_evt_queue = (QueueHandle_t)port_ctx;
|
||||
TEST_ASSERT(in_isr); //Current HCD implementation should never call a port callback in a task context
|
||||
TEST_ASSERT_TRUE(in_isr); //Current HCD implementation should never call a port callback in a task context
|
||||
port_event_msg_t msg = {
|
||||
.port_hdl = port_hdl,
|
||||
.port_event = port_event,
|
||||
|
@ -95,13 +98,14 @@ void test_hcd_expect_port_event(hcd_port_handle_t port_hdl, hcd_port_event_t exp
|
|||
{
|
||||
//Get the port event queue from the port's context variable
|
||||
QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, port_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(port_evt_queue);
|
||||
//Wait for port callback to send an event message
|
||||
port_event_msg_t msg;
|
||||
xQueueReceive(port_evt_queue, &msg, portMAX_DELAY);
|
||||
BaseType_t ret = xQueueReceive(port_evt_queue, &msg, pdMS_TO_TICKS(5000));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(pdPASS, ret, "Port event not generated on time");
|
||||
//Check the contents of that event message
|
||||
TEST_ASSERT_EQUAL(port_hdl, msg.port_hdl);
|
||||
TEST_ASSERT_EQUAL(expected_event, msg.port_event);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(expected_event, msg.port_event, "Unexpected event");
|
||||
printf("\t-> Port event\n");
|
||||
}
|
||||
|
||||
|
@ -109,20 +113,21 @@ void test_hcd_expect_pipe_event(hcd_pipe_handle_t pipe_hdl, hcd_pipe_event_t exp
|
|||
{
|
||||
//Get the pipe's event queue from the pipe's context variable
|
||||
QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, pipe_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(pipe_evt_queue);
|
||||
//Wait for pipe callback to send an event message
|
||||
pipe_event_msg_t msg;
|
||||
xQueueReceive(pipe_evt_queue, &msg, portMAX_DELAY);
|
||||
BaseType_t ret = xQueueReceive(pipe_evt_queue, &msg, pdMS_TO_TICKS(5000));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(pdPASS, ret, "Pipe event not generated on time");
|
||||
//Check the contents of that event message
|
||||
TEST_ASSERT_EQUAL(pipe_hdl, msg.pipe_hdl);
|
||||
TEST_ASSERT_EQUAL(expected_event, msg.pipe_event);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(expected_event, msg.pipe_event, "Unexpected event");
|
||||
}
|
||||
|
||||
int test_hcd_get_num_port_events(hcd_port_handle_t port_hdl)
|
||||
{
|
||||
//Get the port event queue from the port's context variable
|
||||
QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, port_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(port_evt_queue);
|
||||
return EVENT_QUEUE_LEN - uxQueueSpacesAvailable(port_evt_queue);
|
||||
}
|
||||
|
||||
|
@ -130,7 +135,7 @@ int test_hcd_get_num_pipe_events(hcd_pipe_handle_t pipe_hdl)
|
|||
{
|
||||
//Get the pipe's event queue from the pipe's context variable
|
||||
QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, pipe_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(pipe_evt_queue);
|
||||
return EVENT_QUEUE_LEN - uxQueueSpacesAvailable(pipe_evt_queue);
|
||||
}
|
||||
|
||||
|
@ -141,7 +146,7 @@ hcd_port_handle_t test_hcd_setup(void)
|
|||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Create a queue for port callback to queue up port events
|
||||
QueueHandle_t port_evt_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(port_event_msg_t));
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, port_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(port_evt_queue);
|
||||
//Install HCD
|
||||
hcd_config_t hcd_config = {
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
|
@ -156,7 +161,7 @@ hcd_port_handle_t test_hcd_setup(void)
|
|||
};
|
||||
hcd_port_handle_t port_hdl;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_port_init(PORT_NUM, &port_config, &port_hdl));
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, port_hdl);
|
||||
TEST_ASSERT_NOT_NULL(port_hdl);
|
||||
TEST_ASSERT_EQUAL(HCD_PORT_STATE_NOT_POWERED, hcd_port_get_state(port_hdl));
|
||||
test_usb_set_phy_state(false, 0); //Force disconnected state on PHY
|
||||
return port_hdl;
|
||||
|
@ -164,9 +169,12 @@ hcd_port_handle_t test_hcd_setup(void)
|
|||
|
||||
void test_hcd_teardown(hcd_port_handle_t port_hdl)
|
||||
{
|
||||
if (!port_hdl) {
|
||||
return; // In case of setup stage failure, don't run tear-down stage
|
||||
}
|
||||
//Get the queue handle from the port's context variable
|
||||
QueueHandle_t port_evt_queue = (QueueHandle_t)hcd_port_get_context(port_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, port_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(port_evt_queue);
|
||||
//Deinitialize a port
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_port_deinit(port_hdl));
|
||||
//Uninstall the HCD
|
||||
|
@ -226,7 +234,7 @@ hcd_pipe_handle_t test_hcd_pipe_alloc(hcd_port_handle_t port_hdl, const usb_ep_d
|
|||
{
|
||||
//Create a queue for pipe callback to queue up pipe events
|
||||
QueueHandle_t pipe_evt_queue = xQueueCreate(EVENT_QUEUE_LEN, sizeof(pipe_event_msg_t));
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, pipe_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(pipe_evt_queue);
|
||||
printf("Creating pipe\n");
|
||||
hcd_pipe_config_t pipe_config = {
|
||||
.callback = pipe_callback,
|
||||
|
@ -238,7 +246,7 @@ hcd_pipe_handle_t test_hcd_pipe_alloc(hcd_port_handle_t port_hdl, const usb_ep_d
|
|||
};
|
||||
hcd_pipe_handle_t pipe_hdl;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_alloc(port_hdl, &pipe_config, &pipe_hdl));
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, pipe_hdl);
|
||||
TEST_ASSERT_NOT_NULL(pipe_hdl);
|
||||
return pipe_hdl;
|
||||
}
|
||||
|
||||
|
@ -246,7 +254,7 @@ void test_hcd_pipe_free(hcd_pipe_handle_t pipe_hdl)
|
|||
{
|
||||
//Get the pipe's event queue from its context variable
|
||||
QueueHandle_t pipe_evt_queue = (QueueHandle_t)hcd_pipe_get_context(pipe_hdl);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, pipe_evt_queue);
|
||||
TEST_ASSERT_NOT_NULL(pipe_evt_queue);
|
||||
//Free the pipe and queue
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_free(pipe_hdl));
|
||||
vQueueDelete(pipe_evt_queue);
|
||||
|
@ -257,8 +265,8 @@ urb_t *test_hcd_alloc_urb(int num_isoc_packets, size_t data_buffer_size)
|
|||
//Allocate a URB and data buffer
|
||||
urb_t *urb = heap_caps_calloc(1, sizeof(urb_t) + (num_isoc_packets * sizeof(usb_isoc_packet_desc_t)), MALLOC_CAP_DEFAULT);
|
||||
uint8_t *data_buffer = heap_caps_malloc(data_buffer_size, MALLOC_CAP_DMA);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, urb);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, data_buffer);
|
||||
TEST_ASSERT_NOT_NULL(urb);
|
||||
TEST_ASSERT_NOT_NULL(data_buffer);
|
||||
//Initialize URB and underlying transfer structure. Need to cast to dummy due to const fields
|
||||
usb_transfer_dummy_t *transfer_dummy = (usb_transfer_dummy_t *)&urb->transfer;
|
||||
transfer_dummy->data_buffer = data_buffer;
|
||||
|
@ -286,7 +294,7 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe)
|
|||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb));
|
||||
test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
|
||||
//Update the MPS of the default pipe
|
||||
usb_device_desc_t *device_desc = (usb_device_desc_t *)(urb->transfer.data_buffer + sizeof(usb_setup_packet_t));
|
||||
|
@ -298,7 +306,7 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe)
|
|||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb));
|
||||
test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
|
||||
//Update address of default pipe
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_update_dev_addr(default_pipe, ENUM_ADDR));
|
||||
|
@ -309,7 +317,7 @@ uint8_t test_hcd_enum_device(hcd_pipe_handle_t default_pipe)
|
|||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb));
|
||||
test_hcd_expect_pipe_event(default_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
TEST_ASSERT_EQUAL(urb, hcd_urb_dequeue(default_pipe));
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
|
||||
//Free URB
|
||||
test_hcd_free_urb(urb);
|
|
@ -10,6 +10,8 @@
|
|||
#include "usb_private.h"
|
||||
#include "usb/usb_types_ch9.h"
|
||||
|
||||
extern hcd_port_handle_t port_hdl;
|
||||
|
||||
#define URB_CONTEXT_VAL ((void *)0xDEADBEEF)
|
||||
|
||||
// ------------------------------------------------- HCD Event Test ----------------------------------------------------
|
|
@ -1,22 +1,13 @@
|
|||
// Copyright 2015-2020 Espressif Systems (Shanghai) PTE LTD
|
||||
//
|
||||
// Licensed under the Apache License, Version 2.0 (the "License");
|
||||
// you may not use this file except in compliance with the License.
|
||||
// You may obtain a copy of the License at
|
||||
|
||||
// http://www.apache.org/licenses/LICENSE-2.0
|
||||
//
|
||||
// Unless required by applicable law or agreed to in writing, software
|
||||
// distributed under the License is distributed on an "AS IS" BASIS,
|
||||
// WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||
// See the License for the specific language governing permissions and
|
||||
// limitations under the License.
|
||||
/*
|
||||
* SPDX-FileCopyrightText: 2021-2022 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: Apache-2.0
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
#define TEST_DEV_ADDR 0
|
||||
|
@ -42,9 +33,8 @@ Procedure:
|
|||
- Expect URB to be USB_TRANSFER_STATUS_CANCELED or USB_TRANSFER_STATUS_COMPLETED
|
||||
- Teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD control pipe URBs", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD control pipe URBs", "[ctrl][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -72,7 +62,7 @@ TEST_CASE("Test HCD control pipe URBs", "[hcd][ignore]")
|
|||
for (int i = 0; i < NUM_URBS; i++) {
|
||||
urb_t *urb = hcd_urb_dequeue(default_pipe);
|
||||
TEST_ASSERT_EQUAL(urb_list[i], urb);
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context);
|
||||
//We must have transmitted at least the setup packet, but device may return less than bytes requested
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes);
|
||||
|
@ -115,12 +105,13 @@ TEST_CASE("Test HCD control pipe URBs", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
Test HCD control pipe STALL condition, abort, and clear
|
||||
|
||||
@todo this test is not passing with low-speed: test with bus analyzer
|
||||
|
||||
Purpose:
|
||||
- Test that a control pipe can react to a STALL (i.e., a HCD_PIPE_EVENT_ERROR_STALL event)
|
||||
- The HCD_PIPE_CMD_FLUSH can retire all URBs
|
||||
|
@ -137,9 +128,8 @@ Procedure:
|
|||
- Dequeue URBs
|
||||
- Teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD control pipe STALL", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD control pipe STALL", "[ctrl][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -205,7 +195,7 @@ TEST_CASE("Test HCD control pipe STALL", "[hcd][ignore]")
|
|||
//expect_pipe_event(pipe_evt_queue, default_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
urb_t *urb = hcd_urb_dequeue(default_pipe);
|
||||
TEST_ASSERT_EQUAL(urb_list[i], urb);
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context);
|
||||
//We must have transmitted at least the setup packet, but device may return less than bytes requested
|
||||
TEST_ASSERT_GREATER_OR_EQUAL(sizeof(usb_setup_packet_t), urb->transfer.actual_num_bytes);
|
||||
|
@ -222,7 +212,6 @@ TEST_CASE("Test HCD control pipe STALL", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -243,9 +232,8 @@ Procedure:
|
|||
- Check that all URBs have completed successfully
|
||||
- Dequeue URBs and teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD control pipe runtime halt and clear", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD control pipe runtime halt and clear", "[ctrl][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -279,7 +267,7 @@ TEST_CASE("Test HCD control pipe runtime halt and clear", "[hcd][ignore]")
|
|||
//Wait for each URB to be done, dequeue, and check results
|
||||
for (int i = 0; i < NUM_URBS; i++) {
|
||||
urb_t *urb = hcd_urb_dequeue(default_pipe);
|
||||
TEST_ASSERT_EQUAL(urb_list[i], urb);
|
||||
TEST_ASSERT_EQUAL_PTR(urb_list[i], urb);
|
||||
TEST_ASSERT(urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED || urb->transfer.status == USB_TRANSFER_STATUS_CANCELED);
|
||||
if (urb->transfer.status == USB_TRANSFER_STATUS_COMPLETED) {
|
||||
//We must have transmitted at least the setup packet, but device may return less than bytes requested
|
||||
|
@ -302,5 +290,4 @@ TEST_CASE("Test HCD control pipe runtime halt and clear", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
|
@ -8,8 +8,8 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "test_usb_mock_hid.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
@ -36,14 +36,13 @@ Note: Some mice will NAK until it is moved, so try moving the mouse around if th
|
|||
|
||||
#define TEST_HID_DEV_SPEED USB_SPEED_LOW
|
||||
#define NUM_URBS 3
|
||||
#define URB_DATA_BUFF_SIZE 4 //MPS is 4
|
||||
#define URB_DATA_BUFF_SIZE MOCK_HID_MOUSE_INTR_IN_MPS
|
||||
#define NUM_URB_ITERS (NUM_URBS * 100)
|
||||
|
||||
TEST_CASE("Test HCD interrupt pipe URBs", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD interrupt pipe URBs", "[intr][low_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
TEST_ASSERT_EQUAL(TEST_HID_DEV_SPEED, TEST_HID_DEV_SPEED);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(TEST_HID_DEV_SPEED, port_speed, "Connected device is not Low Speed!");
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
hcd_pipe_handle_t default_pipe = test_hcd_pipe_alloc(port_hdl, NULL, 0, port_speed); //Create a default pipe (using a NULL EP descriptor)
|
||||
|
@ -68,7 +67,7 @@ TEST_CASE("Test HCD interrupt pipe URBs", "[hcd][ignore]")
|
|||
test_hcd_expect_pipe_event(intr_pipe, HCD_PIPE_EVENT_URB_DONE);
|
||||
//Dequeue the URB and check results
|
||||
urb_t *urb = hcd_urb_dequeue(intr_pipe);
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context);
|
||||
mock_hid_process_report((mock_hid_mouse_report_t *)urb->transfer.data_buffer, iter_count);
|
||||
//Requeue URB
|
||||
|
@ -85,5 +84,4 @@ TEST_CASE("Test HCD interrupt pipe URBs", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Clearnup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
|
@ -9,8 +9,7 @@
|
|||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
|
@ -40,9 +39,8 @@ Procedure:
|
|||
- Teardown
|
||||
*/
|
||||
|
||||
TEST_CASE("Test HCD isochronous pipe URBs", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD isochronous pipe URBs", "[isoc][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
//The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX));
|
||||
|
@ -82,9 +80,9 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[hcd][ignore]")
|
|||
TEST_ASSERT_EQUAL(URB_CONTEXT_VAL, urb->transfer.context);
|
||||
//Overall URB status and overall number of bytes
|
||||
TEST_ASSERT_EQUAL(URB_DATA_BUFF_SIZE, urb->transfer.actual_num_bytes);
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.status, "Transfer NOT completed");
|
||||
for (int pkt_idx = 0; pkt_idx < NUM_PACKETS_PER_URB; pkt_idx++) {
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, urb->transfer.isoc_packet_desc[pkt_idx].status, "Transfer NOT completed");
|
||||
}
|
||||
}
|
||||
//Free URB list and pipe
|
||||
|
@ -95,7 +93,6 @@ TEST_CASE("Test HCD isochronous pipe URBs", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -122,9 +119,8 @@ Procedure:
|
|||
- Free both pipes
|
||||
- Teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD isochronous pipe sudden disconnect", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD isochronous pipe sudden disconnect", "[isoc][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
//The MPS of the ISOC OUT pipe is quite large, so we need to bias the FIFO sizing
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_port_set_fifo_bias(port_hdl, HCD_PORT_FIFO_BIAS_PTX));
|
||||
|
@ -189,6 +185,4 @@ TEST_CASE("Test HCD isochronous pipe sudden disconnect", "[hcd][ignore]")
|
|||
}
|
||||
test_hcd_pipe_free(isoc_out_pipe);
|
||||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
|
@ -9,7 +9,6 @@
|
|||
#include "freertos/semphr.h"
|
||||
#include "unity.h"
|
||||
#include "esp_rom_sys.h"
|
||||
#include "test_utils.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_hcd_common.h"
|
||||
|
||||
|
@ -42,9 +41,8 @@ Procedure:
|
|||
- Teardown port and HCD
|
||||
*/
|
||||
|
||||
TEST_CASE("Test HCD port sudden disconnect", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD port sudden disconnect", "[port][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -110,7 +108,6 @@ TEST_CASE("Test HCD port sudden disconnect", "[hcd][ignore]")
|
|||
//Recovered port should be able to connect and disconnect again
|
||||
test_hcd_wait_for_conn(port_hdl);
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -133,9 +130,8 @@ Procedure:
|
|||
- Cleanup default pipe
|
||||
- Trigger disconnection and teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD port suspend and resume", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD port suspend and resume", "[port][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -169,7 +165,6 @@ TEST_CASE("Test HCD port suspend and resume", "[hcd][ignore]")
|
|||
test_hcd_pipe_free(default_pipe);
|
||||
//Cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, false);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -189,9 +184,8 @@ Procedure:
|
|||
- Check that a disconnection still works after disable
|
||||
- Teardown
|
||||
*/
|
||||
TEST_CASE("Test HCD port disable", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD port disable", "[port][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
usb_speed_t port_speed = test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
|
@ -210,15 +204,15 @@ TEST_CASE("Test HCD port disable", "[hcd][ignore]")
|
|||
printf("Enqueuing URBs\n");
|
||||
for (int i = 0; i < NUM_URBS; i++) {
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_urb_enqueue(default_pipe, urb_list[i]));
|
||||
//Add a short delay to let the transfers run for a bit
|
||||
esp_rom_delay_us(POST_ENQUEUE_DELAY_US);
|
||||
}
|
||||
//Add a short delay to let the transfers run for a bit
|
||||
esp_rom_delay_us(POST_ENQUEUE_DELAY_US);
|
||||
|
||||
//Halt the default pipe before suspending
|
||||
TEST_ASSERT_EQUAL(HCD_PIPE_STATE_ACTIVE, hcd_pipe_get_state(default_pipe));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_pipe_command(default_pipe, HCD_PIPE_CMD_HALT));
|
||||
TEST_ASSERT_EQUAL(HCD_PIPE_STATE_HALTED, hcd_pipe_get_state(default_pipe));
|
||||
|
||||
|
||||
//Check that port can be disabled
|
||||
TEST_ASSERT_EQUAL(ESP_OK, hcd_port_command(port_hdl, HCD_PORT_CMD_DISABLE));
|
||||
TEST_ASSERT_EQUAL(HCD_PORT_STATE_DISABLED, hcd_port_get_state(port_hdl));
|
||||
|
@ -252,7 +246,6 @@ TEST_CASE("Test HCD port disable", "[hcd][ignore]")
|
|||
|
||||
//Trigger a disconnection and cleanup
|
||||
test_hcd_wait_for_disconn(port_hdl, true);
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -279,17 +272,16 @@ static void concurrent_task(void *arg)
|
|||
vTaskDelay(portMAX_DELAY); //Block forever and wait to be deleted
|
||||
}
|
||||
|
||||
TEST_CASE("Test HCD port command bailout", "[hcd][ignore]")
|
||||
TEST_CASE("Test HCD port command bailout", "[port][low_speed][full_speed]")
|
||||
{
|
||||
hcd_port_handle_t port_hdl = test_hcd_setup(); //Setup the HCD and port
|
||||
test_hcd_wait_for_conn(port_hdl); //Trigger a connection
|
||||
vTaskDelay(pdMS_TO_TICKS(100)); //Short delay send of SOF (for FS) or EOPs (for LS)
|
||||
|
||||
//Create task to run port commands concurrently
|
||||
SemaphoreHandle_t sync_sem = xSemaphoreCreateBinary();
|
||||
TaskHandle_t task_handle;
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, sync_sem);
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(concurrent_task, "tsk", 4096, (void *) sync_sem, UNITY_FREERTOS_PRIORITY + 1, &task_handle, 0));
|
||||
TEST_ASSERT_NOT_NULL(sync_sem);
|
||||
TEST_ASSERT_EQUAL(pdTRUE, xTaskCreatePinnedToCore(concurrent_task, "tsk", 4096, (void *) sync_sem, uxTaskPriorityGet(NULL) + 1, &task_handle, 0));
|
||||
|
||||
//Suspend the device
|
||||
printf("Suspending\n");
|
||||
|
@ -310,6 +302,4 @@ TEST_CASE("Test HCD port command bailout", "[hcd][ignore]")
|
|||
vTaskDelay(pdMS_TO_TICKS(10)); //Short delay for concurrent task finish running
|
||||
vTaskDelete(task_handle);
|
||||
vSemaphoreDelete(sync_sem);
|
||||
|
||||
test_hcd_teardown(port_hdl);
|
||||
}
|
|
@ -6,7 +6,6 @@
|
|||
|
||||
#include <stdio.h>
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
#include "usb/usb_host.h"
|
||||
|
||||
/*
|
||||
|
@ -347,11 +346,11 @@ static void test_walk_desc(const usb_config_desc_t *config_desc)
|
|||
const usb_standard_desc_t *cur_desc = (usb_standard_desc_t *)config_desc;
|
||||
for (int i = 0; i < TEST_NUM_INTF_DESC; i++) {
|
||||
cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, cur_desc);
|
||||
TEST_ASSERT_NOT_NULL(cur_desc);
|
||||
}
|
||||
//Attempting to look for another interface descriptor should result in NULL
|
||||
cur_desc = usb_parse_next_descriptor_of_type(cur_desc, config_desc->wTotalLength, USB_B_DESCRIPTOR_TYPE_INTERFACE, &offset);
|
||||
TEST_ASSERT_EQUAL(NULL, cur_desc);
|
||||
TEST_ASSERT_NULL(cur_desc);
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -373,37 +372,37 @@ static void test_parse_intf_and_ep(const usb_config_desc_t *config_desc)
|
|||
|
||||
//Get bInterfaceNumber 0 (index 0)
|
||||
const usb_intf_desc_t *intf_desc = usb_parse_interface_descriptor(config_desc, 0, 0, &offset_intf);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
|
||||
TEST_ASSERT_NOT_NULL(intf_desc);
|
||||
//Should only have one endpoint
|
||||
int offset_ep = offset_intf;
|
||||
const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NOT_NULL(ep_desc);
|
||||
TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
|
||||
offset_ep = offset_intf;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
|
||||
TEST_ASSERT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NULL(ep_desc);
|
||||
|
||||
//Get bInterfaceNumber 1 alternate setting 0
|
||||
offset_intf = 0;
|
||||
intf_desc = usb_parse_interface_descriptor(config_desc, 1, 0, &offset_intf);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
|
||||
TEST_ASSERT_NOT_NULL(intf_desc);
|
||||
//Should have no endpoints
|
||||
offset_ep = offset_intf;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
|
||||
TEST_ASSERT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NULL(ep_desc);
|
||||
|
||||
//Get bInterfaceNumber 1 alternate setting 1
|
||||
offset_intf = 0;
|
||||
intf_desc = usb_parse_interface_descriptor(config_desc, 1, 1, &offset_intf);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, intf_desc);
|
||||
TEST_ASSERT_NOT_NULL(intf_desc);
|
||||
//Should only have one endpoint
|
||||
offset_ep = offset_intf;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 0, config_desc->wTotalLength, &offset_ep);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NOT_NULL(ep_desc);
|
||||
TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
|
||||
offset_ep = offset_intf;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_index(intf_desc, 1, config_desc->wTotalLength, &offset_ep);
|
||||
TEST_ASSERT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NULL(ep_desc);
|
||||
}
|
||||
|
||||
static void test_parse_ep_by_address(const usb_config_desc_t *config_desc)
|
||||
|
@ -411,25 +410,25 @@ static void test_parse_ep_by_address(const usb_config_desc_t *config_desc)
|
|||
int offset_ep = 0;
|
||||
//Get bInterface 0 bAlternateSetting 0 EP 0x83
|
||||
const usb_ep_desc_t *ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 0, 0, 0x83, &offset_ep);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NOT_NULL(ep_desc);
|
||||
TEST_ASSERT_EQUAL(0x83, ep_desc->bEndpointAddress);
|
||||
//Getting same EP address under different interface should return NULL
|
||||
offset_ep = 0;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x83, &offset_ep);
|
||||
TEST_ASSERT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NULL(ep_desc);
|
||||
|
||||
//Get bInterface 1 bAlternateSetting 1 EP 0x81
|
||||
offset_ep = 0;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 1, 0x81, &offset_ep);
|
||||
TEST_ASSERT_NOT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NOT_NULL(ep_desc);
|
||||
TEST_ASSERT_EQUAL(0x81, ep_desc->bEndpointAddress);
|
||||
//Getting same EP address under different interface should return NULL
|
||||
offset_ep = 0;
|
||||
ep_desc = usb_parse_endpoint_descriptor_by_address(config_desc, 1, 0, 0x81, &offset_ep);
|
||||
TEST_ASSERT_EQUAL(NULL, ep_desc);
|
||||
TEST_ASSERT_NULL(ep_desc);
|
||||
}
|
||||
|
||||
TEST_CASE("Test USB Helpers descriptor parsing", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Helpers descriptor parsing", "[helpers][full_speed]")
|
||||
{
|
||||
const usb_config_desc_t *config_desc = (const usb_config_desc_t *)config_desc_bytes;
|
||||
test_walk_desc(config_desc);
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.usb_host_flash_disk
|
||||
def test_usb_hcd(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('[full_speed]')
|
||||
dut.expect_unity_test_output()
|
|
@ -0,0 +1,8 @@
|
|||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
# CONFIG_ESP_TASK_WDT_INIT is not set
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
# CONFIG_UNITY_ENABLE_FLOAT is not set
|
||||
# CONFIG_UNITY_ENABLE_DOUBLE is not set
|
||||
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y
|
|
@ -0,0 +1,6 @@
|
|||
# This is the project CMakeLists.txt file for the test subproject
|
||||
cmake_minimum_required(VERSION 3.16)
|
||||
|
||||
include($ENV{IDF_PATH}/tools/cmake/project.cmake)
|
||||
set(EXTRA_COMPONENT_DIRS "../common")
|
||||
project(test_app_usb_host)
|
|
@ -0,0 +1,11 @@
|
|||
| Supported Targets | ESP32-S2 | ESP32-S3 |
|
||||
| ----------------- | -------- | -------- |
|
||||
|
||||
# USB: Host test application
|
||||
|
||||
There are two sets of tests in this application:
|
||||
1. Low-speed: Expects low-speed USB mouse with interrupt endpoint to be connected
|
||||
2. Full-speed: Expects full-speed USB flash disk with 2 bulk endpoints to be connected
|
||||
|
||||
For running these tests locally, you will have to update device definitions (VID, PID, ...) in [test_usb_mock_msc.h](../common/test_usb_mock_msc.h) and [test_usb_mock_hid.h](../common/test_usb_mock_hid.h).
|
||||
|
|
@ -0,0 +1,6 @@
|
|||
# In order for the cases defined by `TEST_CASE` to be linked into the final elf,
|
||||
# the component can be registered as WHOLE_ARCHIVE
|
||||
idf_component_register(SRC_DIRS "."
|
||||
PRIV_INCLUDE_DIRS "."
|
||||
REQUIRES usb unity common
|
||||
WHOLE_ARCHIVE)
|
|
@ -14,7 +14,6 @@
|
|||
#include "ctrl_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
/*
|
||||
Implementation of a control transfer client used for USB Host Tests.
|
||||
|
@ -63,7 +62,7 @@ static void ctrl_transfer_cb(usb_transfer_t *transfer)
|
|||
{
|
||||
ctrl_client_obj_t *ctrl_obj = (ctrl_client_obj_t *)transfer->context;
|
||||
//Check the completed control transfer
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(ctrl_obj->config_desc_cached->wTotalLength, transfer->actual_num_bytes - sizeof(usb_setup_packet_t));
|
||||
ctrl_obj->num_xfer_done++;
|
||||
if (ctrl_obj->num_xfer_sent < ctrl_obj->test_param.num_ctrl_xfer_to_send) {
|
||||
|
@ -134,7 +133,7 @@ void ctrl_client_async_seq_task(void *arg)
|
|||
case TEST_STAGE_DEV_OPEN: {
|
||||
ESP_LOGD(CTRL_CLIENT_TAG, "Open");
|
||||
//Open the device
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr_to_open, &ctrl_obj.dev_hdl));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(ESP_OK, usb_host_device_open(ctrl_obj.client_hdl, ctrl_obj.dev_addr_to_open, &ctrl_obj.dev_hdl), "Failed to open the device");
|
||||
//Target our transfers to the device
|
||||
for (int i = 0; i < NUM_TRANSFER_OBJ; i++) {
|
||||
ctrl_xfer[i]->device_handle = ctrl_obj.dev_hdl;
|
||||
|
@ -169,6 +168,7 @@ void ctrl_client_async_seq_task(void *arg)
|
|||
}
|
||||
case TEST_STAGE_DEV_CLOSE: {
|
||||
ESP_LOGD(CTRL_CLIENT_TAG, "Close");
|
||||
vTaskDelay(10); // Give USB Host Lib some time to process all trnsfers
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(ctrl_obj.client_hdl, ctrl_obj.dev_hdl));
|
||||
exit_loop = true;
|
||||
break;
|
|
@ -12,12 +12,11 @@
|
|||
#include "freertos/task.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "msc_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
/*
|
||||
Implementation of an asynchronous MSC client used for USB Host disconnection test.
|
||||
|
@ -29,7 +28,7 @@ Implementation of an asynchronous MSC client used for USB Host disconnection tes
|
|||
- Trigger a single MSC SCSI transfer
|
||||
- Split the data stage into multiple transfers (so that the endpoint multiple queued up transfers)
|
||||
- Cause a disconnection mid-way through the data stage
|
||||
- All of the transfers should be automatically deqeueud
|
||||
- All of the transfers should be automatically dequeued
|
||||
- Then a USB_HOST_CLIENT_EVENT_DEV_GONE event should occur afterwards
|
||||
- Free transfer objects
|
||||
- Close device
|
||||
|
@ -62,7 +61,7 @@ static void msc_reset_cbw_transfer_cb(usb_transfer_t *transfer)
|
|||
{
|
||||
msc_client_obj_t *msc_obj = (msc_client_obj_t *)transfer->context;
|
||||
//We expect the reset and CBW transfers to complete with no issues
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes);
|
||||
switch (msc_obj->cur_stage) {
|
||||
case TEST_STAGE_MSC_RESET:
|
|
@ -12,12 +12,11 @@
|
|||
#include "freertos/task.h"
|
||||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "msc_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
/*
|
||||
Implementation of an asynchronous MSC client used for USB Host enumeration test.
|
||||
|
@ -120,10 +119,10 @@ void msc_client_async_enum_task(void *arg)
|
|||
case TEST_STAGE_CHECK_DEV_DESC: {
|
||||
//Check the device descriptor
|
||||
const usb_device_desc_t *device_desc;
|
||||
const usb_device_desc_t *device_desc_ref = (const usb_device_desc_t *)mock_msc_scsi_dev_desc;
|
||||
const usb_device_desc_t *device_desc_ref = &mock_msc_scsi_dev_desc;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_device_descriptor(msc_obj.dev_hdl, &device_desc));
|
||||
TEST_ASSERT_EQUAL(device_desc_ref->bLength, device_desc->bLength);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(device_desc_ref, device_desc, device_desc_ref->bLength));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(device_desc_ref, device_desc, device_desc_ref->bLength, "Device descriptors do not match.");
|
||||
msc_obj.next_stage = TEST_STAGE_CHECK_CONFIG_DESC;
|
||||
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_CONFIG_DESC
|
||||
break;
|
||||
|
@ -134,8 +133,8 @@ void msc_client_async_enum_task(void *arg)
|
|||
const usb_config_desc_t *config_desc;
|
||||
const usb_config_desc_t *config_desc_ref = (const usb_config_desc_t *)mock_msc_scsi_config_desc;
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_get_active_config_descriptor(msc_obj.dev_hdl, &config_desc));
|
||||
TEST_ASSERT_EQUAL(config_desc_ref->wTotalLength, config_desc->wTotalLength);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(config_desc_ref, config_desc, config_desc_ref->wTotalLength));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(config_desc_ref->wTotalLength, config_desc->wTotalLength, "Incorrent length of CFG descriptor");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(config_desc_ref, config_desc, config_desc_ref->wTotalLength, "Configuration descriptors do not match");
|
||||
msc_obj.next_stage = TEST_STAGE_CHECK_STR_DESC;
|
||||
skip_event_handling = true; //Need to execute TEST_STAGE_CHECK_STR_DESC
|
||||
break;
|
||||
|
@ -150,9 +149,9 @@ void msc_client_async_enum_task(void *arg)
|
|||
TEST_ASSERT_EQUAL(manu_str_desc_ref->bLength, dev_info.str_desc_manufacturer->bLength);
|
||||
TEST_ASSERT_EQUAL(product_str_desc_ref->bLength, dev_info.str_desc_product->bLength);
|
||||
TEST_ASSERT_EQUAL(ser_num_str_desc_ref->bLength, dev_info.str_desc_serial_num->bLength);
|
||||
TEST_ASSERT_EQUAL(0, memcmp(manu_str_desc_ref, dev_info.str_desc_manufacturer , manu_str_desc_ref->bLength));
|
||||
TEST_ASSERT_EQUAL(0, memcmp(product_str_desc_ref, dev_info.str_desc_product , manu_str_desc_ref->bLength));
|
||||
TEST_ASSERT_EQUAL(0, memcmp(ser_num_str_desc_ref, dev_info.str_desc_serial_num , manu_str_desc_ref->bLength));
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(manu_str_desc_ref, dev_info.str_desc_manufacturer , manu_str_desc_ref->bLength, "Manufacturer string descriptors do not match.");
|
||||
TEST_ASSERT_EQUAL_MEMORY_MESSAGE(product_str_desc_ref, dev_info.str_desc_product , manu_str_desc_ref->bLength, "Product string descriptors do not match.");
|
||||
//TEST_ASSERT_EQUAL_MEMORY_MESSAGE(ser_num_str_desc_ref, dev_info.str_desc_serial_num , manu_str_desc_ref->bLength, "Serial number string descriptors do not match.");
|
||||
//Get dev info and compare
|
||||
msc_obj.next_stage = TEST_STAGE_DEV_CLOSE;
|
||||
skip_event_handling = true; //Need to execute TEST_STAGE_DEV_CLOSE
|
|
@ -13,11 +13,10 @@
|
|||
#include "esp_err.h"
|
||||
#include "esp_log.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "msc_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
/*
|
||||
Implementation of an MSC client used for USB Host Tests
|
||||
|
@ -62,29 +61,29 @@ static void msc_transfer_cb(usb_transfer_t *transfer)
|
|||
switch (msc_obj->cur_stage) {
|
||||
case TEST_STAGE_MSC_RESET: {
|
||||
//Check MSC SCSI interface reset
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(transfer->num_bytes, transfer->actual_num_bytes);
|
||||
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
|
||||
break;
|
||||
}
|
||||
case TEST_STAGE_MSC_CBW: {
|
||||
//Check MSC SCSI CBW transfer
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(sizeof(mock_msc_bulk_cbw_t), transfer->actual_num_bytes);
|
||||
msc_obj->next_stage = TEST_STAGE_MSC_DATA;
|
||||
break;
|
||||
}
|
||||
case TEST_STAGE_MSC_DATA: {
|
||||
//Check MSC SCSI data IN transfer
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_EQUAL(MOCK_MSC_SCSI_SECTOR_SIZE * msc_obj->test_param.num_sectors_per_xfer, transfer->actual_num_bytes);
|
||||
msc_obj->next_stage = TEST_STAGE_MSC_CSW;
|
||||
break;
|
||||
}
|
||||
case TEST_STAGE_MSC_CSW: {
|
||||
//Check MSC SCSI CSW transfer
|
||||
TEST_ASSERT_EQUAL(USB_TRANSFER_STATUS_COMPLETED, transfer->status);
|
||||
TEST_ASSERT_EQUAL(true, mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)transfer->data_buffer, msc_obj->test_param.msc_scsi_xfer_tag));
|
||||
TEST_ASSERT_EQUAL_MESSAGE(USB_TRANSFER_STATUS_COMPLETED, transfer->status, "Transfer NOT completed");
|
||||
TEST_ASSERT_TRUE(mock_msc_scsi_check_csw((mock_msc_bulk_csw_t *)transfer->data_buffer, msc_obj->test_param.msc_scsi_xfer_tag));
|
||||
msc_obj->num_sectors_read += msc_obj->test_param.num_sectors_per_xfer;
|
||||
if (msc_obj->num_sectors_read < msc_obj->test_param.num_sectors_to_read) {
|
||||
msc_obj->next_stage = TEST_STAGE_MSC_CBW;
|
|
@ -0,0 +1,59 @@
|
|||
/*
|
||||
* SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*
|
||||
* SPDX-License-Identifier: CC0-1.0
|
||||
*/
|
||||
|
||||
#include "unity.h"
|
||||
#include "unity_test_runner.h"
|
||||
#include "unity_test_utils_memory.h"
|
||||
|
||||
#include "freertos/FreeRTOS.h"
|
||||
#include "freertos/task.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "usb/usb_host.h"
|
||||
|
||||
void setUp(void)
|
||||
{
|
||||
mock_msc_scsi_init_reference_descriptors();
|
||||
unity_utils_record_free_mem();
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("USB Host installed\n");
|
||||
}
|
||||
|
||||
void tearDown(void)
|
||||
{
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
unity_utils_evaluate_leaks();
|
||||
}
|
||||
|
||||
void app_main(void)
|
||||
{
|
||||
// ____ ___ ___________________ __ __
|
||||
// | | \/ _____/\______ \ _/ |_ ____ _______/ |_
|
||||
// | | /\_____ \ | | _/ \ __\/ __ \ / ___/\ __\.
|
||||
// | | / / \ | | \ | | \ ___/ \___ \ | |
|
||||
// |______/ /_______ / |______ / |__| \___ >____ > |__|
|
||||
// \/ \/ \/ \/
|
||||
printf(" ____ ___ ___________________ __ __ \r\n");
|
||||
printf("| | \\/ _____/\\______ \\ _/ |_ ____ _______/ |_ \r\n");
|
||||
printf("| | /\\_____ \\ | | _/ \\ __\\/ __ \\ / ___/\\ __\\\r\n");
|
||||
printf("| | / / \\ | | \\ | | \\ ___/ \\___ \\ | | \r\n");
|
||||
printf("|______/ /_______ / |______ / |__| \\___ >____ > |__| \r\n");
|
||||
printf(" \\/ \\/ \\/ \\/ \r\n");
|
||||
|
||||
unity_utils_setup_heap_record(80);
|
||||
unity_utils_set_leak_level(128);
|
||||
unity_run_menu();
|
||||
}
|
|
@ -11,12 +11,11 @@
|
|||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "msc_client.h"
|
||||
#include "ctrl_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
#define TEST_MSC_NUM_SECTORS_TOTAL 10
|
||||
#define TEST_MSC_NUM_SECTORS_PER_XFER 2
|
||||
|
@ -45,17 +44,8 @@ Procedure:
|
|||
- Uninstall USB Host Library
|
||||
*/
|
||||
|
||||
TEST_CASE("Test USB Host async client (single client)", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host async client (single client)", "[usb_host][full_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
//Create task to run client that communicates with MSC SCSI interface
|
||||
msc_client_test_param_t params = {
|
||||
.num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL,
|
||||
|
@ -66,6 +56,7 @@ TEST_CASE("Test USB Host async client (single client)", "[usb_host][ignore]")
|
|||
};
|
||||
TaskHandle_t task_hdl;
|
||||
xTaskCreatePinnedToCore(msc_client_async_seq_task, "async", 4096, (void *)¶ms, 2, &task_hdl, 0);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(task_hdl, "Failed to create async task");
|
||||
//Start the task
|
||||
xTaskNotifyGive(task_hdl);
|
||||
|
||||
|
@ -81,12 +72,6 @@ TEST_CASE("Test USB Host async client (single client)", "[usb_host][ignore]")
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -109,17 +94,8 @@ Procedure:
|
|||
- Free all devices
|
||||
- Uninstall USB Host Library
|
||||
*/
|
||||
TEST_CASE("Test USB Host async client (multi client)", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host async client (multi client)", "[usb_host][full_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
//Create task to run the MSC client
|
||||
msc_client_test_param_t msc_params = {
|
||||
.num_sectors_to_read = TEST_MSC_NUM_SECTORS_TOTAL,
|
||||
|
@ -130,6 +106,7 @@ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][ignore]")
|
|||
};
|
||||
TaskHandle_t msc_task_hdl;
|
||||
xTaskCreatePinnedToCore(msc_client_async_seq_task, "msc", 4096, (void *)&msc_params, 2, &msc_task_hdl, 0);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(msc_task_hdl, "Failed to create MSC task");
|
||||
|
||||
//Create task a control transfer client
|
||||
ctrl_client_test_param_t ctrl_params = {
|
||||
|
@ -139,6 +116,7 @@ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][ignore]")
|
|||
};
|
||||
TaskHandle_t ctrl_task_hdl;
|
||||
xTaskCreatePinnedToCore(ctrl_client_async_seq_task, "ctrl", 4096, (void *)&ctrl_params, 2, &ctrl_task_hdl, 0);
|
||||
TEST_ASSERT_NOT_NULL_MESSAGE(ctrl_task_hdl, "Failed to create CTRL task");
|
||||
|
||||
//Start both tasks
|
||||
xTaskNotifyGive(msc_task_hdl);
|
||||
|
@ -156,12 +134,6 @@ TEST_CASE("Test USB Host async client (multi client)", "[usb_host][ignore]")
|
|||
break;
|
||||
}
|
||||
}
|
||||
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -214,18 +186,8 @@ static void test_async_client_cb(const usb_host_client_event_msg_t *event_msg, v
|
|||
}
|
||||
}
|
||||
|
||||
TEST_CASE("Test USB Host async API", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host async API", "[usb_host][full_speed][low_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
//Register two clients
|
||||
client_test_stage_t client0_stage = CLIENT_TEST_STAGE_NONE;
|
||||
client_test_stage_t client1_stage = CLIENT_TEST_STAGE_NONE;
|
||||
|
@ -249,16 +211,17 @@ TEST_CASE("Test USB Host async API", "[usb_host][ignore]")
|
|||
usb_host_lib_handle_events(0, NULL);
|
||||
usb_host_client_handle_events(client0_hdl, 0);
|
||||
usb_host_client_handle_events(client1_hdl, 0);
|
||||
vTaskDelay(10);
|
||||
vTaskDelay(pdMS_TO_TICKS(10));
|
||||
}
|
||||
|
||||
//Check that both clients can open the device
|
||||
TEST_ASSERT_NOT_EQUAL(0, dev_addr);
|
||||
usb_device_handle_t client0_dev_hdl;
|
||||
usb_device_handle_t client1_dev_hdl;
|
||||
printf("Opening device\n");
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, dev_addr, &client0_dev_hdl));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_open(client1_hdl, dev_addr, &client1_dev_hdl));
|
||||
TEST_ASSERT_EQUAL(client0_dev_hdl, client1_dev_hdl); //Check that its the same device
|
||||
TEST_ASSERT_EQUAL_PTR(client0_dev_hdl, client1_dev_hdl); //Check that its the same device
|
||||
//Check that a client cannot open a non-existent device
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, 0, &client0_dev_hdl));
|
||||
|
||||
|
@ -266,12 +229,14 @@ TEST_CASE("Test USB Host async API", "[usb_host][ignore]")
|
|||
usb_device_handle_t dummy_dev_hdl;
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client0_hdl, dev_addr, &dummy_dev_hdl));
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_device_open(client1_hdl, dev_addr, &dummy_dev_hdl));
|
||||
printf("Claiming interface\n");
|
||||
//Check that both clients cannot claim the same interface
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client1_hdl, client1_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
|
||||
//Check that client0 cannot claim the same interface multiple times
|
||||
TEST_ASSERT_NOT_EQUAL(ESP_OK, usb_host_interface_claim(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER, MOCK_MSC_SCSI_INTF_ALT_SETTING));
|
||||
|
||||
printf("Releasing interface\n");
|
||||
//Check that client0 can release the interface
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_interface_release(client0_hdl, client0_dev_hdl, MOCK_MSC_SCSI_INTF_NUMBER));
|
||||
//Check that client0 cannot release interface it has not claimed
|
||||
|
@ -285,6 +250,7 @@ TEST_CASE("Test USB Host async API", "[usb_host][ignore]")
|
|||
usb_host_client_handle_events(client1_hdl, 0);
|
||||
vTaskDelay(10);
|
||||
}
|
||||
printf("Closing device\n");
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(client0_hdl, client0_dev_hdl));
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_device_close(client1_hdl, client1_dev_hdl));
|
||||
|
||||
|
@ -300,8 +266,4 @@ TEST_CASE("Test USB Host async API", "[usb_host][ignore]")
|
|||
}
|
||||
vTaskDelay(10);
|
||||
}
|
||||
|
||||
//Cleanup
|
||||
TEST_ASSERT_EQUAL(ESP_OK, usb_host_uninstall());
|
||||
test_usb_deinit_phy();
|
||||
}
|
|
@ -10,12 +10,11 @@
|
|||
#include "esp_err.h"
|
||||
#include "esp_intr_alloc.h"
|
||||
#include "test_usb_common.h"
|
||||
#include "test_usb_mock_classes.h"
|
||||
#include "test_usb_mock_msc.h"
|
||||
#include "msc_client.h"
|
||||
#include "ctrl_client.h"
|
||||
#include "usb/usb_host.h"
|
||||
#include "unity.h"
|
||||
#include "test_utils.h"
|
||||
|
||||
// --------------------------------------------------- Test Cases ------------------------------------------------------
|
||||
|
||||
|
@ -34,17 +33,8 @@ Procedure:
|
|||
|
||||
#define TEST_DCONN_NO_CLIENT_ITERATIONS 3
|
||||
|
||||
TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][full_speed][low_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host Library
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
bool connected = false;
|
||||
int dconn_iter = 0;
|
||||
while (1) {
|
||||
|
@ -73,10 +63,6 @@ TEST_CASE("Test USB Host sudden disconnection (no client)", "[usb_host][ignore]"
|
|||
}
|
||||
}
|
||||
}
|
||||
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -95,17 +81,8 @@ Procedure:
|
|||
#define TEST_FORCE_DCONN_NUM_TRANSFERS 3
|
||||
#define TEST_MSC_SCSI_TAG 0xDEADBEEF
|
||||
|
||||
TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][full_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
//Create task to run client that communicates with MSC SCSI interface
|
||||
msc_client_test_param_t params = {
|
||||
.num_sectors_to_read = 1, //Unused by disconnect MSC client
|
||||
|
@ -134,12 +111,6 @@ TEST_CASE("Test USB Host sudden disconnection (single client)", "[usb_host][igno
|
|||
all_dev_free = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
}
|
||||
|
||||
/*
|
||||
|
@ -160,17 +131,8 @@ Procedure:
|
|||
|
||||
#define TEST_ENUM_ITERATIONS 3
|
||||
|
||||
TEST_CASE("Test USB Host enumeration", "[usb_host][ignore]")
|
||||
TEST_CASE("Test USB Host enumeration", "[usb_host][full_speed]")
|
||||
{
|
||||
test_usb_init_phy(); //Initialize the internal USB PHY and USB Controller for testing
|
||||
//Install USB Host
|
||||
usb_host_config_t host_config = {
|
||||
.skip_phy_setup = true, //test_usb_init_phy() will already have setup the internal USB PHY for us
|
||||
.intr_flags = ESP_INTR_FLAG_LEVEL1,
|
||||
};
|
||||
ESP_ERROR_CHECK(usb_host_install(&host_config));
|
||||
printf("Installed\n");
|
||||
|
||||
//Create task to run client that checks the enumeration of the device
|
||||
TaskHandle_t task_hdl;
|
||||
xTaskCreatePinnedToCore(msc_client_async_enum_task, "async", 6144, NULL, 2, &task_hdl, 0);
|
||||
|
@ -192,10 +154,4 @@ TEST_CASE("Test USB Host enumeration", "[usb_host][ignore]")
|
|||
all_dev_free = true;
|
||||
}
|
||||
}
|
||||
|
||||
//Short delay to allow task to be cleaned up
|
||||
vTaskDelay(10);
|
||||
//Clean up USB Host
|
||||
ESP_ERROR_CHECK(usb_host_uninstall());
|
||||
test_usb_deinit_phy(); //Deinitialize the internal USB PHY after testing
|
||||
}
|
|
@ -0,0 +1,14 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.esp32s3
|
||||
@pytest.mark.usb_host_flash_disk
|
||||
def test_usb_host(dut: Dut) -> None:
|
||||
dut.expect_exact('Press ENTER to see the list of tests')
|
||||
dut.write('[full_speed]')
|
||||
dut.expect_unity_test_output()
|
|
@ -0,0 +1,8 @@
|
|||
# This file was generated using idf.py save-defconfig. It can be edited manually.
|
||||
# Espressif IoT Development Framework (ESP-IDF) Project Minimal Configuration
|
||||
#
|
||||
# CONFIG_ESP_TASK_WDT_INIT is not set
|
||||
CONFIG_HEAP_POISONING_COMPREHENSIVE=y
|
||||
# CONFIG_UNITY_ENABLE_FLOAT is not set
|
||||
# CONFIG_UNITY_ENABLE_DOUBLE is not set
|
||||
CONFIG_UNITY_ENABLE_BACKTRACE_ON_FAIL=y
|
|
@ -1336,7 +1336,7 @@ esp_err_t usb_host_transfer_submit_control(usb_host_client_handle_t client_hdl,
|
|||
//Check that control transfer is valid
|
||||
HOST_CHECK(transfer->device_handle != NULL, ESP_ERR_INVALID_ARG); //Target device must be set
|
||||
usb_device_handle_t dev_hdl = transfer->device_handle;
|
||||
bool xfer_is_in = ((usb_setup_packet_t *)transfer->data_buffer)->bmRequestType & USB_BM_REQUEST_TYPE_DIR_OUT;
|
||||
bool xfer_is_in = ((usb_setup_packet_t *)transfer->data_buffer)->bmRequestType & USB_BM_REQUEST_TYPE_DIR_IN;
|
||||
usb_device_info_t dev_info;
|
||||
ESP_ERROR_CHECK(usbh_dev_get_info(dev_hdl, &dev_info));
|
||||
HOST_CHECK(transfer_check(transfer, USB_TRANSFER_TYPE_CTRL, dev_info.bMaxPacketSize0, xfer_is_in), ESP_ERR_INVALID_ARG);
|
||||
|
|
|
@ -11,7 +11,7 @@ USB Device Driver
|
|||
Overview
|
||||
--------
|
||||
|
||||
The driver allows users to use {IDF_TARGET_NAME} chips to develop USB devices on a top of the TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as a composite device supporting several USB devices simultaneously. Currently, only the Communications Device Class (CDC) type of the device with the Abstract Control Model (ACM) subclass and the Musical Instrument Digital Interface (MIDI) are supported.
|
||||
The driver allows you to use {IDF_TARGET_NAME} chips to develop USB devices on a top of TinyUSB stack. TinyUSB is integrated with ESP-IDF to provide USB features of the framework. Using this driver the chip works as simple or composite device supporting several USB devices simultaneously.
|
||||
|
||||
TinyUSB stack is distributed via `IDF Component Registry <https://components.espressif.com/components/espressif/esp_tinyusb>`_.
|
||||
|
||||
|
@ -38,7 +38,7 @@ On {IDF_TARGET_NAME}, connect GPIO {IDF_TARGET_USB_DP_GPIO_NUM} and {IDF_TARGET_
|
|||
|
||||
.. figure:: ../../../_static/usb-board-connection.png
|
||||
:align: center
|
||||
:alt: Connection of an ESP board to a USB host
|
||||
:alt: Connection of an ESP board to a USB host
|
||||
:figclass: align-center
|
||||
|
||||
Self-powered devices must also connect VBUS through voltage divider or comparator, more details in :ref:`self-powered-device` subchapter.
|
||||
|
@ -68,9 +68,9 @@ Via Menuconfig options you can specify:
|
|||
Descriptors Configuration
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
The driver's descriptors are provided by the :cpp:type:`tinyusb_config_t` structure's :cpp:member:`descriptor` and :cpp:member:`string_descriptor` members. Therefore, users should initialize :cpp:type:`tinyusb_config_t` to their desired descriptor before calling :cpp:func:`tinyusb_driver_install` to install driver.
|
||||
The driver's descriptors are provided by :cpp:type:`tinyusb_config_t` structure's :cpp:member:`device_descriptor`, :cpp:member:`configuration_descriptor` and :cpp:member:`string_descriptor` members. Therefore, you should initialize :cpp:type:`tinyusb_config_t` with your desired descriptors before calling :cpp:func:`tinyusb_driver_install` to install the driver.
|
||||
|
||||
However, the driver also provides a default descriptor. The driver can be installed with the default descriptor by setting the :cpp:member:`descriptor` and :cpp:member:`string_descriptor` members of :cpp:type:`tinyusb_config_t` to `NULL` before calling :cpp:func:`tinyusb_driver_install`. The driver's default descriptor is specified using Menuconfig, where the following fields should be configured:
|
||||
However, the driver also provides default descriptors. You can install the driver with default device and string descriptors by setting the :cpp:member:`device_descriptor` and :cpp:member:`string_descriptor` members of :cpp:type:`tinyusb_config_t` to `NULL` before calling :cpp:func:`tinyusb_driver_install`. To lower your development effort we also provide default configuration descriptor for CDC and MSC class, as these classes rarely require custom configuration. The driver's default device descriptor is specified using Menuconfig, where the following fields should be configured:
|
||||
|
||||
- PID
|
||||
- VID
|
||||
|
@ -87,14 +87,15 @@ Install Driver
|
|||
|
||||
To initialize the driver, users should call :cpp:func:`tinyusb_driver_install`. The driver's configuration is specified in a :cpp:type:`tinyusb_config_t` structure that is passed as an argument to :cpp:func:`tinyusb_driver_install`.
|
||||
|
||||
Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``tinyusb_config_t tusb_cfg = { 0 }``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below)
|
||||
Note that the :cpp:type:`tinyusb_config_t` structure can be zero initialized (e.g. ``const tinyusb_config_t tusb_cfg = { 0 };``) or partially (as shown below). For any member that is initialized to `0` or `NULL`, the driver will use its default configuration values for that member (see example below)
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
const tinyusb_config_t partial_init = {
|
||||
.descriptor = NULL; //Uses default descriptor specified in Menuconfig
|
||||
.string_descriptor = NULL; //Uses default string specified in Menuconfig
|
||||
.external_phy = false;
|
||||
.device_descriptor = NULL, // Use default device descriptor specified in Menuconfig
|
||||
.string_descriptor = NULL, // Use default string descriptors specified in Menuconfig
|
||||
.external_phy = false, // Use internal USB PHY
|
||||
.configuration_descriptor = NULL, // Use default configuration descriptor according to settings in Menuconfig
|
||||
};
|
||||
|
||||
.. _self-powered-device:
|
||||
|
@ -118,11 +119,11 @@ To use this feature, in :cpp:type:`tinyusb_config_t` you must set :cpp:member:`s
|
|||
USB Serial Device (CDC-ACM)
|
||||
---------------------------
|
||||
|
||||
If the CDC option is enabled in Menuconfig, the USB Serial Device could be initialized with :cpp:func:`tusb_cdc_acm_init` according to the settings from :cpp:type:`tinyusb_config_cdcacm_t` (see example below).
|
||||
If the CDC option is enabled in Menuconfig, the USB Serial Device can be initialized with :cpp:func:`tusb_cdc_acm_init` according to the settings from :cpp:type:`tinyusb_config_cdcacm_t` (see example below).
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
tinyusb_config_cdcacm_t acm_cfg = {
|
||||
const tinyusb_config_cdcacm_t acm_cfg = {
|
||||
.usb_dev = TINYUSB_USBDEV_0,
|
||||
.cdc_port = TINYUSB_CDC_ACM_0,
|
||||
.rx_unread_buf_sz = 64,
|
||||
|
|
|
@ -0,0 +1,9 @@
|
|||
# Documentation: .gitlab/ci/README.md#manifest-file-to-control-the-buildtest-apps
|
||||
|
||||
examples/peripherals/usb/device:
|
||||
enable:
|
||||
- if: SOC_USB_OTG_SUPPORTED == 1
|
||||
disable_test:
|
||||
- if: IDF_TARGET == "esp32s3"
|
||||
temporary: true
|
||||
reason: lack of runners
|
|
@ -0,0 +1,35 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from serial import Serial
|
||||
from serial.tools.list_ports import comports
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.usb_device
|
||||
def test_usb_device_console_example(dut: Dut) -> None:
|
||||
dut.expect_exact('USB initialization DONE')
|
||||
dut.expect_exact('example: log -> UART')
|
||||
dut.expect_exact('example: print -> stdout')
|
||||
dut.expect_exact('example: print -> stderr')
|
||||
|
||||
# Find device with Espressif TinyUSB VID/PID
|
||||
sleep(2) # Some time for the OS to enumerate our USB device
|
||||
ports = comports()
|
||||
for port, _, hwid in ports:
|
||||
if '303A:4001' in hwid:
|
||||
with Serial(port) as s:
|
||||
# Assert TinyUSB output: Read 3 lines and check their content
|
||||
serial_output = list()
|
||||
serial_output.append(s.readline())
|
||||
serial_output.append(s.readline())
|
||||
serial_output.append(s.readline())
|
||||
assert any(b'example: log -> USB' in out for out in serial_output)
|
||||
assert any(b'example: print -> stdout' in out for out in serial_output)
|
||||
assert any(b'example: print -> stderr' in out for out in serial_output)
|
||||
return
|
||||
|
||||
raise Exception('TinyUSB COM port not found')
|
|
@ -0,0 +1,12 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.usb_device
|
||||
def test_usb_device_hid_example(dut: Dut) -> None:
|
||||
dut.expect_exact('USB initialization DONE')
|
||||
dut.expect_exact('Sending Keyboard report')
|
||||
dut.expect_exact('Sending Mouse report')
|
|
@ -3,7 +3,7 @@
|
|||
*
|
||||
* SPDX-License-Identifier: MIT
|
||||
*
|
||||
* SPDX-FileContributor: 2022 Espressif Systems (Shanghai) CO LTD
|
||||
* SPDX-FileContributor: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
*/
|
||||
|
||||
#include <stdlib.h>
|
||||
|
@ -57,6 +57,7 @@ static void periodic_midi_write_example_cb(void *arg)
|
|||
}
|
||||
|
||||
// Send Note On for current position at full velocity (127) on channel 1.
|
||||
ESP_LOGI(TAG, "Writing MIDI data %d", note_sequence[note_pos]);
|
||||
uint8_t note_on[3] = {0x90 | channel, note_sequence[note_pos], 127};
|
||||
tud_midi_stream_write(cable_num, note_on, 3);
|
||||
|
||||
|
|
|
@ -0,0 +1,13 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.usb_device
|
||||
def test_usb_device_midi_example(dut: Dut) -> None:
|
||||
dut.expect_exact('USB initialization DONE')
|
||||
dut.expect_exact('MIDI write task init')
|
||||
dut.expect_exact('MIDI read task init')
|
||||
dut.expect_exact('Writing MIDI data 74')
|
|
@ -0,0 +1,29 @@
|
|||
# SPDX-FileCopyrightText: 2022-2023 Espressif Systems (Shanghai) CO LTD
|
||||
# SPDX-License-Identifier: CC0-1.0
|
||||
from time import sleep
|
||||
|
||||
import pytest
|
||||
from pytest_embedded import Dut
|
||||
from serial import Serial
|
||||
from serial.tools.list_ports import comports
|
||||
|
||||
|
||||
@pytest.mark.esp32s2
|
||||
@pytest.mark.usb_device
|
||||
def test_usb_device_serial_example(dut: Dut) -> None:
|
||||
dut.expect_exact('USB initialization DONE')
|
||||
sleep(2) # Some time for the OS to enumerate our USB device
|
||||
|
||||
# Find device with Espressif TinyUSB VID/PID
|
||||
ports = comports()
|
||||
for port, _, hwid in ports:
|
||||
if '303A:4001' in hwid:
|
||||
with Serial(port) as s:
|
||||
s.write('text\r\n'.encode()) # Write dummy text to COM port
|
||||
dut.expect_exact('Data from channel 0:') # Check ESP log
|
||||
dut.expect_exact('|text..|')
|
||||
res = s.readline() # Check COM echo
|
||||
assert b'text\r\n' in res
|
||||
return
|
||||
|
||||
raise Exception('TinyUSB COM port not found')
|
|
@ -37,6 +37,8 @@ markers =
|
|||
quad_psram: runners with quad psram
|
||||
octal_psram: runners with octal psram
|
||||
usb_host: usb host runners
|
||||
usb_host_flash_disk: usb host runners with USB flash disk attached
|
||||
usb_device: usb device runners
|
||||
ethernet_ota: ethernet OTA runners
|
||||
flash_encryption: Flash Encryption runners
|
||||
flash_encryption_f4r8: Flash Encryption runners with 4-line flash and 8-line psram
|
||||
|
|
|
@ -153,7 +153,9 @@ tinyusb:
|
|||
- 'examples/peripherals/usb/device/tusb_midi/'
|
||||
allowed_licenses:
|
||||
- Apache-2.0
|
||||
- MIT
|
||||
- MIT # Example derived from TinyUSB code by HaThach
|
||||
- Unlicense
|
||||
- CC0-1.0
|
||||
|
||||
# files matching this section do not perform the check
|
||||
# file patterns starting with ! are negated, meaning files matching them won't match the section.
|
||||
|
|
Ładowanie…
Reference in New Issue