diff --git a/.github/workflows/build_aarch64.yml b/.github/workflows/build_aarch64.yml index 0cc7a5de1..8cf7852b9 100644 --- a/.github/workflows/build_aarch64.yml +++ b/.github/workflows/build_aarch64.yml @@ -18,7 +18,7 @@ jobs: matrix: family: # Alphabetical order - - 'raspberrypi4' + - 'broadcom_64bit' steps: - name: Setup Python uses: actions/setup-python@v2 diff --git a/.github/workflows/build_arm.yml b/.github/workflows/build_arm.yml index dc4d9fcfb..177f1076e 100644 --- a/.github/workflows/build_arm.yml +++ b/.github/workflows/build_arm.yml @@ -39,6 +39,7 @@ jobs: matrix: family: # Alphabetical order + - 'broadcom_32bit' - 'imxrt' - 'lpc15' - 'lpc18' @@ -114,7 +115,7 @@ jobs: done # --------------------------------------- - # Build all no-family (opharned) boards + # Build all no-family (orphaned) boards # --------------------------------------- build-board: runs-on: ubuntu-latest diff --git a/.github/workflows/build_esp.yml b/.github/workflows/build_esp.yml index 57dbf33e3..1ed76ef4d 100644 --- a/.github/workflows/build_esp.yml +++ b/.github/workflows/build_esp.yml @@ -18,7 +18,7 @@ jobs: # ESP32-S2 - 'espressif_saola_1' # ESP32-S3 - #- 'espressif_addax_1' + #- 'espressif_s3_devkitm' # S3 compile error with "dangerous relocation: call8: call target out of range: memcpy" steps: diff --git a/.gitignore b/.gitignore index f7adff4c9..87a5faa80 100644 --- a/.gitignore +++ b/.gitignore @@ -26,3 +26,5 @@ cov-int # cppcheck build directories *-build-dir /_bin/ +__pycache__ + diff --git a/README.rst b/README.rst index a8ce9399c..03219db3f 100644 --- a/README.rst +++ b/README.rst @@ -50,7 +50,7 @@ The stack supports the following MCUs: - **Renesas:** RX63N, RX65N, RX72N - **Silabs:** EFM32GG - **Sony:** CXD56 -- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, L0, L1, L4, L4+ +- **ST:** STM32 series: F0, F1, F2, F3, F4, F7, H7, G4, L0, L1, L4, L4+ - **TI:** MSP430, MSP432E4, TM4C123 - **ValentyUSB:** eptri diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index e3cb8c679..1f7f395cb 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -82,6 +82,8 @@ Supported MCUs | +-----------------------+--------+------+-----------+-------------------+--------------+ | | H7 | ✔ | | ✔ | dwc2 | | | +-----------------------+--------+------+-----------+-------------------+--------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------+--------+------+-----------+-------------------+--------------+ | | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | | +----+------------------+--------+------+-----------+-------------------+--------------+ | | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | @@ -243,6 +245,7 @@ Kinetis - `Freedom FRDM-KL25Z `__ - `Freedom FRDM-K32L2B3 `__ +- `KUIIC `__ LPC 11-13-15 ^^^^^^^^^^^^ @@ -341,6 +344,7 @@ F4 - `STM32 F411ve Discovery `__ - `STM32 F412zg Discovery `__ - `STM32 F412zg Nucleo `__ +- `STM32 F439zi Nucleo `__ F7 ^^ @@ -352,6 +356,17 @@ F7 - `STM32 F767zi Nucleo `__ - `STM32 F769i Discovery `__ +H7 +^^ +- `STM32 H743zi Nucleo `__ +- `STM32 H743i Evaluation `__ +- `STM32 H745i Discovery `__ +- `Waveshare OpenH743I-C `__ + +G4 +^^ +- `STM32 G474RE Nucleo `__ + L0 ^^ - `STM32 L035c8 Discovery `__ @@ -362,13 +377,6 @@ L4 - `STM32 L4P5zg Nucleo `__ - `STM32 L4R5zi Nucleo `__ -H7 -^^ -- `STM32 H743zi Nucleo `__ -- `STM32 H743i Evaluation `__ -- `STM32 H745i Discovery `__ -- `Waveshare OpenH743I-C `__ - TI -- diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAMD11 b/examples/device/audio_4_channel_mic/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAME5X b/examples/device/audio_4_channel_mic/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/.skip.MCU_SAMG b/examples/device/audio_4_channel_mic/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_4_channel_mic/skip.txt b/examples/device/audio_4_channel_mic/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_4_channel_mic/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/audio_test/.skip.MCU_SAMD11 b/examples/device/audio_test/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/.skip.MCU_SAME5X b/examples/device/audio_test/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/.skip.MCU_SAMG b/examples/device/audio_test/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/audio_test/skip.txt b/examples/device/audio_test/skip.txt new file mode 100644 index 000000000..ae9b57f1f --- /dev/null +++ b/examples/device/audio_test/skip.txt @@ -0,0 +1,3 @@ +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/cdc_msc/.skip.MCU_SAMD11 b/examples/device/cdc_msc/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc/skip.txt b/examples/device/cdc_msc/skip.txt new file mode 100644 index 000000000..d844feae8 --- /dev/null +++ b/examples/device/cdc_msc/skip.txt @@ -0,0 +1 @@ +mcu:SAMD11 \ No newline at end of file diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_BCM2711 b/examples/device/cdc_msc_freertos/.skip.MCU_BCM2711 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_CXD56 b/examples/device/cdc_msc_freertos/.skip.MCU_CXD56 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_GD32VF103 b/examples/device/cdc_msc_freertos/.skip.MCU_GD32VF103 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_MKL25ZXX b/examples/device/cdc_msc_freertos/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_MSP430x5xx b/examples/device/cdc_msc_freertos/.skip.MCU_MSP430x5xx deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_RP2040 b/examples/device/cdc_msc_freertos/.skip.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_SAMD11 b/examples/device/cdc_msc_freertos/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_SAMX7X b/examples/device/cdc_msc_freertos/.skip.MCU_SAMX7X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/.skip.MCU_VALENTYUSB_EPTRI b/examples/device/cdc_msc_freertos/.skip.MCU_VALENTYUSB_EPTRI deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt new file mode 100644 index 000000000..7137b78af --- /dev/null +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -0,0 +1,10 @@ +mcu:CXD56 +mcu:MSP430x5xx +mcu:SAMD11 +mcu:VALENTYUSB_EPTRI +mcu:MKL25ZXX +mcu:RP2040 +mcu:SAMX7X +mcu:GD32VF103 +family:broadcom_64bit +family:broadcom_32bit \ No newline at end of file diff --git a/examples/device/dfu/.skip.MCU_TM4C123 b/examples/device/dfu/.skip.MCU_TM4C123 deleted file mode 100644 index 6260e6e25..000000000 --- a/examples/device/dfu/.skip.MCU_TM4C123 +++ /dev/null @@ -1,4 +0,0 @@ -LINK _build/ek-tm4c123gxl/dfu.elf -/home/runner/cache/toolchain/xpack-arm-none-eabi-gcc-10.2.1-1.1/bin/../lib/gcc/arm-none-eabi/10.2.1/../../../../arm-none-eabi/bin/ld: section .ARM.exidx.text._close LMA [0000000000002980,0000000000002987] overlaps section .data LMA [0000000000002980,0000000000002a03] -collect2: error: ld returned 1 exit status -make: *** [../../rules.mk:94: _build/ek-tm4c123gxl/dfu.elf] Error 1 \ No newline at end of file diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt new file mode 100644 index 000000000..9ac346bad --- /dev/null +++ b/examples/device/dfu/skip.txt @@ -0,0 +1,2 @@ +mcu:TM4C123 +mcu:BCM2835 diff --git a/examples/device/dynamic_configuration/.skip.MCU_SAMD11 b/examples/device/dynamic_configuration/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/dynamic_configuration/skip.txt b/examples/device/dynamic_configuration/skip.txt new file mode 100644 index 000000000..d844feae8 --- /dev/null +++ b/examples/device/dynamic_configuration/skip.txt @@ -0,0 +1 @@ +mcu:SAMD11 \ No newline at end of file diff --git a/examples/device/hid_composite_freertos/.skip.MCU_BCM2711 b/examples/device/hid_composite_freertos/.skip.MCU_BCM2711 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_CXD56 b/examples/device/hid_composite_freertos/.skip.MCU_CXD56 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_GD32VF103 b/examples/device/hid_composite_freertos/.skip.MCU_GD32VF103 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_MSP430x5xx b/examples/device/hid_composite_freertos/.skip.MCU_MSP430x5xx deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_RP2040 b/examples/device/hid_composite_freertos/.skip.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_SAMD11 b/examples/device/hid_composite_freertos/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_SAMX7X b/examples/device/hid_composite_freertos/.skip.MCU_SAMX7X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/.skip.MCU_VALENTYUSB_EPTRI b/examples/device/hid_composite_freertos/.skip.MCU_VALENTYUSB_EPTRI deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt new file mode 100644 index 000000000..e64187fd4 --- /dev/null +++ b/examples/device/hid_composite_freertos/skip.txt @@ -0,0 +1,9 @@ +mcu:CXD56 +mcu:MSP430x5xx +mcu:SAMD11 +mcu:VALENTYUSB_EPTRI +mcu:RP2040 +mcu:SAMX7X +mcu:GD32VF103 +family:broadcom_64bit +family:broadcom_32bit \ No newline at end of file diff --git a/examples/device/hid_generic_inout/hid_test.py b/examples/device/hid_generic_inout/hid_test.py index a42930fb5..21fd3f421 100644 --- a/examples/device/hid_generic_inout/hid_test.py +++ b/examples/device/hid_generic_inout/hid_test.py @@ -1,20 +1,22 @@ # Install python3 HID package https://pypi.org/project/hid/ import hid -USB_VID = 0xcafe +# default is TinyUSB (0xcafe), Adafruit (0x239a), RaspberryPi (0x2e8a), Espressif (0x303a) VID +USB_VID = (0xcafe, 0x239a, 0x2e8a, 0x303a) -print("Openning HID device with VID = 0x%X" % USB_VID) +print("VID list: " + ", ".join('%02x' % v for v in USB_VID)) -for dict in hid.enumerate(USB_VID): - print(dict) - dev = hid.Device(dict['vendor_id'], dict['product_id']) - if dev: - while True: - # Get input from console and encode to UTF8 for array of chars. - # hid generic inout is single report therefore by HIDAPI requirement - # it must be preceeded with 0x00 as dummy reportID - str_out = b'\x00' - str_out += input("Send text to HID Device : ").encode('utf-8') - dev.write(str_out) - str_in = dev.read(64) - print("Received from HID Device:", str_in, '\n') +for vid in USB_VID: + for dict in hid.enumerate(vid): + print(dict) + dev = hid.Device(dict['vendor_id'], dict['product_id']) + if dev: + while True: + # Get input from console and encode to UTF8 for array of chars. + # hid generic inout is single report therefore by HIDAPI requirement + # it must be preceeded with 0x00 as dummy reportID + str_out = b'\x00' + str_out += input("Send text to HID Device : ").encode('utf-8') + dev.write(str_out) + str_in = dev.read(64) + print("Received from HID Device:", str_in, '\n') diff --git a/examples/device/msc_dual_lun/.skip.MCU_MKL25ZXX b/examples/device/msc_dual_lun/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/msc_dual_lun/.skip.MCU_SAMD11 b/examples/device/msc_dual_lun/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/msc_dual_lun/skip.txt b/examples/device/msc_dual_lun/skip.txt new file mode 100644 index 000000000..3549c702a --- /dev/null +++ b/examples/device/msc_dual_lun/skip.txt @@ -0,0 +1,2 @@ +mcu:SAMD11 +mcu:MKL25ZXX \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 b/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 deleted file mode 100644 index bdc68f5db..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_BCM2711 +++ /dev/null @@ -1 +0,0 @@ -tinyusb/lib/lwip/src/include/lwip/arch.h:202:13: error: conflicting types for 'ssize_t' \ No newline at end of file diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX b/examples/device/net_lwip_webserver/.skip.MCU_LPC11UXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX b/examples/device/net_lwip_webserver/.skip.MCU_LPC13XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_MKL25ZXX b/examples/device/net_lwip_webserver/.skip.MCU_MKL25ZXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx b/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx deleted file mode 100644 index 17600f062..000000000 --- a/examples/device/net_lwip_webserver/.skip.MCU_MSP430x5xx +++ /dev/null @@ -1 +0,0 @@ -too many warnings for 16-bit integer overflow diff --git a/examples/device/net_lwip_webserver/.skip.MCU_NUC121 b/examples/device/net_lwip_webserver/.skip.MCU_NUC121 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_SAMD11 b/examples/device/net_lwip_webserver/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 b/examples/device/net_lwip_webserver/.skip.MCU_STM32L0 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/net_lwip_webserver/skip.txt b/examples/device/net_lwip_webserver/skip.txt new file mode 100644 index 000000000..68761b058 --- /dev/null +++ b/examples/device/net_lwip_webserver/skip.txt @@ -0,0 +1,10 @@ +mcu:LPC11UXX +mcu:LPC13XX +mcu:MSP430x5xx +mcu:NUC121 +mcu:SAMD11 +mcu:STM32L0 +mcu:MKL25ZXX +family:broadcom_64bit +family:broadcom_32bit +board:curiosity_nano \ No newline at end of file diff --git a/examples/device/uac2_headset/.skip.MCU_LPC11UXX b/examples/device/uac2_headset/.skip.MCU_LPC11UXX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_LPC13XX b/examples/device/uac2_headset/.skip.MCU_LPC13XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_NUC121 b/examples/device/uac2_headset/.skip.MCU_NUC121 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAMD11 b/examples/device/uac2_headset/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAME5X b/examples/device/uac2_headset/.skip.MCU_SAME5X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/.skip.MCU_SAMG b/examples/device/uac2_headset/.skip.MCU_SAMG deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt new file mode 100644 index 000000000..9471822a4 --- /dev/null +++ b/examples/device/uac2_headset/skip.txt @@ -0,0 +1,6 @@ +mcu:LPC11UXX +mcu:LPC13XX +mcu:NUC121 +mcu:SAMD11 +mcu:SAME5X +mcu:SAMG \ No newline at end of file diff --git a/examples/device/usbtmc/skip.txt b/examples/device/usbtmc/skip.txt new file mode 100644 index 000000000..a43106cf0 --- /dev/null +++ b/examples/device/usbtmc/skip.txt @@ -0,0 +1 @@ +mcu:BCM2835 diff --git a/examples/device/video_capture/.skip.MCU_MSP430x5xx b/examples/device/video_capture/.skip.MCU_MSP430x5xx deleted file mode 100644 index 17600f062..000000000 --- a/examples/device/video_capture/.skip.MCU_MSP430x5xx +++ /dev/null @@ -1 +0,0 @@ -too many warnings for 16-bit integer overflow diff --git a/examples/device/video_capture/.skip.MCU_SAMD11 b/examples/device/video_capture/.skip.MCU_SAMD11 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt new file mode 100644 index 000000000..892a8c6a7 --- /dev/null +++ b/examples/device/video_capture/skip.txt @@ -0,0 +1,2 @@ +mcu:MSP430x5xx +mcu:SAMD11 \ No newline at end of file diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC175X_6X b/examples/host/cdc_msc_hid/.only.MCU_LPC175X_6X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC177X_8X b/examples/host/cdc_msc_hid/.only.MCU_LPC177X_8X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC18XX b/examples/host/cdc_msc_hid/.only.MCU_LPC18XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC40XX b/examples/host/cdc_msc_hid/.only.MCU_LPC40XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_LPC43XX b/examples/host/cdc_msc_hid/.only.MCU_LPC43XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX b/examples/host/cdc_msc_hid/.only.MCU_MIMXRT10XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/.only.MCU_RP2040 b/examples/host/cdc_msc_hid/.only.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt new file mode 100644 index 000000000..db9a337e5 --- /dev/null +++ b/examples/host/cdc_msc_hid/only.txt @@ -0,0 +1,8 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 \ No newline at end of file diff --git a/examples/host/hid_controller/.only.MCU_LPC175X_6X b/examples/host/hid_controller/.only.MCU_LPC175X_6X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC177X_8X b/examples/host/hid_controller/.only.MCU_LPC177X_8X deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC18XX b/examples/host/hid_controller/.only.MCU_LPC18XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC40XX b/examples/host/hid_controller/.only.MCU_LPC40XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_LPC43XX b/examples/host/hid_controller/.only.MCU_LPC43XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_MIMXRT10XX b/examples/host/hid_controller/.only.MCU_MIMXRT10XX deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/.only.MCU_RP2040 b/examples/host/hid_controller/.only.MCU_RP2040 deleted file mode 100644 index e69de29bb..000000000 diff --git a/examples/host/hid_controller/Makefile b/examples/host/hid_controller/Makefile index a4eaf0816..c58df562b 100644 --- a/examples/host/hid_controller/Makefile +++ b/examples/host/hid_controller/Makefile @@ -9,7 +9,7 @@ INC += \ EXAMPLE_SOURCE += \ src/hid_app.c \ src/main.c - + SRC_C += $(addprefix $(CURRENT_PATH)/, $(EXAMPLE_SOURCE)) # TODO: suppress warning caused by host stack diff --git a/examples/host/hid_controller/only.txt b/examples/host/hid_controller/only.txt new file mode 100644 index 000000000..db9a337e5 --- /dev/null +++ b/examples/host/hid_controller/only.txt @@ -0,0 +1,8 @@ +mcu:LPC175X_6X +mcu:LPC177X_8X +mcu:LPC18XX +mcu:LPC40XX +mcu:LPC43XX +mcu:MIMXRT10XX +mcu:RP2040 +mcu:MSP432E4 \ No newline at end of file diff --git a/examples/host/hid_controller/src/hid_app.c b/examples/host/hid_controller/src/hid_app.c index bbfea8182..582e01959 100644 --- a/examples/host/hid_controller/src/hid_app.c +++ b/examples/host/hid_controller/src/hid_app.c @@ -138,6 +138,8 @@ void hid_app_task(void) // therefore report_desc = NULL, desc_len = 0 void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, uint8_t const* desc_report, uint16_t desc_len) { + (void)desc_report; + (void)desc_len; uint16_t vid, pid; tuh_vid_pid_get(dev_addr, &vid, &pid); diff --git a/examples/make.mk b/examples/make.mk index 793c40aa2..bed46d02b 100644 --- a/examples/make.mk +++ b/examples/make.mk @@ -54,6 +54,8 @@ endif #-------------- Cross Compiler ------------ # Can be set by board, default to ARM GCC CROSS_COMPILE ?= arm-none-eabi- +# Allow for -Os to be changed by board makefiles in case -Os is not allowed +CFLAGS_OPTIMIZED ?= -Os CC = $(CROSS_COMPILE)gcc CXX = $(CROSS_COMPILE)g++ @@ -112,7 +114,7 @@ CFLAGS += \ ifeq ($(DEBUG), 1) CFLAGS += -Og else - CFLAGS += -Os + CFLAGS += $(CFLAGS_OPTIMIZED) endif # Log level is mapped to TUSB DEBUG option diff --git a/examples/rules.mk b/examples/rules.mk index 4cc35cb22..95a9c9879 100644 --- a/examples/rules.mk +++ b/examples/rules.mk @@ -12,8 +12,10 @@ ifeq (,$(findstring $(FAMILY),esp32s2 esp32s3 rp2040)) # Compiler Flags # --------------------------------------- +LIBS_GCC ?= -lgcc -lm -lnosys + # libc -LIBS += -lgcc -lm -lnosys +LIBS += $(LIBS_GCC) ifneq ($(BOARD), spresense) LIBS += -lc @@ -49,7 +51,11 @@ ifeq ($(NO_LTO),1) CFLAGS := $(filter-out -flto,$(CFLAGS)) endif -LDFLAGS += $(CFLAGS) -Wl,-T,$(TOP)/$(LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections +ifneq ($(LD_FILE),) +LDFLAGS_LD_FILE ?= -Wl,-T,$(TOP)/$(LD_FILE) +endif + +LDFLAGS += $(CFLAGS) $(LDFLAGS_LD_FILE) -Wl,-Map=$@.map -Wl,-cref -Wl,-gc-sections ifneq ($(SKIP_NANOLIB), 1) LDFLAGS += -specs=nosys.specs -specs=nano.specs endif diff --git a/hw/bsp/board.c b/hw/bsp/board.c index afacdef9f..e208624ba 100644 --- a/hw/bsp/board.c +++ b/hw/bsp/board.c @@ -126,6 +126,8 @@ TU_ATTR_USED int sys_write (int fhdl, const void *buf, size_t count) TU_ATTR_USED int sys_read (int fhdl, char *buf, size_t count) { (void) fhdl; + (void) buf; + (void) count; return 0; } diff --git a/hw/bsp/board_mcu.h b/hw/bsp/board_mcu.h index f8b5c061c..b911e1e53 100644 --- a/hw/bsp/board_mcu.h +++ b/hw/bsp/board_mcu.h @@ -32,7 +32,7 @@ //--------------------------------------------------------------------+ // Low Level MCU header include. TinyUSB stack and example should be -// platform independent and mostly doens't need to include this file. +// platform independent and mostly doesn't need to include this file. // However there are still certain situation where this file is needed: // - FreeRTOSConfig.h to set up correct clock and NVIC interrupts for ARM Cortex // - SWO logging for Cortex M with ITM_SendChar() / ITM_ReceiveChar() @@ -146,6 +146,9 @@ #elif CFG_TUSB_MCU == OPT_MCU_TM4C123 #include "TM4C123.h" +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) + // no header needed + #else #error "Missing MCU header" #endif diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h similarity index 100% rename from hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.h rename to hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.h diff --git a/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk new file mode 100644 index 000000000..52e9e45c4 --- /dev/null +++ b/hw/bsp/broadcom_32bit/boards/raspberrypi_zero_w/board.mk @@ -0,0 +1,5 @@ +CFLAGS += -mcpu=arm1176jzf-s \ + -DBCM_VERSION=2835 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2835 + +SUFFIX = diff --git a/hw/bsp/raspberrypi4/family.c b/hw/bsp/broadcom_32bit/family.c similarity index 82% rename from hw/bsp/raspberrypi4/family.c rename to hw/bsp/broadcom_32bit/family.c index ba0b2700a..f7a11fb49 100644 --- a/hw/bsp/raspberrypi4/family.c +++ b/hw/bsp/broadcom_32bit/family.c @@ -27,8 +27,9 @@ #include "bsp/board.h" #include "board.h" +#include "broadcom/cpu.h" +#include "broadcom/gpio.h" #include "broadcom/interrupts.h" -#include "broadcom/io.h" #include "broadcom/mmu.h" #include "broadcom/caches.h" #include "broadcom/vcmailbox.h" @@ -37,9 +38,8 @@ #define LED_PIN 18 #define LED_STATE_ON 1 -// Button -#define BUTTON_PIN 16 -#define BUTTON_STATE_ACTIVE 0 +// UART TX +#define UART_TX_PIN 14 //--------------------------------------------------------------------+ // Forward USB interrupt events to TinyUSB IRQ Handler @@ -62,14 +62,26 @@ void board_init(void) init_caches(); // LED - gpio_initOutputPinWithPullNone(LED_PIN); + gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); + gpio_set_pull(LED_PIN, BP_PULL_NONE); board_led_write(true); - // Button - // TODO - // Uart - uart_init(); + COMPLETE_MEMORY_READS; + AUX->ENABLES_b.UART_1 = true; + + UART1->IER = 0; + UART1->CNTL = 0; + UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; + UART1->MCR = 0; + UART1->IER = 0; + + uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + UART1->BAUD = ((source_clock / (115200 * 8)) - 1); + UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; + COMPLETE_MEMORY_READS; + + gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); // Turn on USB peripheral. vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); @@ -87,7 +99,7 @@ void board_init(void) void board_led_write(bool state) { - gpio_setPinOutputBool(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); } uint32_t board_button_read(void) diff --git a/hw/bsp/broadcom_32bit/family.mk b/hw/bsp/broadcom_32bit/family.mk new file mode 100644 index 000000000..98744c5d0 --- /dev/null +++ b/hw/bsp/broadcom_32bit/family.mk @@ -0,0 +1,46 @@ +MCU_DIR = hw/mcu/broadcom +DEPS_SUBMODULES += $(MCU_DIR) + +include $(TOP)/$(BOARD_PATH)/board.mk + +CFLAGS += \ + -Wall \ + -O0 \ + -ffreestanding \ + -nostdlib \ + -nostartfiles \ + -mgeneral-regs-only \ + -fno-exceptions \ + -std=c17 + +CROSS_COMPILE = arm-none-eabi- + +# mcu driver cause following warnings +CFLAGS += -Wno-error=cast-qual + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ + $(MCU_DIR)/broadcom/gpio.c \ + $(MCU_DIR)/broadcom/interrupts.c \ + $(MCU_DIR)/broadcom/mmu.c \ + $(MCU_DIR)/broadcom/caches.c \ + $(MCU_DIR)/broadcom/vcmailbox.c + +SKIP_NANOLIB = 1 + +LD_FILE = $(MCU_DIR)/broadcom/link$(SUFFIX).ld + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(MCU_DIR) + +SRC_S += $(MCU_DIR)/broadcom/boot$(SUFFIX).S + +$(BUILD)/kernel$(SUFFIX).img: $(BUILD)/$(PROJECT).elf + $(OBJCOPY) -O binary $^ $@ + +# Copy to kernel to netboot drive or SD card +# Change destinaation to fit your need +flash: $(BUILD)/kernel$(SUFFIX).img + @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk new file mode 100644 index 000000000..5706b8318 --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_cm4/board.mk @@ -0,0 +1,3 @@ +CFLAGS += -mcpu=cortex-a72 \ + -DBCM_VERSION=2711 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2711 diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h new file mode 100644 index 000000000..1d3565d5c --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.h @@ -0,0 +1,38 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk new file mode 100644 index 000000000..3060b0571 --- /dev/null +++ b/hw/bsp/broadcom_64bit/boards/raspberrypi_zero2w/board.mk @@ -0,0 +1,3 @@ +CFLAGS += -mcpu=cortex-a53 \ + -DBCM_VERSION=2837 \ + -DCFG_TUSB_MCU=OPT_MCU_BCM2837 diff --git a/hw/bsp/broadcom_64bit/family.c b/hw/bsp/broadcom_64bit/family.c new file mode 100644 index 000000000..f7a11fb49 --- /dev/null +++ b/hw/bsp/broadcom_64bit/family.c @@ -0,0 +1,156 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019 Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "bsp/board.h" +#include "board.h" + +#include "broadcom/cpu.h" +#include "broadcom/gpio.h" +#include "broadcom/interrupts.h" +#include "broadcom/mmu.h" +#include "broadcom/caches.h" +#include "broadcom/vcmailbox.h" + +// LED +#define LED_PIN 18 +#define LED_STATE_ON 1 + +// UART TX +#define UART_TX_PIN 14 + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_IRQHandler(void) +{ + tud_int_handler(0); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ +void board_init(void) +{ + setup_mmu_flat_map(); + init_caches(); + + // LED + gpio_set_function(LED_PIN, GPIO_FUNCTION_OUTPUT); + gpio_set_pull(LED_PIN, BP_PULL_NONE); + board_led_write(true); + + // Uart + COMPLETE_MEMORY_READS; + AUX->ENABLES_b.UART_1 = true; + + UART1->IER = 0; + UART1->CNTL = 0; + UART1->LCR_b.DATA_SIZE = UART1_LCR_DATA_SIZE_MODE_8BIT; + UART1->MCR = 0; + UART1->IER = 0; + + uint32_t source_clock = vcmailbox_get_clock_rate_measured(VCMAILBOX_CLOCK_CORE); + UART1->BAUD = ((source_clock / (115200 * 8)) - 1); + UART1->CNTL |= UART1_CNTL_TX_ENABLE_Msk; + COMPLETE_MEMORY_READS; + + gpio_set_function(UART_TX_PIN, GPIO_FUNCTION_ALT5); + + // Turn on USB peripheral. + vcmailbox_set_power_state(VCMAILBOX_DEVICE_USB_HCD, true); + + // Timer 1/1024 second tick + SYSTMR->CS_b.M1 = 1; + SYSTMR->C1 = SYSTMR->CLO + 977; + BP_EnableIRQ(TIMER_1_IRQn); + + BP_SetPriority(USB_IRQn, 0x00); + BP_ClearPendingIRQ(USB_IRQn); + BP_EnableIRQ(USB_IRQn); + BP_EnableIRQs(); +} + +void board_led_write(bool state) +{ + gpio_set_value(LED_PIN, state ? LED_STATE_ON : (1-LED_STATE_ON)); +} + +uint32_t board_button_read(void) +{ + return 0; +} + +int board_uart_read(uint8_t* buf, int len) +{ + (void) buf; (void) len; + return 0; +} + +int board_uart_write(void const * buf, int len) +{ + for (int i = 0; i < len; i++) { + const char* cbuf = buf; + while (!UART1->STAT_b.TX_READY) {} + if (cbuf[i] == '\n') { + UART1->IO = '\r'; + while (!UART1->STAT_b.TX_READY) {} + } + UART1->IO = cbuf[i]; + } + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void TIMER_1_IRQHandler(void) +{ + system_ticks++; + SYSTMR->C1 += 977; + SYSTMR->CS_b.M1 = 1; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif + +void HardFault_Handler (void) +{ + // asm("bkpt"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) +{ + +} diff --git a/hw/bsp/raspberrypi4/family.mk b/hw/bsp/broadcom_64bit/family.mk similarity index 77% rename from hw/bsp/raspberrypi4/family.mk rename to hw/bsp/broadcom_64bit/family.mk index c65070a71..723926734 100644 --- a/hw/bsp/raspberrypi4/family.mk +++ b/hw/bsp/broadcom_64bit/family.mk @@ -3,18 +3,16 @@ DEPS_SUBMODULES += $(MCU_DIR) include $(TOP)/$(BOARD_PATH)/board.mk -CC = clang - CFLAGS += \ - -mcpu=cortex-a72 \ -Wall \ -O0 \ -ffreestanding \ -nostdlib \ -nostartfiles \ - -std=c17 \ -mgeneral-regs-only \ - -DCFG_TUSB_MCU=OPT_MCU_BCM2711 + -std=c17 + +CROSS_COMPILE = aarch64-none-elf- # mcu driver cause following warnings CFLAGS += -Wno-error=cast-qual @@ -22,25 +20,22 @@ CFLAGS += -Wno-error=cast-qual SRC_C += \ src/portable/synopsys/dwc2/dcd_dwc2.c \ $(MCU_DIR)/broadcom/gen/interrupt_handlers.c \ + $(MCU_DIR)/broadcom/gpio.c \ $(MCU_DIR)/broadcom/interrupts.c \ - $(MCU_DIR)/broadcom/io.c \ $(MCU_DIR)/broadcom/mmu.c \ $(MCU_DIR)/broadcom/caches.c \ $(MCU_DIR)/broadcom/vcmailbox.c - -CROSS_COMPILE = aarch64-none-elf- - SKIP_NANOLIB = 1 -LD_FILE = $(MCU_DIR)/broadcom/link.ld +LD_FILE = $(MCU_DIR)/broadcom/link8.ld INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(MCU_DIR) \ $(TOP)/lib/CMSIS_5/CMSIS/Core_A/Include -SRC_S += $(MCU_DIR)/broadcom/boot.S +SRC_S += $(MCU_DIR)/broadcom/boot8.S $(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf $(OBJCOPY) -O binary $^ $@ @@ -48,4 +43,4 @@ $(BUILD)/kernel8.img: $(BUILD)/$(PROJECT).elf # Copy to kernel to netboot drive or SD card # Change destinaation to fit your need flash: $(BUILD)/kernel8.img - $(CP) $< /home/$(USER)/Documents/code/pi4_tinyusb/boot_cpy + @$(CP) $< /home/$(USER)/Documents/code/pi_tinyusb/boot_cpy diff --git a/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake b/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake index 60f7d19ca..8996ff9dc 100644 --- a/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake +++ b/hw/bsp/esp32s3/boards/espressif_addax_1/board.cmake @@ -1,16 +1,6 @@ # Apply board specific content here target_include_directories(${COMPONENT_LIB} PRIVATE .) -idf_build_get_property(idf_target IDF_TARGET) - -message(STATUS "Apply ${BOARD}(${idf_target}) specific options for component: ${COMPONENT_TARGET}") - -if(NOT ${idf_target} STREQUAL "esp32s3") - message(FATAL_ERROR "Incorrect target for board ${BOARD}: (${idf_target}), try to clean the build first." ) -endif() - -set(IDF_TARGET "esp32s3" FORCE) - target_compile_options(${COMPONENT_TARGET} PUBLIC "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" "-DCFG_TUSB_OS=OPT_OS_FREERTOS" diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake new file mode 100644 index 000000000..8996ff9dc --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.cmake @@ -0,0 +1,7 @@ +# Apply board specific content here +target_include_directories(${COMPONENT_LIB} PRIVATE .) + +target_compile_options(${COMPONENT_TARGET} PUBLIC + "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" + "-DCFG_TUSB_OS=OPT_OS_FREERTOS" +) \ No newline at end of file diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h new file mode 100644 index 000000000..c7940c56e --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitc/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake new file mode 100644 index 000000000..8996ff9dc --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.cmake @@ -0,0 +1,7 @@ +# Apply board specific content here +target_include_directories(${COMPONENT_LIB} PRIVATE .) + +target_compile_options(${COMPONENT_TARGET} PUBLIC + "-DCFG_TUSB_MCU=OPT_MCU_ESP32S3" + "-DCFG_TUSB_OS=OPT_OS_FREERTOS" +) \ No newline at end of file diff --git a/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h new file mode 100644 index 000000000..c7940c56e --- /dev/null +++ b/hw/bsp/esp32s3/boards/espressif_s3_devkitm/board.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define NEOPIXEL_PIN 48 + +#define BUTTON_PIN 0 +#define BUTTON_STATE_ACTIVE 0 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld b/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld new file mode 100644 index 000000000..5420ffc00 --- /dev/null +++ b/hw/bsp/kuiic/K32L2B31xxxxA_flash.ld @@ -0,0 +1,217 @@ +/* +** ################################################################### +** Processors: K32L2B31VFM0A +** K32L2B31VFT0A +** K32L2B31VLH0A +** K32L2B31VMP0A +** +** Compiler: GNU C Compiler +** Reference manual: K32L2B3xRM, Rev.0, July 2019 +** Version: rev. 1.0, 2019-07-30 +** Build: b190930 +** +** Abstract: +** Linker file for the GNU C Compiler +** +** Copyright 2016 Freescale Semiconductor, Inc. +** Copyright 2016-2019 NXP +** All rights reserved. +** +** SPDX-License-Identifier: BSD-3-Clause +** +** http: www.nxp.com +** mail: support@nxp.com +** +** ################################################################### +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +HEAP_SIZE = DEFINED(__heap_size__) ? __heap_size__ : 0x0400; +STACK_SIZE = DEFINED(__stack_size__) ? __stack_size__ : 0x0400; + +/* Specify the memory areas */ +MEMORY +{ + m_interrupts (RX) : ORIGIN = 0x00008000, LENGTH = 0x00000200 + m_flash_config (RX) : ORIGIN = 0x00008400, LENGTH = 0x00000010 + m_text (RX) : ORIGIN = 0x00008410, LENGTH = 0x00037BF0 + m_data (RW) : ORIGIN = 0x1FFFE000, LENGTH = 0x00008000 +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into internal flash */ + .interrupts : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } > m_interrupts + + .flash_config : + { + . = ALIGN(4); + KEEP(*(.FlashConfig)) /* Flash Configuration Field (FCF) */ + . = ALIGN(4); + } > m_flash_config + + /* The program code and other data goes into internal flash */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + KEEP (*(.init)) + KEEP (*(.fini)) + . = ALIGN(4); + } > m_text + + .ARM.extab : + { + *(.ARM.extab* .gnu.linkonce.armextab.*) + } > m_text + + .ARM : + { + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + } > m_text + + .ctors : + { + __CTOR_LIST__ = .; + /* gcc uses crtbegin.o to find the start of + the constructors, so we make sure it is + first. Because this is a wildcard, it + doesn't matter if the user does not + actually link against crtbegin.o; the + linker won't look for a file to match a + wildcard. The wildcard also means that it + doesn't matter which directory crtbegin.o + is in. */ + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + /* We don't want to include the .ctor section from + from the crtend.o file until after the sorted ctors. + The .ctor section from the crtend file contains the + end of ctors marker and it must be last */ + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + __CTOR_END__ = .; + } > m_text + + .dtors : + { + __DTOR_LIST__ = .; + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE(*crtend?.o *crtend.o) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + __DTOR_END__ = .; + } > m_text + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } > m_text + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + } > m_text + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + } > m_text + + __etext = .; /* define a global symbol at end of code */ + __DATA_ROM = .; /* Symbol is used by startup for data initialization */ + + /* reserve MTB memory at the beginning of m_data */ + .mtb : /* MTB buffer address as defined by the hardware */ + { + . = ALIGN(8); + _mtb_start = .; + KEEP(*(.mtb_buf)) /* need to KEEP Micro Trace Buffer as not referenced by application */ + . = ALIGN(8); + _mtb_end = .; + } > m_data + + .data : AT(__DATA_ROM) + { + . = ALIGN(4); + __DATA_RAM = .; + __data_start__ = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + KEEP(*(.jcr*)) + . = ALIGN(4); + __data_end__ = .; /* define a global symbol at data end */ + } > m_data + + __DATA_END = __DATA_ROM + (__data_end__ - __data_start__); + text_end = ORIGIN(m_text) + LENGTH(m_text); + ASSERT(__DATA_END <= text_end, "region m_text overflowed with text and data") + + /* Uninitialized data section */ + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + . = ALIGN(4); + __START_BSS = .; + __bss_start__ = .; + *(.bss) + *(.bss*) + *(COMMON) + . = ALIGN(4); + __bss_end__ = .; + __END_BSS = .; + } > m_data + + .heap : + { + . = ALIGN(8); + __end__ = .; + PROVIDE(end = .); + __HeapBase = .; + . += HEAP_SIZE; + __HeapLimit = .; + __heap_limit = .; /* Add for _sbrk */ + } > m_data + + .stack : + { + . = ALIGN(8); + . += STACK_SIZE; + } > m_data + + /* Initializes stack on the end of block */ + __StackTop = ORIGIN(m_data) + LENGTH(m_data); + __StackLimit = __StackTop - STACK_SIZE; + PROVIDE(__stack = __StackTop); + + .ARM.attributes 0 : { *(.ARM.attributes) } + + ASSERT(__StackLimit >= __HeapLimit, "region m_data overflowed with stack and heap") +} + diff --git a/hw/bsp/kuiic/board.h b/hw/bsp/kuiic/board.h new file mode 100644 index 000000000..78ad83a2e --- /dev/null +++ b/hw/bsp/kuiic/board.h @@ -0,0 +1,45 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2019, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + + +#ifndef BOARD_H_ +#define BOARD_H_ + +#include "fsl_device_registers.h" + +// LED +#define LED_PIN_CLOCK kCLOCK_PortA +#define LED_GPIO GPIOA +#define LED_PORT PORTA +#define LED_PIN 2 +#define LED_STATE_ON 1 + +// UART +#define UART_PORT LPUART1 +#define UART_PIN_RX 3u +#define UART_PIN_TX 0u + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/kuiic/board.mk b/hw/bsp/kuiic/board.mk new file mode 100644 index 000000000..39e9d9deb --- /dev/null +++ b/hw/bsp/kuiic/board.mk @@ -0,0 +1,52 @@ +SDK_DIR = hw/mcu/nxp/mcux-sdk +DEPS_SUBMODULES += $(SDK_DIR) tools/uf2 + +# This board uses TinyUF2 for updates +UF2_FAMILY_ID = 0x7f83e793 + +CFLAGS += \ + -mthumb \ + -mabi=aapcs \ + -mcpu=cortex-m0plus \ + -DCPU_K32L2B31VLH0A \ + -DCFG_TUSB_MCU=OPT_MCU_K32L2BXX + +# mcu driver cause following warnings +CFLAGS += -Wno-error=unused-parameter + +MCU_DIR = $(SDK_DIR)/devices/K32L2B31A + +# All source paths should be relative to the top level. +LD_FILE = /hw/bsp/$(BOARD)/K32L2B31xxxxA_flash.ld + +SRC_C += \ + src/portable/nxp/khci/dcd_khci.c \ + $(MCU_DIR)/system_K32L2B31A.c \ + $(MCU_DIR)/drivers/fsl_clock.c \ + $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ + $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c + +INC += \ + $(TOP)/hw/bsp/$(BOARD) \ + $(TOP)/$(SDK_DIR)/CMSIS/Include \ + $(TOP)/$(SDK_DIR)/drivers/smc \ + $(TOP)/$(SDK_DIR)/drivers/common \ + $(TOP)/$(SDK_DIR)/drivers/gpio \ + $(TOP)/$(SDK_DIR)/drivers/port \ + $(TOP)/$(SDK_DIR)/drivers/lpuart \ + $(TOP)/$(MCU_DIR) \ + $(TOP)/$(MCU_DIR)/drivers + +SRC_S += $(MCU_DIR)/gcc/startup_K32L2B31A.S + +# For freeRTOS port source +FREERTOS_PORT = ARM_CM0 + +# For flash-jlink target +JLINK_DEVICE = MKL25Z128xxx4 + +# For flash-pyocd target +PYOCD_TARGET = K32L2B + +# flash using pyocd +flash: flash-pyocd diff --git a/hw/bsp/kuiic/kuiic.c b/hw/bsp/kuiic/kuiic.c new file mode 100644 index 000000000..737ef3f5c --- /dev/null +++ b/hw/bsp/kuiic/kuiic.c @@ -0,0 +1,203 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2018, hathach (tinyusb.org) + * Copyright (c) 2020, Koji Kitayama + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "../board.h" +#include "board.h" +#include "fsl_smc.h" +#include "fsl_gpio.h" +#include "fsl_port.h" +#include "fsl_clock.h" +#include "fsl_lpuart.h" + +/******************************************************************************* + * Definitions + ******************************************************************************/ +#define SIM_OSC32KSEL_LPO_CLK 3U /*!< OSC32KSEL select: LPO clock */ +#define SOPT5_LPUART1RXSRC_LPUART_RX 0x00u /*!<@brief LPUART1 Receive Data Source Select: LPUART_RX pin */ +#define SOPT5_LPUART1TXSRC_LPUART_TX 0x00u /*!<@brief LPUART1 Transmit Data Source Select: LPUART_TX pin */ +#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ + +/******************************************************************************* + * Variables + ******************************************************************************/ +/* System clock frequency. */ +extern uint32_t SystemCoreClock; + +/******************************************************************************* + * Variables for BOARD_BootClockRUN configuration + ******************************************************************************/ +const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN = { + .outSrc = kMCGLITE_ClkSrcHirc, /* MCGOUTCLK source is HIRC */ + .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ + .ircs = kMCGLITE_Lirc8M, /* Slow internal reference (LIRC) 8 MHz clock selected */ + .fcrdiv = kMCGLITE_LircDivBy1, /* Low-frequency Internal Reference Clock Divider: divided by 1 */ + .lircDiv2 = kMCGLITE_LircDivBy1, /* Second Low-frequency Internal Reference Clock Divider: divided by 1 */ + .hircEnableInNotHircMode = true, /* HIRC source is enabled */ +}; +const sim_clock_config_t simConfig_BOARD_BootClockRUN = { + .er32kSrc = SIM_OSC32KSEL_LPO_CLK, /* OSC32KSEL select: LPO clock */ + .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ +}; + +/******************************************************************************* + * Code for BOARD_BootClockRUN configuration + ******************************************************************************/ +void BOARD_BootClockRUN(void) +{ + /* Set the system clock dividers in SIM to safe value. */ + CLOCK_SetSimSafeDivs(); + /* Set MCG to HIRC mode. */ + CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockRUN); + /* Set the clock configuration in SIM module. */ + CLOCK_SetSimConfig(&simConfig_BOARD_BootClockRUN); + /* Set SystemCoreClock variable. */ + SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; +} + + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB0_IRQHandler(void) +{ + tud_int_handler(0); +} + +void board_init(void) +{ + /* Enable port clocks for GPIO pins */ + CLOCK_EnableClock(kCLOCK_PortA); + CLOCK_EnableClock(kCLOCK_PortB); + CLOCK_EnableClock(kCLOCK_PortC); + CLOCK_EnableClock(kCLOCK_PortD); + CLOCK_EnableClock(kCLOCK_PortE); + + + gpio_pin_config_t led_config = { kGPIO_DigitalOutput, 1 }; + GPIO_PinInit(GPIOA, 1U, &led_config); + PORT_SetPinMux(PORTA, 1U, kPORT_MuxAsGpio); + led_config.outputLogic = 0; + GPIO_PinInit(GPIOA, 2U, &led_config); + PORT_SetPinMux(PORTA, 2U, kPORT_MuxAsGpio); + +#ifdef BUTTON_PIN + gpio_pin_config_t button_config = { kGPIO_DigitalInput, 0 }; + GPIO_PinInit(BUTTON_GPIO, BUTTON_PIN, &button_config); + const port_pin_config_t BUTTON_CFG = { + kPORT_PullUp, + kPORT_FastSlewRate, + kPORT_PassiveFilterDisable, + kPORT_LowDriveStrength, + kPORT_MuxAsGpio + }; + PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); +#endif + + /* PORTC3 is configured as LPUART0_RX */ + PORT_SetPinMux(PORTC, 3U, kPORT_MuxAlt3); + /* PORTA2 (pin 24) is configured as LPUART0_TX */ + PORT_SetPinMux(PORTE, 0U, kPORT_MuxAlt3); + + SIM->SOPT5 = ((SIM->SOPT5 & + /* Mask bits to zero which are setting */ + (~(SIM_SOPT5_LPUART1TXSRC_MASK | SIM_SOPT5_LPUART1RXSRC_MASK))) + /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ + | SIM_SOPT5_LPUART1TXSRC(SOPT5_LPUART1TXSRC_LPUART_TX) + /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ + | SIM_SOPT5_LPUART1RXSRC(SOPT5_LPUART1RXSRC_LPUART_RX)); + + BOARD_BootClockRUN(); + SystemCoreClockUpdate(); + CLOCK_SetLpuart1Clock(1); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); +#endif + + lpuart_config_t uart_config; + LPUART_GetDefaultConfig(&uart_config); + uart_config.baudRate_Bps = CFG_BOARD_UART_BAUDRATE; + uart_config.enableTx = true; + uart_config.enableRx = true; + LPUART_Init(UART_PORT, &uart_config, CLOCK_GetFreq(kCLOCK_McgIrc48MClk)); + + // USB + CLOCK_EnableUsbfs0Clock(kCLOCK_UsbSrcIrc48M, 48000000U); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) +{ + if (state) { + LED_GPIO->PDDR |= GPIO_FIT_REG((1UL << LED_PIN)); + } else { + LED_GPIO->PDDR &= GPIO_FIT_REG(~(1UL << LED_PIN)); + } +// GPIO_PinWrite(GPIOA, 1, state ? LED_STATE_ON : (1-LED_STATE_ON) ); +// GPIO_PinWrite(GPIOA, 2, state ? (1-LED_STATE_ON) : LED_STATE_ON ); +} + +uint32_t board_button_read(void) +{ +#ifdef BUTTON_PIN + return BUTTON_STATE_ACTIVE == GPIO_PinRead(BUTTON_GPIO, BUTTON_PIN); +#else + return 0; +#endif +} + +int board_uart_read(uint8_t* buf, int len) +{ + LPUART_ReadBlocking(UART_PORT, buf, len); + return len; +} + +int board_uart_write(void const * buf, int len) +{ + LPUART_WriteBlocking(UART_PORT, (uint8_t const*) buf, len); + return len; +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; +void SysTick_Handler(void) +{ + system_ticks++; +} + +uint32_t board_millis(void) +{ + return system_ticks; +} +#endif diff --git a/hw/bsp/msp432e4/family.c b/hw/bsp/msp432e4/family.c index 7114da693..262dc1d30 100644 --- a/hw/bsp/msp432e4/family.c +++ b/hw/bsp/msp432e4/family.c @@ -33,7 +33,12 @@ //--------------------------------------------------------------------+ void USB0_IRQHandler(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } //--------------------------------------------------------------------+ @@ -42,6 +47,7 @@ void USB0_IRQHandler(void) void board_init(void) { + unsigned bits; /* Turn off power domains that unused peripherals belong to */ SYSCTL->PCCAN = 0u; #ifdef __MCU_HAS_LCD0__ @@ -80,20 +86,23 @@ void board_init(void) #endif /* USR_LED1 ON1 */ - SYSCTL->RCGCGPIO |= TU_BIT(CLK_LED); - while (!(SYSCTL->PRGPIO & TU_BIT(CLK_LED))) ; + bits = TU_BIT(CLK_LED); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_LED->DIR = TU_BIT(GPIO_LED_PIN); GPIO_LED->DEN = TU_BIT(GPIO_LED_PIN); /* USR_SW1 PJ0 */ - SYSCTL->RCGCGPIO |= TU_BIT(CLK_BUTTON); - while (!(SYSCTL->PRGPIO & TU_BIT(CLK_BUTTON))) ; + bits = TU_BIT(CLK_BUTTON); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIO_BUTTON->PUR = TU_BIT(GPIO_BUTTON_PIN); GPIO_BUTTON->DEN = TU_BIT(GPIO_BUTTON_PIN); /* UART PA0,1 */ - SYSCTL->RCGCGPIO |= 1u << 0; - while (!(SYSCTL->PRGPIO & (1u << 0))) ; + bits = TU_BIT(0); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; GPIOA->AFSEL = 3u; GPIOA->PCTL = 0x11u; GPIOA->DEN = 3u; @@ -107,11 +116,22 @@ void board_init(void) UART0->CC = UART_CC_CS_PIOSC; /* Set the baud clock to PIOSC */ UART0->CTL = UART_CTL_RXE | UART_CTL_TXE | UART_CTL_UARTEN; - /* USB PB1(VBUS) PL6,7(DP,DM) */ - SYSCTL->RCGCGPIO |= (1u << 1) | (1u << 10); - while (((1u << 1) | (1u << 10)) != (SYSCTL->PRGPIO & ((1u << 1) | (1u << 10)))) ; - GPIOB->AMSEL = 1u << 1; - GPIOL->AMSEL = (1u << 6) | (1u << 7); + /* USB PB0(ID) PB1(VBUS) PL6,7(DP,DM) */ + bits = TU_BIT(1) | TU_BIT(10); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; + GPIOB->AMSEL = TU_BIT(0) | TU_BIT(1); + GPIOL->AMSEL = TU_BIT(6) | TU_BIT(7); + +#if TUSB_OPT_HOST_ENABLED + /* USB PD6(EPEN) */ + bits = TU_BIT(3); + SYSCTL->RCGCGPIO |= bits; + while (bits != (SYSCTL->RCGCGPIO & bits)) ; + GPIOD->AFSEL = TU_BIT(6); + GPIOD->PCTL = 0x05000000u; + GPIOD->DEN = TU_BIT(6); +#endif SYSCTL->RCGCUSB = 1u; /* Open the clock gate for SYSCLK */ while (!(SYSCTL->PRUSB & (1u << 0))) ; @@ -124,6 +144,13 @@ void board_init(void) USB0->CC = USB_CC_CLKEN | (3u << USB_CC_CLKDIV_S); /* 60MHz = 240MHz / 4 */ __DMB(); /* Wait for completion of opening of the clock gate */ +#if TUSB_OPT_HOST_ENABLED + USB0->GPCS = USB_GPCS_DEVMOD_OTG; + USB0->EPC = USB_EPC_EPENDE | USB_EPC_EPEN_HIGH; +#endif +#if TUSB_OPT_DEVICE_ENABLED + USB0->GPCS = USB_GPCS_DEVMOD_DEVVBUS; +#endif } //--------------------------------------------------------------------+ diff --git a/hw/bsp/msp432e4/family.mk b/hw/bsp/msp432e4/family.mk index b664c4c1b..e3cb90abc 100644 --- a/hw/bsp/msp432e4/family.mk +++ b/hw/bsp/msp432e4/family.mk @@ -23,6 +23,7 @@ MCU_DIR = hw/mcu/ti/msp432e4 SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ $(MCU_DIR)/Source/system_msp432e401y.c INC += \ diff --git a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk b/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk deleted file mode 100644 index 897342479..000000000 --- a/hw/bsp/raspberrypi4/boards/raspberrypi_cm4/board.mk +++ /dev/null @@ -1 +0,0 @@ -CFLAGS += -DBCM_VERSION=2711 diff --git a/hw/bsp/samd21/boards/curiosity_nano/.skip.device.net_lwip_webserver b/hw/bsp/samd21/boards/curiosity_nano/.skip.device.net_lwip_webserver deleted file mode 100644 index e69de29bb..000000000 diff --git a/hw/bsp/samd21/family.c b/hw/bsp/samd21/family.c index cead582e9..494dc393a 100644 --- a/hw/bsp/samd21/family.c +++ b/hw/bsp/samd21/family.c @@ -47,7 +47,7 @@ void USB_Handler(void) //--------------------------------------------------------------------+ // UART support //--------------------------------------------------------------------+ -void uart_init(void); +static void uart_init(void); //--------------------------------------------------------------------+ // MACRO TYPEDEF CONSTANT ENUM DECLARATION @@ -152,7 +152,7 @@ uint32_t board_button_read(void) #define BOARD_SERCOM2(n) SERCOM ## n #define BOARD_SERCOM(n) BOARD_SERCOM2(n) -void uart_init(void) +static void uart_init(void) { #if UART_SERCOM == 0 gpio_set_pin_function(PIN_PA06, PINMUX_PA06D_SERCOM0_PAD2); @@ -217,7 +217,7 @@ int board_uart_write(void const * buf, int len) } #else // ! defined(UART_SERCOM) -void uart_init(void) +static void uart_init(void) { } diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld new file mode 100644 index 000000000..2dc277c77 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/STM32F439ZITX_FLASH.ld @@ -0,0 +1,206 @@ +/* +****************************************************************************** +** +** @file : LinkerScript.ld +** +** @author : Auto-generated by STM32CubeIDE +** +** Abstract : Linker script for NUCLEO-F439ZI Board embedding STM32F439ZITx Device from stm32f4 series +** 2048Kbytes FLASH +** 64Kbytes CCMRAM +** 192Kbytes RAM +** +** Set heap size, stack size and stack location according +** to application requirements. +** +** Set memory bank area and size if external memory is used +** +** Target : STMicroelectronics STM32 +** +** Distribution: The file is distributed as is, without any warranty +** of any kind. +** +****************************************************************************** +** @attention +** +** Copyright (c) 2021 STMicroelectronics. +** All rights reserved. +** +** This software is licensed under terms that can be found in the LICENSE file +** in the root directory of this software component. +** If no LICENSE file comes with this software, it is provided AS-IS. +** +****************************************************************************** +*/ + +/* Entry Point */ +ENTRY(Reset_Handler) + +/* Highest address of the user mode stack */ +_estack = ORIGIN(RAM) + LENGTH(RAM); /* end of "RAM" Ram type memory */ + +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Memories definition */ +MEMORY +{ + CCMRAM (xrw) : ORIGIN = 0x10000000, LENGTH = 64K + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 192K + FLASH (rx) : ORIGIN = 0x8000000, LENGTH = 2048K +} + +/* Sections */ +SECTIONS +{ + /* The startup code into "FLASH" Rom type memory */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data into "FLASH" Rom type memory */ + .text : + { + . = ALIGN(4); + *(.text) /* .text sections (code) */ + *(.text*) /* .text* sections (code) */ + *(.glue_7) /* glue arm to thumb code */ + *(.glue_7t) /* glue thumb to arm code */ + *(.eh_frame) + + KEEP (*(.init)) + KEEP (*(.fini)) + + . = ALIGN(4); + _etext = .; /* define a global symbols at end of code */ + } >FLASH + + /* Constant data into "FLASH" Rom type memory */ + .rodata : + { + . = ALIGN(4); + *(.rodata) /* .rodata sections (constants, strings, etc.) */ + *(.rodata*) /* .rodata* sections (constants, strings, etc.) */ + . = ALIGN(4); + } >FLASH + + .ARM.extab : { + . = ALIGN(4); + *(.ARM.extab* .gnu.linkonce.armextab.*) + . = ALIGN(4); + } >FLASH + + .ARM : { + . = ALIGN(4); + __exidx_start = .; + *(.ARM.exidx*) + __exidx_end = .; + . = ALIGN(4); + } >FLASH + + .preinit_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array*)) + PROVIDE_HIDDEN (__preinit_array_end = .); + . = ALIGN(4); + } >FLASH + + .init_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT(.init_array.*))) + KEEP (*(.init_array*)) + PROVIDE_HIDDEN (__init_array_end = .); + . = ALIGN(4); + } >FLASH + + .fini_array : + { + . = ALIGN(4); + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT(.fini_array.*))) + KEEP (*(.fini_array*)) + PROVIDE_HIDDEN (__fini_array_end = .); + . = ALIGN(4); + } >FLASH + + /* Used by the startup to initialize data */ + _sidata = LOADADDR(.data); + + /* Initialized data sections into "RAM" Ram type memory */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + *(.RamFunc) /* .RamFunc sections */ + *(.RamFunc*) /* .RamFunc* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + + } >RAM AT> FLASH + + _siccmram = LOADADDR(.ccmram); + + /* CCM-RAM section + * + * IMPORTANT NOTE! + * If initialized variables will be placed in this section, + * the startup code needs to be modified to copy the init-values. + */ + .ccmram : + { + . = ALIGN(4); + _sccmram = .; /* create a global symbol at ccmram start */ + *(.ccmram) + *(.ccmram*) + + . = ALIGN(4); + _eccmram = .; /* create a global symbol at ccmram end */ + } >CCMRAM AT> FLASH + + /* Uninitialized data section into "RAM" Ram type memory */ + . = ALIGN(4); + .bss : + { + /* This is used by the startup in order to initialize the .bss section */ + _sbss = .; /* define a global symbol at bss start */ + __bss_start__ = _sbss; + *(.bss) + *(.bss*) + *(COMMON) + + . = ALIGN(4); + _ebss = .; /* define a global symbol at bss end */ + __bss_end__ = _ebss; + } >RAM + + /* User_heap_stack section, used to check that there is enough "RAM" Ram type memory left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + /* Remove information from the compiler libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h new file mode 100644 index 000000000..e5a822426 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.h @@ -0,0 +1,108 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// LED +#define LED_PORT GPIOB +#define LED_PIN GPIO_PIN_14 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART3 +#define UART_GPIO_PORT GPIOD +#define UART_GPIO_AF GPIO_AF7_USART3 +#define UART_TX_PIN GPIO_PIN_8 +#define UART_RX_PIN GPIO_PIN_9 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void board_clock_init(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct; + RCC_OscInitTypeDef RCC_OscInitStruct; + + /* Enable Power Control clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /* The voltage scaling allows optimizing the power consumption when the + * device is clocked below the maximum system frequency, to update the + * voltage scaling value regarding system frequency refer to product + * datasheet. */ + __HAL_PWR_VOLTAGESCALING_CONFIG(PWR_REGULATOR_VOLTAGE_SCALE1); + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = HSE_VALUE/1000000; + RCC_OscInitStruct.PLL.PLLN = 336; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = 7; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* Select PLL as system clock source and configure the HCLK, PCLK1 and PCLK2 + * clocks dividers */ + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | + RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV4; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV2; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_5); + + // Enable clocks for LED, Button, Uart + __HAL_RCC_GPIOB_CLK_ENABLE(); + __HAL_RCC_GPIOC_CLK_ENABLE(); + __HAL_RCC_GPIOD_CLK_ENABLE(); + __HAL_RCC_USART3_CLK_ENABLE(); +} + +static inline void board_vbus_sense_init(void) +{ + // Enable VBUS sense (B device) via pin PA9 + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_NOVBUSSENS; + USB_OTG_FS->GCCFG |= USB_OTG_GCCFG_VBUSBSEN; +} + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk new file mode 100644 index 000000000..b7b36a8a6 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/board.mk @@ -0,0 +1,11 @@ +CFLAGS += -DSTM32F439xx + +LD_FILE = $(BOARD_PATH)/STM32F439ZITX_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32f439xx.s + +# For flash-jlink target +JLINK_DEVICE = stm32f439zi + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h b/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h new file mode 100644 index 000000000..a2c11d717 --- /dev/null +++ b/hw/bsp/stm32f4/boards/stm32f439nucleo/stm32f4xx_hal_conf.h @@ -0,0 +1,486 @@ +/** + ****************************************************************************** + * @file stm32f4xx_hal_conf_template.h + * @author MCD Application Team + * @brief HAL configuration file + ****************************************************************************** + * @attention + * + *

© Copyright (c) 2017 STMicroelectronics. + * All rights reserved.

+ * + * This software component is licensed by ST under BSD 3-Clause license, + * the "License"; You may not use this file except in compliance with the + * License. You may obtain a copy of the License at: + * opensource.org/licenses/BSD-3-Clause + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef __STM32F4xx_HAL_CONF_H +#define __STM32F4xx_HAL_CONF_H + +#ifdef __cplusplus + extern "C" { +#endif + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/* ########################## Module Selection ############################## */ +/** + * @brief This is the list of modules to be used in the HAL driver + */ +#define HAL_MODULE_ENABLED +/* #define HAL_ADC_MODULE_ENABLED */ +/* #define HAL_CAN_MODULE_ENABLED */ +/* #define HAL_CAN_LEGACY_MODULE_ENABLED */ +/* #define HAL_CRC_MODULE_ENABLED */ +/* #define HAL_CEC_MODULE_ENABLED */ +/* #define HAL_CRYP_MODULE_ENABLED */ +/* #define HAL_DAC_MODULE_ENABLED */ +/* #define HAL_DCMI_MODULE_ENABLED */ +#define HAL_DMA_MODULE_ENABLED +/* #define HAL_DMA2D_MODULE_ENABLED */ +/* #define HAL_ETH_MODULE_ENABLED */ +#define HAL_FLASH_MODULE_ENABLED +/* #define HAL_NAND_MODULE_ENABLED */ +/* #define HAL_NOR_MODULE_ENABLED */ +/* #define HAL_PCCARD_MODULE_ENABLED */ +/* #define HAL_SRAM_MODULE_ENABLED */ +/* #define HAL_SDRAM_MODULE_ENABLED */ +/* #define HAL_HASH_MODULE_ENABLED */ +#define HAL_GPIO_MODULE_ENABLED +/* #define HAL_EXTI_MODULE_ENABLED */ +/* #define HAL_I2C_MODULE_ENABLED */ +/* #define HAL_SMBUS_MODULE_ENABLED */ +/* #define HAL_I2S_MODULE_ENABLED */ +/* #define HAL_IWDG_MODULE_ENABLED */ +/* #define HAL_LTDC_MODULE_ENABLED */ +/* #define HAL_DSI_MODULE_ENABLED */ +#define HAL_PWR_MODULE_ENABLED +/* #define HAL_QSPI_MODULE_ENABLED */ +#define HAL_RCC_MODULE_ENABLED +/* #define HAL_RNG_MODULE_ENABLED */ +/* #define HAL_RTC_MODULE_ENABLED */ +/* #define HAL_SAI_MODULE_ENABLED */ +/* #define HAL_SD_MODULE_ENABLED */ +// #define HAL_SPI_MODULE_ENABLED +/* #define HAL_TIM_MODULE_ENABLED */ +#define HAL_UART_MODULE_ENABLED +/* #define HAL_USART_MODULE_ENABLED */ +/* #define HAL_IRDA_MODULE_ENABLED */ +/* #define HAL_SMARTCARD_MODULE_ENABLED */ +/* #define HAL_WWDG_MODULE_ENABLED */ +#define HAL_CORTEX_MODULE_ENABLED +/* #define HAL_PCD_MODULE_ENABLED */ +/* #define HAL_HCD_MODULE_ENABLED */ +/* #define HAL_FMPI2C_MODULE_ENABLED */ +/* #define HAL_SPDIFRX_MODULE_ENABLED */ +/* #define HAL_DFSDM_MODULE_ENABLED */ +/* #define HAL_LPTIM_MODULE_ENABLED */ +/* #define HAL_MMC_MODULE_ENABLED */ + +/* ########################## HSE/HSI Values adaptation ##################### */ +/** + * @brief Adjust the value of External High Speed oscillator (HSE) used in your application. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSE is used as system clock source, directly or through the PLL). + */ +#if !defined (HSE_VALUE) + #define HSE_VALUE (8000000U) /*!< Value of the External oscillator in Hz */ +#endif /* HSE_VALUE */ + +#if !defined (HSE_STARTUP_TIMEOUT) + #define HSE_STARTUP_TIMEOUT (100U) /*!< Time out for HSE start up, in ms */ +#endif /* HSE_STARTUP_TIMEOUT */ + +/** + * @brief Internal High Speed oscillator (HSI) value. + * This value is used by the RCC HAL module to compute the system frequency + * (when HSI is used as system clock source, directly or through the PLL). + */ +#if !defined (HSI_VALUE) + #define HSI_VALUE (16000000U) /*!< Value of the Internal oscillator in Hz*/ +#endif /* HSI_VALUE */ + +/** + * @brief Internal Low Speed oscillator (LSI) value. + */ +#if !defined (LSI_VALUE) + #define LSI_VALUE (32000U) +#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz + The real value may vary depending on the variations + in voltage and temperature. */ +/** + * @brief External Low Speed oscillator (LSE) value. + */ +#if !defined (LSE_VALUE) + #define LSE_VALUE (32768U) /*!< Value of the External Low Speed oscillator in Hz */ +#endif /* LSE_VALUE */ + +#if !defined (LSE_STARTUP_TIMEOUT) + #define LSE_STARTUP_TIMEOUT (5000U) /*!< Time out for LSE start up, in ms */ +#endif /* LSE_STARTUP_TIMEOUT */ + +/** + * @brief External clock source for I2S peripheral + * This value is used by the I2S HAL module to compute the I2S clock source + * frequency, this source is inserted directly through I2S_CKIN pad. + */ +#if !defined (EXTERNAL_CLOCK_VALUE) + #define EXTERNAL_CLOCK_VALUE (12288000U) /*!< Value of the External oscillator in Hz*/ +#endif /* EXTERNAL_CLOCK_VALUE */ + +/* Tip: To avoid modifying this file each time you need to use different HSE, + === you can define the HSE value in your toolchain compiler preprocessor. */ + +/* ########################### System Configuration ######################### */ +/** + * @brief This is the HAL system configuration section + */ +#define VDD_VALUE (3300U) /*!< Value of VDD in mv */ +#define TICK_INT_PRIORITY (0x0FU) /*!< tick interrupt priority */ +#define USE_RTOS 0U +#define PREFETCH_ENABLE 1U +#define INSTRUCTION_CACHE_ENABLE 1U +#define DATA_CACHE_ENABLE 1U + +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */ +#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */ +#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */ +#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */ +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */ +#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */ +#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */ +#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */ +#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */ +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */ +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */ +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */ +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */ +#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */ +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */ +#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */ +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */ +#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */ +#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */ +#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */ +#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */ +#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */ +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */ +#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */ +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */ +#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */ +#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */ +#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */ +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */ +#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */ +#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */ +#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */ +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */ +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */ +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */ +#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */ +#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */ +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */ + +/* ########################## Assert Selection ############################## */ +/** + * @brief Uncomment the line below to expanse the "assert_param" macro in the + * HAL drivers code + */ +/* #define USE_FULL_ASSERT 1U */ + +/* ################## Ethernet peripheral configuration ##################### */ + +/* Section 1 : Ethernet peripheral configuration */ + +/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */ +#define MAC_ADDR0 2U +#define MAC_ADDR1 0U +#define MAC_ADDR2 0U +#define MAC_ADDR3 0U +#define MAC_ADDR4 0U +#define MAC_ADDR5 0U + +/* Definition of the Ethernet driver buffers size and count */ +#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */ +#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */ +#define ETH_RXBUFNB 4U /* 4 Rx buffers of size ETH_RX_BUF_SIZE */ +#define ETH_TXBUFNB 4U /* 4 Tx buffers of size ETH_TX_BUF_SIZE */ + +/* Section 2: PHY configuration section */ + +/* LAN8742A_PHY_ADDRESS Address*/ +#define LAN8742A_PHY_ADDRESS 0U +/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/ +#define PHY_RESET_DELAY 0x000000FFU +/* PHY Configuration delay */ +#define PHY_CONFIG_DELAY 0x00000FFFU + +#define PHY_READ_TO 0x0000FFFFU +#define PHY_WRITE_TO 0x0000FFFFU + +/* Section 3: Common PHY Registers */ + +#define PHY_BCR ((uint16_t)0x00U) /*!< Transceiver Basic Control Register */ +#define PHY_BSR ((uint16_t)0x01U) /*!< Transceiver Basic Status Register */ + +#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */ +#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */ +#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */ +#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */ +#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */ +#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */ +#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */ +#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */ +#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */ +#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */ + +#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */ +#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */ +#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */ + +/* Section 4: Extended PHY Registers */ +#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */ + +#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */ +#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */ + +#define PHY_ISFR ((uint16_t)0x001DU) /*!< PHY Interrupt Source Flag register Offset */ +#define PHY_ISFR_INT4 ((uint16_t)0x000BU) /*!< PHY Link down inturrupt */ + +/* ################## SPI peripheral configuration ########################## */ + +/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver +* Activated: CRC code is present inside driver +* Deactivated: CRC code cleaned from driver +*/ + +#define USE_SPI_CRC 0U + +/* Includes ------------------------------------------------------------------*/ +/** + * @brief Include module's header file + */ + +#ifdef HAL_RCC_MODULE_ENABLED + #include "stm32f4xx_hal_rcc.h" +#endif /* HAL_RCC_MODULE_ENABLED */ + +#ifdef HAL_GPIO_MODULE_ENABLED + #include "stm32f4xx_hal_gpio.h" +#endif /* HAL_GPIO_MODULE_ENABLED */ + +#ifdef HAL_EXTI_MODULE_ENABLED + #include "stm32f4xx_hal_exti.h" +#endif /* HAL_EXTI_MODULE_ENABLED */ + +#ifdef HAL_DMA_MODULE_ENABLED + #include "stm32f4xx_hal_dma.h" +#endif /* HAL_DMA_MODULE_ENABLED */ + +#ifdef HAL_CORTEX_MODULE_ENABLED + #include "stm32f4xx_hal_cortex.h" +#endif /* HAL_CORTEX_MODULE_ENABLED */ + +#ifdef HAL_ADC_MODULE_ENABLED + #include "stm32f4xx_hal_adc.h" +#endif /* HAL_ADC_MODULE_ENABLED */ + +#ifdef HAL_CAN_MODULE_ENABLED + #include "stm32f4xx_hal_can.h" +#endif /* HAL_CAN_MODULE_ENABLED */ + +#ifdef HAL_CAN_LEGACY_MODULE_ENABLED + #include "stm32f4xx_hal_can_legacy.h" +#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */ + +#ifdef HAL_CRC_MODULE_ENABLED + #include "stm32f4xx_hal_crc.h" +#endif /* HAL_CRC_MODULE_ENABLED */ + +#ifdef HAL_CRYP_MODULE_ENABLED + #include "stm32f4xx_hal_cryp.h" +#endif /* HAL_CRYP_MODULE_ENABLED */ + +#ifdef HAL_DMA2D_MODULE_ENABLED + #include "stm32f4xx_hal_dma2d.h" +#endif /* HAL_DMA2D_MODULE_ENABLED */ + +#ifdef HAL_DAC_MODULE_ENABLED + #include "stm32f4xx_hal_dac.h" +#endif /* HAL_DAC_MODULE_ENABLED */ + +#ifdef HAL_DCMI_MODULE_ENABLED + #include "stm32f4xx_hal_dcmi.h" +#endif /* HAL_DCMI_MODULE_ENABLED */ + +#ifdef HAL_ETH_MODULE_ENABLED + #include "stm32f4xx_hal_eth.h" +#endif /* HAL_ETH_MODULE_ENABLED */ + +#ifdef HAL_FLASH_MODULE_ENABLED + #include "stm32f4xx_hal_flash.h" +#endif /* HAL_FLASH_MODULE_ENABLED */ + +#ifdef HAL_SRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sram.h" +#endif /* HAL_SRAM_MODULE_ENABLED */ + +#ifdef HAL_NOR_MODULE_ENABLED + #include "stm32f4xx_hal_nor.h" +#endif /* HAL_NOR_MODULE_ENABLED */ + +#ifdef HAL_NAND_MODULE_ENABLED + #include "stm32f4xx_hal_nand.h" +#endif /* HAL_NAND_MODULE_ENABLED */ + +#ifdef HAL_PCCARD_MODULE_ENABLED + #include "stm32f4xx_hal_pccard.h" +#endif /* HAL_PCCARD_MODULE_ENABLED */ + +#ifdef HAL_SDRAM_MODULE_ENABLED + #include "stm32f4xx_hal_sdram.h" +#endif /* HAL_SDRAM_MODULE_ENABLED */ + +#ifdef HAL_HASH_MODULE_ENABLED + #include "stm32f4xx_hal_hash.h" +#endif /* HAL_HASH_MODULE_ENABLED */ + +#ifdef HAL_I2C_MODULE_ENABLED + #include "stm32f4xx_hal_i2c.h" +#endif /* HAL_I2C_MODULE_ENABLED */ + +#ifdef HAL_SMBUS_MODULE_ENABLED + #include "stm32f4xx_hal_smbus.h" +#endif /* HAL_SMBUS_MODULE_ENABLED */ + +#ifdef HAL_I2S_MODULE_ENABLED + #include "stm32f4xx_hal_i2s.h" +#endif /* HAL_I2S_MODULE_ENABLED */ + +#ifdef HAL_IWDG_MODULE_ENABLED + #include "stm32f4xx_hal_iwdg.h" +#endif /* HAL_IWDG_MODULE_ENABLED */ + +#ifdef HAL_LTDC_MODULE_ENABLED + #include "stm32f4xx_hal_ltdc.h" +#endif /* HAL_LTDC_MODULE_ENABLED */ + +#ifdef HAL_PWR_MODULE_ENABLED + #include "stm32f4xx_hal_pwr.h" +#endif /* HAL_PWR_MODULE_ENABLED */ + +#ifdef HAL_RNG_MODULE_ENABLED + #include "stm32f4xx_hal_rng.h" +#endif /* HAL_RNG_MODULE_ENABLED */ + +#ifdef HAL_RTC_MODULE_ENABLED + #include "stm32f4xx_hal_rtc.h" +#endif /* HAL_RTC_MODULE_ENABLED */ + +#ifdef HAL_SAI_MODULE_ENABLED + #include "stm32f4xx_hal_sai.h" +#endif /* HAL_SAI_MODULE_ENABLED */ + +#ifdef HAL_SD_MODULE_ENABLED + #include "stm32f4xx_hal_sd.h" +#endif /* HAL_SD_MODULE_ENABLED */ + +#ifdef HAL_SPI_MODULE_ENABLED + #include "stm32f4xx_hal_spi.h" +#endif /* HAL_SPI_MODULE_ENABLED */ + +#ifdef HAL_TIM_MODULE_ENABLED + #include "stm32f4xx_hal_tim.h" +#endif /* HAL_TIM_MODULE_ENABLED */ + +#ifdef HAL_UART_MODULE_ENABLED + #include "stm32f4xx_hal_uart.h" +#endif /* HAL_UART_MODULE_ENABLED */ + +#ifdef HAL_USART_MODULE_ENABLED + #include "stm32f4xx_hal_usart.h" +#endif /* HAL_USART_MODULE_ENABLED */ + +#ifdef HAL_IRDA_MODULE_ENABLED + #include "stm32f4xx_hal_irda.h" +#endif /* HAL_IRDA_MODULE_ENABLED */ + +#ifdef HAL_SMARTCARD_MODULE_ENABLED + #include "stm32f4xx_hal_smartcard.h" +#endif /* HAL_SMARTCARD_MODULE_ENABLED */ + +#ifdef HAL_WWDG_MODULE_ENABLED + #include "stm32f4xx_hal_wwdg.h" +#endif /* HAL_WWDG_MODULE_ENABLED */ + +#ifdef HAL_PCD_MODULE_ENABLED + #include "stm32f4xx_hal_pcd.h" +#endif /* HAL_PCD_MODULE_ENABLED */ + +#ifdef HAL_HCD_MODULE_ENABLED + #include "stm32f4xx_hal_hcd.h" +#endif /* HAL_HCD_MODULE_ENABLED */ + +#ifdef HAL_DSI_MODULE_ENABLED + #include "stm32f4xx_hal_dsi.h" +#endif /* HAL_DSI_MODULE_ENABLED */ + +#ifdef HAL_QSPI_MODULE_ENABLED + #include "stm32f4xx_hal_qspi.h" +#endif /* HAL_QSPI_MODULE_ENABLED */ + +#ifdef HAL_CEC_MODULE_ENABLED + #include "stm32f4xx_hal_cec.h" +#endif /* HAL_CEC_MODULE_ENABLED */ + +#ifdef HAL_FMPI2C_MODULE_ENABLED + #include "stm32f4xx_hal_fmpi2c.h" +#endif /* HAL_FMPI2C_MODULE_ENABLED */ + +#ifdef HAL_SPDIFRX_MODULE_ENABLED + #include "stm32f4xx_hal_spdifrx.h" +#endif /* HAL_SPDIFRX_MODULE_ENABLED */ + +#ifdef HAL_DFSDM_MODULE_ENABLED + #include "stm32f4xx_hal_dfsdm.h" +#endif /* HAL_DFSDM_MODULE_ENABLED */ + +#ifdef HAL_LPTIM_MODULE_ENABLED + #include "stm32f4xx_hal_lptim.h" +#endif /* HAL_LPTIM_MODULE_ENABLED */ + +#ifdef HAL_MMC_MODULE_ENABLED + #include "stm32f4xx_hal_mmc.h" +#endif /* HAL_MMC_MODULE_ENABLED */ + +/* Exported macro ------------------------------------------------------------*/ +#ifdef USE_FULL_ASSERT +/** + * @brief The assert_param macro is used for function's parameters check. + * @param expr If expr is false, it calls assert_failed function + * which reports the name of the source file and the source + * line number of the call that failed. + * If expr is true, it returns no value. + * @retval None + */ + #define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__)) +/* Exported functions ------------------------------------------------------- */ + void assert_failed(uint8_t* file, uint32_t line); +#else + #define assert_param(expr) ((void)0U) +#endif /* USE_FULL_ASSERT */ + + +#ifdef __cplusplus +} +#endif + +#endif /* __STM32F4xx_HAL_CONF_H */ + + +/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/ diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h index fd9d50183..eab0bd5f0 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.h @@ -32,8 +32,8 @@ #endif // G474RE Nucleo does not has usb connection. We need to manually connect -// - PA11 for D+, CN10.14 -// - PA12 for D-, CN10.12 +// - PA12 for D+, CN10.12 +// - PA11 for D-, CN10.14 // LED #define LED_PORT GPIOA @@ -61,32 +61,36 @@ static inline void board_clock_init(void) { RCC_OscInitTypeDef RCC_OscInitStruct = {0}; RCC_ClkInitTypeDef RCC_ClkInitStruct = {0}; + RCC_PeriphCLKInitTypeDef PeriphClkInit = {0}; // Configure the main internal regulator output voltage HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1_BOOST); // Initializes the CPU, AHB and APB busses clocks - RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI; - RCC_OscInitStruct.HSIState = RCC_HSI_ON; - RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; - RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; - RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; - RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; - RCC_OscInitStruct.PLL.PLLN = 85; - RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; - RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; - RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + RCC_OscInitStruct.PLL.PLLM = RCC_PLLM_DIV4; + RCC_OscInitStruct.PLL.PLLN = 50; + RCC_OscInitStruct.PLL.PLLP = RCC_PLLP_DIV2; + RCC_OscInitStruct.PLL.PLLQ = RCC_PLLQ_DIV2; + RCC_OscInitStruct.PLL.PLLR = RCC_PLLR_DIV2; HAL_RCC_OscConfig(&RCC_OscInitStruct); // Initializes the CPU, AHB and APB busses clocks - RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK|RCC_CLOCKTYPE_SYSCLK |RCC_CLOCKTYPE_PCLK1|RCC_CLOCKTYPE_PCLK2; - RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; - RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.ClockType = RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; - HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_8); + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInit.UsbClockSelection = RCC_USBCLKSOURCE_HSI48; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit) ; + #if 0 // TODO need to check if USB clock is enabled /* Enable HSI48 */ memset(&RCC_OscInitStruct, 0, sizeof(RCC_OscInitStruct)); diff --git a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk index 1951fcba0..e41edd3b7 100644 --- a/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk +++ b/hw/bsp/stm32g4/boards/stm32g474nucleo/board.mk @@ -1,4 +1,6 @@ -CFLAGS += -DSTM32G474xx +CFLAGS += \ + -DSTM32G474xx \ + -DHSE_VALUE=24000000 LD_FILE = $(BOARD_PATH)/STM32G474RETx_FLASH.ld diff --git a/hw/bsp/stm32g4/family.c b/hw/bsp/stm32g4/family.c index 318f50746..461dc61a1 100644 --- a/hw/bsp/stm32g4/family.c +++ b/hw/bsp/stm32g4/family.c @@ -118,13 +118,13 @@ void board_init(void) // USB Pins TODO double check USB clock and pin setup // Configure USB DM and DP pins. This is optional, and maintained only for user guidance. -// GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); -// GPIO_InitStruct.Mode = GPIO_MODE_INPUT; -// GPIO_InitStruct.Pull = GPIO_NOPULL; -// GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; -// HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); -// -// __HAL_RCC_USB_CLK_ENABLE(); + GPIO_InitStruct.Pin = (GPIO_PIN_11 | GPIO_PIN_12); + GPIO_InitStruct.Mode = GPIO_MODE_INPUT; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_HIGH; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + + __HAL_RCC_USB_CLK_ENABLE(); board_vbus_sense_init(); } diff --git a/hw/bsp/tm4c123/family.c b/hw/bsp/tm4c123/family.c index 048832dc9..449781ce1 100644 --- a/hw/bsp/tm4c123/family.c +++ b/hw/bsp/tm4c123/family.c @@ -7,7 +7,13 @@ //--------------------------------------------------------------------+ void USB0_Handler(void) { +#if TUSB_OPT_HOST_ENABLED + tuh_int_handler(0); +#endif + +#if TUSB_OPT_DEVICE_ENABLED tud_int_handler(0); +#endif } //--------------------------------------------------------------------+ @@ -23,10 +29,12 @@ static void board_uart_init (void) GPIOA->PCTL |= (1 << 0) | (1 << 4); // Configure the GPIOPCTL register to select UART0 in PA0 and PA1 GPIOA->DEN |= (1 << 0) | (1 << 1); // Enable the digital functionality in PA0 and PA1 - /** BAUDRATE = 9600 bits per second, refer manual for calculation **/ + // BAUDRATE = 115200, with SystemCoreClock = 50 Mhz refer manual for calculation + // - BRDI = SystemCoreClock / (16* baud) + // - BRDF = int(fraction*64 + 0.5) UART0->CTL &= ~(1 << 0); // Disable UART0 by clearing UARTEN bit in the UARTCTL register - UART0->IBRD = 325; // Write the integer portion of the BRD to the UARTIRD register - UART0->FBRD = 33; // Write the fractional portion of the BRD to the UARTFBRD registerer + UART0->IBRD = 27; // Write the integer portion of the BRD to the UARTIRD register + UART0->FBRD = 8; // Write the fractional portion of the BRD to the UARTFBRD registerer UART0->LCRH = (0x3 << 5); // 8-bit, no parity, 1 stop bit UART0->CC = 0x0; // Configure the UART clock source as system clock @@ -40,8 +48,7 @@ static void initialize_board_led (GPIOA_Type *port, uint8_t PinMsk, uint8_t dirm SYSCTL->RCGCGPIO |= (1 << 5); /* Let the clock stabilize */ - while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) - ; + while ( !((SYSCTL->PRGPIO) & (1 << 5)) ) {} /* Port Digital Enable */ port->DEN |= PinMsk; @@ -60,9 +67,13 @@ static void board_switch_init (void) static void WriteGPIOPin (GPIOA_Type *port, uint8_t PinMsk, bool state) { if ( state ) + { port->DATA |= PinMsk; + } else + { port->DATA &= ~(PinMsk); + } } static uint32_t ReadGPIOPin (GPIOA_Type *port, uint8_t pinMsk) @@ -99,8 +110,7 @@ void board_init (void) SYSCTL->RCGCGPIO |= (1u << 3); /* Let the clock stabilize */ - while ( !(SYSCTL->PRGPIO & (1u << 3)) ) - ; + while ( !(SYSCTL->PRGPIO & (1u << 3)) ) {} /* USB IOs to Analog Mode */ GPIOD->AFSEL &= ~((1u << 4) | (1u << 5)); @@ -119,6 +129,7 @@ void board_init (void) /* Initialize board UART */ board_uart_init(); + TU_LOG1_INT(SystemCoreClock); } void board_led_write (bool state) diff --git a/hw/bsp/tm4c123/family.mk b/hw/bsp/tm4c123/family.mk index 9665a2d7d..751076196 100644 --- a/hw/bsp/tm4c123/family.mk +++ b/hw/bsp/tm4c123/family.mk @@ -28,6 +28,7 @@ INC += \ SRC_C += \ src/portable/mentor/musb/dcd_musb.c \ + src/portable/mentor/musb/hcd_musb.c \ $(MCU_DIR)/Source/system_TM4C123.c \ $(MCU_DIR)/Source/GCC/tm4c123_startup.c diff --git a/hw/mcu/broadcom b/hw/mcu/broadcom index 5bff1d5e0..083700860 160000 --- a/hw/mcu/broadcom +++ b/hw/mcu/broadcom @@ -1 +1 @@ -Subproject commit 5bff1d5e02c37c38ee1e5cf3f7fe82fdc7e1517e +Subproject commit 08370086080759ed54ac1136d62d2ad24c6fa267 diff --git a/src/class/usbtmc/usbtmc_device.c b/src/class/usbtmc/usbtmc_device.c index 4bd1edf12..26be987cf 100644 --- a/src/class/usbtmc/usbtmc_device.c +++ b/src/class/usbtmc/usbtmc_device.c @@ -235,17 +235,19 @@ void usbtmcd_init_cb(void) usbtmc_state.capabilities = tud_usbtmc_get_capabilities_cb(); #ifndef NDEBUG # if CFG_TUD_USBTMC_ENABLE_488 - if(usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) - TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); - // Per USB488 spec: table 8 - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); - TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); + if (usbtmc_state.capabilities->bmIntfcCapabilities488.supportsTrigger) { + TU_ASSERT(&tud_usbtmc_msg_trigger_cb != NULL,); + } + // Per USB488 spec: table 8 + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.listenOnly,); + TU_ASSERT(!usbtmc_state.capabilities->bmIntfcCapabilities.talkOnly,); # endif - if(usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) - TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + if (usbtmc_state.capabilities->bmIntfcCapabilities.supportsIndicatorPulse) { + TU_ASSERT(&tud_usbtmc_indicator_pulse_cb != NULL,); + } #endif - usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); + usbtmcLock = osal_mutex_create(&usbtmcLockBuffer); } uint16_t usbtmcd_open_cb(uint8_t rhport, tusb_desc_interface_t const * itf_desc, uint16_t max_len) diff --git a/src/common/tusb_verify.h b/src/common/tusb_verify.h index 56ba8bcd1..8fef11dc7 100644 --- a/src/common/tusb_verify.h +++ b/src/common/tusb_verify.h @@ -37,31 +37,31 @@ * manipulation that you are told to stay away. * * This contains macros for both VERIFY and ASSERT: - * + * * VERIFY: Used when there is an error condition which is not the * fault of the MCU. For example, bounds checking on data * sent to the micro over USB should use this function. * Another example is checking for buffer overflows, where * returning from the active function causes a NAK. - * + * * ASSERT: Used for error conditions that are caused by MCU firmware * bugs. This is used to discover bugs in the code more * quickly. One example would be adding assertions in library * function calls to confirm a function's (untainted) * parameters are valid. - * + * * The difference in behavior is that ASSERT triggers a breakpoint while * verify does not. * * #define TU_VERIFY(cond) if(cond) return false; * #define TU_VERIFY(cond,ret) if(cond) return ret; - * + * * #define TU_VERIFY_HDLR(cond,handler) if(cond) {handler; return false;} * #define TU_VERIFY_HDLR(cond,ret,handler) if(cond) {handler; return ret;} * * #define TU_ASSERT(cond) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return false;} * #define TU_ASSERT(cond,ret) if(cond) {_MESS_FAILED(); TU_BREAKPOINT(), return ret;} - * + * *------------------------------------------------------------------*/ #ifdef __cplusplus @@ -81,8 +81,8 @@ #define _MESS_FAILED() do {} while (0) #endif -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7, M33 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) #define TU_BREAKPOINT() do \ { \ volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ diff --git a/src/device/dcd_attr.h b/src/device/dcd_attr.h index 3c5dadaf4..feba82ea9 100644 --- a/src/device/dcd_attr.h +++ b/src/device/dcd_attr.h @@ -190,7 +190,7 @@ #define DCD_ATTR_ENDPOINT_MAX 4 //------------- Broadcom -------------// -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define DCD_ATTR_ENDPOINT_MAX 8 //------------- Broadcom -------------// diff --git a/src/portable/mentor/musb/dcd_musb.c b/src/portable/mentor/musb/dcd_musb.c index 4b4c2f9b2..f6e05e134 100644 --- a/src/portable/mentor/musb/dcd_musb.c +++ b/src/portable/mentor/musb/dcd_musb.c @@ -26,7 +26,8 @@ #include "tusb_option.h" -#if TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) +#if TUSB_OPT_DEVICE_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) /* GCC warns that an address may be unaligned, even though @@ -250,12 +251,12 @@ static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) len -= 4; } if (len >= 2) { - *(uint32_t *)addr = reg->u16; + *(uint16_t *)addr = reg->u16; addr += 2; len -= 2; } if (len) { - *(uint32_t *)addr = reg->u8; + *(uint8_t *)addr = reg->u8; } } diff --git a/src/portable/mentor/musb/hcd_musb.c b/src/portable/mentor/musb/hcd_musb.c new file mode 100644 index 000000000..acccb7674 --- /dev/null +++ b/src/portable/mentor/musb/hcd_musb.c @@ -0,0 +1,876 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021 Koji KITAYAMA + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#include "tusb_option.h" + +#if TUSB_OPT_HOST_ENABLED && \ + TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) + +#if __GNUC__ > 8 && defined(__ARM_FEATURE_UNALIGNED) +/* GCC warns that an address may be unaligned, even though + * the target CPU has the capability for unaligned memory access. */ +_Pragma("GCC diagnostic ignored \"-Waddress-of-packed-member\""); +#endif + +#include "host/hcd.h" + +#if TU_CHECK_MCU(OPT_MCU_MSP432E4) + #include "musb_msp432e.h" + +#elif TU_CHECK_MCU(OPT_MCU_TM4C123, OPT_MCU_TM4C129) + #include "musb_tm4c.h" + + // HACK generalize later + #include "musb_type.h" + #define FIFO0_WORD FIFO0 + +#else + #error "Unsupported MCUs" +#endif + +#ifndef HCD_ATTR_ENDPOINT_MAX +# define HCD_ATTR_ENDPOINT_MAX 8 +#endif + +/*------------------------------------------------------------------ + * MACRO TYPEDEF CONSTANT ENUM DECLARATION + *------------------------------------------------------------------*/ +#define REQUEST_TYPE_INVALID (0xFFu) + +typedef struct { + uint_fast16_t beg; /* offset of including first element */ + uint_fast16_t end; /* offset of excluding the last element */ +} free_block_t; + +typedef struct TU_ATTR_PACKED { + uint8_t TXFUNCADDR; + uint8_t RESERVED0; + uint8_t TXHUBADDR; + uint8_t TXHUBPORT; + uint8_t RXFUNCADDR; + uint8_t RESERVED1; + uint8_t RXHUBADDR; + uint8_t RXHUBPORT; +} hw_addr_t; + +typedef struct TU_ATTR_PACKED { + uint16_t TXMAXP; + uint8_t TXCSRL; + uint8_t TXCSRH; + uint16_t RXMAXP; + uint8_t RXCSRL; + uint8_t RXCSRH; + uint16_t RXCOUNT; + uint8_t TXTYPE; + uint8_t TXINTERVAL; + uint8_t RXTYPE; + uint8_t RXINTERVAL; + uint16_t RESERVED; +} hw_endpoint_t; + +typedef union { + uint8_t u8; + uint16_t u16; + uint32_t u32; +} hw_fifo_t; + +typedef struct TU_ATTR_PACKED +{ + void *buf; /* the start address of a transfer data buffer */ + uint16_t length; /* the number of bytes in the buffer */ + uint16_t remaining; /* the number of bytes remaining in the buffer */ +} pipe_state_t; + +typedef struct TU_ATTR_PACKED +{ + uint8_t dev; + uint8_t ep; +} pipe_addr_t; + +typedef struct +{ + bool need_reset; /* The device has not been reset after connection. */ + uint8_t bmRequestType; + uint8_t ctl_mps[7]; /* EP0 max packet size for each device */ + pipe_state_t pipe0; + pipe_state_t pipe[7][2]; /* pipe[pipe number - 1][direction 0:RX 1:TX] */ + pipe_addr_t addr[7][2]; /* addr[pipe number - 1][direction 0:RX 1:TX] */ +} hcd_data_t; + +/*------------------------------------------------------------------ + * INTERNAL OBJECT & FUNCTION DECLARATION + *------------------------------------------------------------------*/ +static hcd_data_t _hcd; + +static inline free_block_t *find_containing_block(free_block_t *beg, free_block_t *end, uint_fast16_t addr) +{ + free_block_t *cur = beg; + for (; cur < end && ((addr < cur->beg) || (cur->end <= addr)); ++cur) ; + return cur; +} + +static inline int update_free_block_list(free_block_t *blks, unsigned num, uint_fast16_t addr, uint_fast16_t size) +{ + free_block_t *p = find_containing_block(blks, blks + num, addr); + TU_ASSERT(p != blks + num, -2); + if (p->beg == addr) { + /* Shrink block */ + p->beg = addr + size; + if (p->beg != p->end) return 0; + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } else { + /* Split into 2 blocks */ + free_block_t tmp = { + .beg = addr + size, + .end = p->end + }; + p->end = addr; + if (p->beg == p->end) { + if (tmp.beg != tmp.end) { + *p = tmp; + return 0; + } + /* remove block */ + free_block_t *end = blks + num; + while (p + 1 < end) { + *p = *(p + 1); + ++p; + } + return -1; + } + if (tmp.beg == tmp.end) return 0; + blks[num] = tmp; + return 1; + } +} + +static inline unsigned free_block_size(free_block_t const *blk) +{ + return blk->end - blk->beg; +} + +static unsigned find_free_memory(uint_fast16_t size_in_log2_minus3) +{ + free_block_t free_blocks[2 * (HCD_ATTR_ENDPOINT_MAX - 1)]; + unsigned num_blocks = 1; + + /* Initialize free memory block list */ + free_blocks[0].beg = 64 / 8; + free_blocks[0].end = (4 << 10) / 8; /* 4KiB / 8 bytes */ + for (int i = 1; i < HCD_ATTR_ENDPOINT_MAX; ++i) { + uint_fast16_t addr; + int num; + USB0->EPIDX = i; + addr = USB0->TXFIFOADD; + if (addr) { + unsigned sz = USB0->TXFIFOSZ; + unsigned sft = (sz & USB_TXFIFOSZ_SIZE_M) + ((sz & USB_TXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + addr = USB0->RXFIFOADD; + if (addr) { + unsigned sz = USB0->RXFIFOSZ; + unsigned sft = (sz & USB_RXFIFOSZ_SIZE_M) + ((sz & USB_RXFIFOSZ_DPB) ? 1: 0); + num = update_free_block_list(free_blocks, num_blocks, addr, 1 << sft); + TU_ASSERT(-2 < num, 0); + num_blocks += num; + } + } + + /* Find the best fit memory block */ + uint_fast16_t size_in_8byte_unit = 1 << size_in_log2_minus3; + free_block_t const *min = NULL; + uint_fast16_t min_sz = 0xFFFFu; + free_block_t const *end = &free_blocks[num_blocks]; + for (free_block_t const *cur = &free_blocks[0]; cur < end; ++cur) { + uint_fast16_t sz = free_block_size(cur); + if (sz < size_in_8byte_unit) continue; + if (size_in_8byte_unit == sz) return cur->beg; + if (sz < min_sz) min = cur; + } + TU_ASSERT(min, 0); + return min->beg; +} + +static inline volatile hw_endpoint_t* edpt_regs(unsigned epnum_minus1) +{ + volatile hw_endpoint_t *regs = (volatile hw_endpoint_t*)((uintptr_t)&USB0->TXMAXP1); + return regs + epnum_minus1; +} + +static unsigned find_pipe(uint_fast8_t dev_addr, uint_fast8_t ep_addr) +{ + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_addr_t const *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if ((dev_addr == p->dev) && (ep_addr == p->ep)) + return i + 1; + } + return 0; +} + +static void pipe_write_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + reg->u32 = *(uint32_t const *)addr; + addr += 4; + len -= 4; + } + if (len >= 2) { + reg->u16 = *(uint16_t const *)addr; + addr += 2; + len -= 2; + } + if (len) { + reg->u8 = *(uint8_t const *)addr; + } +} + +static void pipe_read_packet(void *buf, volatile void *fifo, unsigned len) +{ + volatile hw_fifo_t *reg = (volatile hw_fifo_t*)fifo; + uintptr_t addr = (uintptr_t)buf; + while (len >= 4) { + *(uint32_t *)addr = reg->u32; + addr += 4; + len -= 4; + } + if (len >= 2) { + *(uint16_t *)addr = reg->u16; + addr += 2; + len -= 2; + } + if (len) { + *(uint8_t *)addr = reg->u8; + } +} + +static bool edpt0_xfer_out(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + USB0->CSRL0 = USB_CSRL0_TXRDY; + return false; +} + +static bool edpt0_xfer_in(void) +{ + pipe_state_t *pipe = &_hcd.pipe0; + unsigned const rem = pipe->remaining; + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const mps = _hcd.ctl_mps[dev_addr]; + unsigned const vld = USB0->COUNT0; + unsigned const len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return true; + } + USB0->CSRL0 = USB_CSRL0_REQPKT; + return false; +} + +static bool edpt0_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + + unsigned const req = _hcd.bmRequestType; + TU_ASSERT(req != REQUEST_TYPE_INVALID); + TU_ASSERT(dev_addr < sizeof(_hcd.ctl_mps)); + + USB0->TXFUNCADDR0 = dev_addr; + const unsigned dir_in = tu_edpt_dir(ep_addr); + if (tu_edpt_dir(req) == dir_in) { /* DATA stage */ + TU_ASSERT(buffer); + _hcd.pipe0.buf = buffer; + _hcd.pipe0.length = buflen; + _hcd.pipe0.remaining = buflen; + if (dir_in) + USB0->CSRL0 = USB_CSRL0_REQPKT; + else + edpt0_xfer_out(); + } else { /* STATUS stage */ + _hcd.pipe0.buf = NULL; + _hcd.pipe0.length = 0; + _hcd.pipe0.remaining = 0; + USB0->CSRL0 = USB_CSRL0_STATUS | (dir_in ? USB_CSRL0_REQPKT: USB_CSRL0_TXRDY); + } + return true; +} + +static bool pipe_xfer_out(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + unsigned const rem = pipe->remaining; + if (!rem) { + pipe->buf = NULL; + return true; + } + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const mps = regs->TXMAXP; + unsigned const len = TU_MIN(rem, mps); + void *buf = pipe->buf; + if (len) { + pipe_write_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = (uint8_t*)buf + len; + } + pipe->remaining = rem - len; + regs->TXCSRL = USB_TXCSRL1_TXRDY; + return false; +} + +static bool pipe_xfer_in(uint_fast8_t pipenum) +{ + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + + TU_ASSERT(regs->RXCSRL & USB_RXCSRL1_RXRDY); + + const unsigned mps = regs->RXMAXP; + const unsigned rem = pipe->remaining; + const unsigned vld = regs->RXCOUNT; + const unsigned len = TU_MIN(TU_MIN(rem, mps), vld); + void *buf = pipe->buf; + if (len) { + pipe_read_packet(buf, &USB0->FIFO0_WORD + pipenum, len); + pipe->buf = buf + len; + pipe->remaining = rem - len; + } + if ((len < mps) || (rem == len)) { + pipe->buf = NULL; + return NULL != buf; + } + regs->RXCSRL = USB_RXCSRL1_REQPKT; + return false; +} + +static bool edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = buffer; + pipe->length = buflen; + pipe->remaining = buflen; + if (dir_tx) { + pipe_xfer_out(pipenum); + } else { + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + regs->RXCSRL = USB_RXCSRL1_REQPKT; + } + return true; +} + +static void process_ep0(uint8_t rhport) +{ + (void)rhport; + + uint_fast8_t csrl = USB0->CSRL0; + // TU_LOG1(" EP0 CSRL = %x\n", csrl); + + unsigned const dev_addr = USB0->TXFUNCADDR0; + unsigned const req = _hcd.bmRequestType; + if (csrl & (USB_CSRL0_ERROR | USB_CSRL0_NAKTO | USB_CSRL0_STALLED)) { + /* No response / NAK timed out / Stall received */ + if (csrl & (USB_CSRL0_RXRDY | USB_CSRL0_TXRDY)) + USB0->CSRH0 = USB_CSRH0_FLUSH; + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + uint8_t result = (csrl & USB_CSRL0_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + if (REQUEST_TYPE_INVALID == req) { /* SETUP */ + uint8_t const ep_addr = tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else if (csrl & USB_CSRL0_STATUS) { /* STATUS */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } else { /* DATA */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_IN): tu_edpt_addr(0, TUSB_DIR_OUT); + hcd_event_xfer_complete(dev_addr, ep_addr, + _hcd.pipe0.length - _hcd.pipe0.remaining, + result, true); + } + return; + } + if (csrl & USB_CSRL0_STATUS) { + /* STATUS IN */ + TU_ASSERT(USB_CSRL0_RXRDY == (csrl & USB_CSRL0_RXRDY),); + TU_ASSERT(0 == USB0->COUNT0,); + USB0->CSRH0 = USB_CSRH0_FLUSH; + USB0->CSRL0 = 0; + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + 0, XFER_RESULT_SUCCESS, true); + return; + } + if (csrl & USB_CSRL0_RXRDY) { + /* DATA IN */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + TU_ASSERT(_hcd.pipe0.buf,); + if (edpt0_xfer_in()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_IN), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } + return; + } + + /* When CSRL0 is zero, it means that completion of sending a any length packet. */ + if (!_hcd.pipe0.buf) { + /* STATUS OUT */ + TU_ASSERT(REQUEST_TYPE_INVALID != req,); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + /* EP address is the reverse direction of DATA stage */ + uint8_t const ep_addr = tu_edpt_dir(req) ? + tu_edpt_addr(0, TUSB_DIR_OUT): tu_edpt_addr(0, TUSB_DIR_IN); + hcd_event_xfer_complete(dev_addr, ep_addr, 0, XFER_RESULT_SUCCESS, true); + return; + } + if (REQUEST_TYPE_INVALID == req) { + /* SETUP */ + _hcd.bmRequestType = *(uint8_t*)_hcd.pipe0.buf; + _hcd.pipe0.buf = NULL; + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + 8, XFER_RESULT_SUCCESS, true); + return; + } + + /* DATA OUT */ + if (edpt0_xfer_out()) { + hcd_event_xfer_complete(dev_addr, tu_edpt_addr(0, TUSB_DIR_OUT), + _hcd.pipe0.length - _hcd.pipe0.remaining, + XFER_RESULT_SUCCESS, true); + } +} + +static void process_pipe_tx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->TXCSRL; + // TU_LOG1(" TXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) { + if (csrl & USB_TXCSRL1_TXRDY) + regs->TXCSRL = (csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR)) | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = csrl & ~(USB_TXCSRL1_STALLED | USB_TXCSRL1_ERROR); + completed = true; + result = (csrl & USB_TXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_out(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][1]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][1]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +static void process_pipe_rx(uint8_t rhport, uint_fast8_t pipenum) +{ + (void)rhport; + bool completed; + uint8_t result; + + volatile hw_endpoint_t *regs = edpt_regs(pipenum - 1); + unsigned const csrl = regs->RXCSRL; + // TU_LOG1(" RXCSRL%d = %x\n", pipenum, csrl); + if (csrl & (USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) { + if (csrl & USB_RXCSRL1_RXRDY) + regs->RXCSRL = (csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR)) | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = csrl & ~(USB_RXCSRL1_STALLED | USB_RXCSRL1_ERROR); + completed = true; + result = (csrl & USB_RXCSRL1_STALLED) ? XFER_RESULT_STALLED: XFER_RESULT_FAILED; + } else { + completed = pipe_xfer_in(pipenum); + result = XFER_RESULT_SUCCESS; + } + if (completed) { + pipe_addr_t *addr = &_hcd.addr[pipenum - 1][0]; + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][0]; + hcd_event_xfer_complete(addr->dev, addr->ep, + pipe->length - pipe->remaining, + result, true); + } +} + +/*------------------------------------------------------------------ + * Host API + *------------------------------------------------------------------*/ + +bool hcd_init(uint8_t rhport) +{ + (void)rhport; + + NVIC_ClearPendingIRQ(USB0_IRQn); + _hcd.bmRequestType = REQUEST_TYPE_INVALID; + USB0->DEVCTL |= USB_DEVCTL_SESSION; + USB0->IE = USB_IE_DISCON | USB_IE_CONN | USB_IE_BABBLE | USB_IE_RESUME; + return true; +} + +void hcd_int_enable(uint8_t rhport) +{ + (void)rhport; + NVIC_EnableIRQ(USB0_IRQn); +} + +void hcd_int_disable(uint8_t rhport) +{ + (void)rhport; + NVIC_DisableIRQ(USB0_IRQn); +} + +uint32_t hcd_frame_number(uint8_t rhport) +{ + (void)rhport; + /* The device must be reset at least once after connection + * in order to start the frame counter. */ + if (_hcd.need_reset) hcd_port_reset(rhport); + return USB0->FRAME; +} + +//--------------------------------------------------------------------+ +// Port API +//--------------------------------------------------------------------+ + +bool hcd_port_connect_status(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (!(devctl & USB_DEVCTL_HOST)) return false; + if (devctl & (USB_DEVCTL_LSDEV | USB_DEVCTL_FSDEV)) return true; + return false; +} + +void hcd_port_reset(uint8_t rhport) +{ + (void)rhport; + USB0->POWER |= USB_POWER_HSENAB | USB_POWER_RESET; + unsigned cnt = SystemCoreClock / 1000 * 20; + while (cnt--) __NOP(); + USB0->POWER &= ~USB_POWER_RESET; + _hcd.need_reset = false; +} + +tusb_speed_t hcd_port_speed_get(uint8_t rhport) +{ + (void)rhport; + unsigned devctl = USB0->DEVCTL; + if (devctl & USB_DEVCTL_LSDEV) return TUSB_SPEED_LOW; + if (!(devctl & USB_DEVCTL_FSDEV)) return TUSB_SPEED_INVALID; + if (USB0->POWER & USB_POWER_HSMODE) return TUSB_SPEED_HIGH; + return TUSB_SPEED_FULL; +} + +void hcd_device_close(uint8_t rhport, uint8_t dev_addr) +{ + (void)rhport; + if (sizeof(_hcd.ctl_mps) <= dev_addr) return; + + unsigned const ie = NVIC_GetEnableIRQ(USB0_IRQn); + NVIC_DisableIRQ(USB0_IRQn); + _hcd.ctl_mps[dev_addr] = 0; + if (!dev_addr) return; + + pipe_addr_t *p = &_hcd.addr[0][0]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i) { + for (unsigned j = 0; j < 2; ++j, ++p) { + if (dev_addr != p->dev) continue; + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + i + 1; + hw_endpoint_t volatile *regs = edpt_regs(i); + USB0->EPIDX = i + 1; + if (j) { + USB0->TXIE &= ~TU_BIT(i + 1); + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + regs->TXMAXP = 0; + regs->TXTYPE = 0; + regs->TXINTERVAL = 0; + fadr->TXFUNCADDR = 0; + fadr->TXHUBADDR = 0; + fadr->TXHUBPORT = 0; + USB0->TXFIFOADD = 0; + USB0->TXFIFOSZ = 0; + } else { + USB0->RXIE &= ~TU_BIT(i + 1); + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + regs->RXMAXP = 0; + regs->RXTYPE = 0; + regs->RXINTERVAL = 0; + fadr->RXFUNCADDR = 0; + fadr->RXHUBADDR = 0; + fadr->RXHUBPORT = 0; + USB0->RXFIFOADD = 0; + USB0->RXFIFOSZ = 0; + } + p->dev = 0; + p->ep = 0; + pipe_state_t *pipe = &_hcd.pipe[i][j]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + } + } + if (ie) NVIC_EnableIRQ(USB0_IRQn); +} + +//--------------------------------------------------------------------+ +// Endpoints API +//--------------------------------------------------------------------+ + +bool hcd_setup_send(uint8_t rhport, uint8_t dev_addr, uint8_t const setup_packet[8]) +{ + (void)rhport; + pipe_write_packet((void*)(uintptr_t)setup_packet, &USB0->FIFO0_WORD, 8); + _hcd.pipe0.buf = (void*)(uintptr_t)setup_packet; + _hcd.pipe0.length = 8; + _hcd.pipe0.remaining = 0; + + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { + default: return false; + case TUSB_SPEED_LOW: USB0->TYPE0 = USB_TYPE0_SPEED_LOW; break; + case TUSB_SPEED_FULL: USB0->TYPE0 = USB_TYPE0_SPEED_FULL; break; + case TUSB_SPEED_HIGH: USB0->TYPE0 = USB_TYPE0_SPEED_HIGH; break; + } + USB0->TXHUBADDR0 = devtree.hub_addr; + USB0->TXHUBPORT0 = devtree.hub_port; + USB0->TXFUNCADDR0 = dev_addr; + USB0->CSRL0 = USB_CSRL0_TXRDY | USB_CSRL0_SETUP; + return true; +} + +bool hcd_edpt_open(uint8_t rhport, uint8_t dev_addr, tusb_desc_endpoint_t const * ep_desc) +{ + (void)rhport; + if (sizeof(_hcd.ctl_mps) <= dev_addr) return false; + unsigned const ep_addr = ep_desc->bEndpointAddress; + unsigned const epn = tu_edpt_number(ep_addr); + if (0 == epn) { + _hcd.ctl_mps[dev_addr] = ep_desc->wMaxPacketSize; + return true; + } + + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + /* Find a free pipe */ + unsigned pipenum = 0; + pipe_addr_t *p = &_hcd.addr[0][dir_tx]; + for (unsigned i = 0; i < sizeof(_hcd.addr)/sizeof(_hcd.addr[0]); ++i, p += 2) { + if (0 == p->ep) { + p->dev = dev_addr; + p->ep = ep_addr; + pipenum = i + 1; + break; + } + } + if (!pipenum) return false; + + unsigned const xfer = ep_desc->bmAttributes.xfer; + unsigned const mps = tu_edpt_packet_size(ep_desc); + + pipe_state_t *pipe = &_hcd.pipe[pipenum - 1][dir_tx]; + pipe->buf = NULL; + pipe->length = 0; + pipe->remaining = 0; + + uint8_t pipe_type = 0; + hcd_devtree_info_t devtree; + hcd_devtree_get_info(dev_addr, &devtree); + switch (devtree.speed) { + default: return false; + case TUSB_SPEED_LOW: pipe_type |= USB_TXTYPE1_SPEED_LOW; break; + case TUSB_SPEED_FULL: pipe_type |= USB_TXTYPE1_SPEED_FULL; break; + case TUSB_SPEED_HIGH: pipe_type |= USB_TXTYPE1_SPEED_HIGH; break; + } + switch (xfer) { + default: return false; + case TUSB_XFER_BULK: pipe_type |= USB_TXTYPE1_PROTO_BULK; break; + case TUSB_XFER_INTERRUPT: pipe_type |= USB_TXTYPE1_PROTO_INT; break; + case TUSB_XFER_ISOCHRONOUS: pipe_type |= USB_TXTYPE1_PROTO_ISOC; break; + } + + hw_addr_t volatile *fadr = (hw_addr_t volatile*)&USB0->TXFUNCADDR0 + pipenum; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + if (dir_tx) { + fadr->TXFUNCADDR = dev_addr; + fadr->TXHUBADDR = devtree.hub_addr; + fadr->TXHUBPORT = devtree.hub_port; + regs->TXMAXP = mps; + regs->TXTYPE = pipe_type | epn; + regs->TXINTERVAL = ep_desc->bInterval; + if (regs->TXCSRL & USB_TXCSRL1_TXRDY) + regs->TXCSRL = USB_TXCSRL1_CLRDT | USB_TXCSRL1_FLUSH; + else + regs->TXCSRL = USB_TXCSRL1_CLRDT; + USB0->TXIE |= TU_BIT(pipenum); + } else { + fadr->RXFUNCADDR = dev_addr; + fadr->RXHUBADDR = devtree.hub_addr; + fadr->RXHUBPORT = devtree.hub_port; + regs->RXMAXP = mps; + regs->RXTYPE = pipe_type | epn; + regs->RXINTERVAL = ep_desc->bInterval; + if (regs->RXCSRL & USB_RXCSRL1_RXRDY) + regs->RXCSRL = USB_RXCSRL1_CLRDT | USB_RXCSRL1_FLUSH; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + USB0->RXIE |= TU_BIT(pipenum); + } + + /* Setup FIFO */ + int size_in_log2_minus3 = 28 - TU_MIN(28, __CLZ((uint32_t)mps)); + if ((8u << size_in_log2_minus3) < mps) ++size_in_log2_minus3; + unsigned addr = find_free_memory(size_in_log2_minus3); + TU_ASSERT(addr); + + USB0->EPIDX = pipenum; + if (dir_tx) { + USB0->TXFIFOADD = addr; + USB0->TXFIFOSZ = size_in_log2_minus3; + } else { + USB0->RXFIFOADD = addr; + USB0->RXFIFOSZ = size_in_log2_minus3; + } + return true; +} + +bool hcd_edpt_xfer(uint8_t rhport, uint8_t dev_addr, uint8_t ep_addr, uint8_t *buffer, uint16_t buflen) +{ + (void)rhport; + bool ret = false; + if (0 == tu_edpt_number(ep_addr)) { + ret = edpt0_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } else { + ret = edpt_xfer(rhport, dev_addr, ep_addr, buffer, buflen); + } + return ret; +} + +// clear stall, data toggle is also reset to DATA0 +bool hcd_edpt_clear_stall(uint8_t dev_addr, uint8_t ep_addr) +{ + unsigned const pipenum = find_pipe(dev_addr, ep_addr); + if (!pipenum) return false; + hw_endpoint_t volatile *regs = edpt_regs(pipenum - 1); + unsigned const dir_tx = tu_edpt_dir(ep_addr) ? 0: 1; + if (dir_tx) + regs->TXCSRL = USB_TXCSRL1_CLRDT; + else + regs->RXCSRL = USB_RXCSRL1_CLRDT; + return true; +} + +/*------------------------------------------------------------------- + * ISR + *-------------------------------------------------------------------*/ +void hcd_int_handler(uint8_t rhport) +{ + uint_fast8_t is, txis, rxis; + + is = USB0->IS; /* read and clear interrupt status */ + txis = USB0->TXIS; /* read and clear interrupt status */ + rxis = USB0->RXIS; /* read and clear interrupt status */ + // TU_LOG1("D%2x T%2x R%2x\n", is, txis, rxis); + + is &= USB0->IE; /* Clear disabled interrupts */ + if (is & USB_IS_RESUME) { + } + if (is & USB_IS_CONN) { + _hcd.need_reset = true; + hcd_event_device_attach(rhport, true); + } + if (is & USB_IS_DISCON) { + hcd_event_device_remove(rhport, true); + } + if (is & USB_IS_BABBLE) { + } + txis &= USB0->TXIE; /* Clear disabled interrupts */ + if (txis & USB_TXIE_EP0) { + process_ep0(rhport); + txis &= ~TU_BIT(0); + } + while (txis) { + unsigned const num = __builtin_ctz(txis); + process_pipe_tx(rhport, num); + txis &= ~TU_BIT(num); + } + rxis &= USB0->RXIE; /* Clear disabled interrupts */ + while (rxis) { + unsigned const num = __builtin_ctz(rxis); + process_pipe_rx(rhport, num); + rxis &= ~TU_BIT(num); + } +} + +#endif diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 2bcd56b8a..ed597a34f 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -1059,7 +1059,13 @@ void tusb_hal_nrf_power_event (uint32_t event) // Enable interrupt, priorities should be set by application NVIC_ClearPendingIRQ(USBD_IRQn); - NVIC_EnableIRQ(USBD_IRQn); + // Don't enable USBD interrupt yet, if dcd_init() did not finish yet + // Interrupt will be enabled by tud_init(), when USB stack is ready + // to handle interrupts. + if (tud_inited()) + { + NVIC_EnableIRQ(USBD_IRQn); + } // Wait for HFCLK while ( !hfclk_running() ) { } diff --git a/src/portable/raspberrypi/rp2040/dcd_rp2040.c b/src/portable/raspberrypi/rp2040/dcd_rp2040.c index e084478e0..42add3167 100644 --- a/src/portable/raspberrypi/rp2040/dcd_rp2040.c +++ b/src/portable/raspberrypi/rp2040/dcd_rp2040.c @@ -83,7 +83,7 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) assert(((uintptr_t )next_buffer_ptr & 0b111111u) == 0); uint dpram_offset = hw_data_offset(ep->hw_data_buf); - assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); + hard_assert(hw_data_offset(next_buffer_ptr) <= USB_DPRAM_MAX); pico_info(" Alloced %d bytes at offset 0x%x (0x%p)\r\n", size, dpram_offset, ep->hw_data_buf); @@ -93,7 +93,6 @@ static void _hw_endpoint_alloc(struct hw_endpoint *ep, uint8_t transfer_type) *ep->endpoint_control = reg; } -#if 0 // todo unused static void _hw_endpoint_close(struct hw_endpoint *ep) { // Clear hardware registers and then zero the struct @@ -103,6 +102,21 @@ static void _hw_endpoint_close(struct hw_endpoint *ep) *ep->buffer_control = 0; // Clear any endpoint state memset(ep, 0, sizeof(struct hw_endpoint)); + + // Reclaim buffer space if all endpoints are closed + bool reclaim_buffers = true; + for ( uint8_t i = 1; i < USB_MAX_ENDPOINTS; i++ ) + { + if (hw_endpoint_get_by_num(i, TUSB_DIR_OUT)->hw_data_buf != NULL || hw_endpoint_get_by_num(i, TUSB_DIR_IN)->hw_data_buf != NULL) + { + reclaim_buffers = false; + break; + } + } + if (reclaim_buffers) + { + next_buffer_ptr = &usb_dpram->epx_data[0]; + } } static void hw_endpoint_close(uint8_t ep_addr) @@ -110,7 +124,6 @@ static void hw_endpoint_close(uint8_t ep_addr) struct hw_endpoint *ep = hw_endpoint_get_by_addr(ep_addr); _hw_endpoint_close(ep); } -#endif static void hw_endpoint_init(uint8_t ep_addr, uint16_t wMaxPacketSize, uint8_t transfer_type) { @@ -224,6 +237,8 @@ static void reset_non_control_endpoints(void) // clear non-control hw endpoints tu_memclr(hw_endpoints[1], sizeof(hw_endpoints) - 2*sizeof(hw_endpoint_t)); + + // reclaim buffer space next_buffer_ptr = &usb_dpram->epx_data[0]; } @@ -232,6 +247,14 @@ static void dcd_rp2040_irq(void) uint32_t const status = usb_hw->ints; uint32_t handled = 0; + // xfer events are handled before setup req. So if a transfer completes immediately + // before closing the EP, the events will be delivered in same order. + if (status & USB_INTS_BUFF_STATUS_BITS) + { + handled |= USB_INTS_BUFF_STATUS_BITS; + hw_handle_buff_status(); + } + if (status & USB_INTS_SETUP_REQ_BITS) { handled |= USB_INTS_SETUP_REQ_BITS; @@ -245,12 +268,6 @@ static void dcd_rp2040_irq(void) usb_hw_clear->sie_status = USB_SIE_STATUS_SETUP_REC_BITS; } - if (status & USB_INTS_BUFF_STATUS_BITS) - { - handled |= USB_INTS_BUFF_STATUS_BITS; - hw_handle_buff_status(); - } - #if FORCE_VBUS_DETECT == 0 // Since we force VBUS detect On, device will always think it is connected and // couldn't distinguish between disconnect and suspend @@ -479,10 +496,9 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { (void) rhport; - (void) ep_addr; - // usbd.c says: In progress transfers on this EP may be delivered after this call pico_trace("dcd_edpt_close %02x\n", ep_addr); + hw_endpoint_close(ep_addr); } void dcd_int_handler(uint8_t rhport) diff --git a/src/portable/raspberrypi/rp2040/rp2040_usb.c b/src/portable/raspberrypi/rp2040/rp2040_usb.c index c9e2f6b26..9d833e65f 100644 --- a/src/portable/raspberrypi/rp2040/rp2040_usb.c +++ b/src/portable/raspberrypi/rp2040/rp2040_usb.c @@ -294,7 +294,7 @@ bool hw_endpoint_xfer_continue(struct hw_endpoint *ep) // Part way through a transfer if (!ep->active) { - panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string); + panic("Can't continue xfer on inactive ep %d %s", tu_edpt_number(ep->ep_addr), ep_dir_string[tu_edpt_dir(ep->ep_addr)]); } // Update EP struct from hardware state diff --git a/src/portable/synopsys/dwc2/dcd_dwc2.c b/src/portable/synopsys/dwc2/dcd_dwc2.c index bb21b3dcd..188611743 100644 --- a/src/portable/synopsys/dwc2/dcd_dwc2.c +++ b/src/portable/synopsys/dwc2/dcd_dwc2.c @@ -33,7 +33,8 @@ #if TUSB_OPT_DEVICE_ENABLED && \ ( defined(DCD_ATTR_DWC2_STM32) || \ TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_GD32VF103) || \ - TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_XMC4000) ) + TU_CHECK_MCU(OPT_MCU_EFM32GG, OPT_MCU_BCM2711, OPT_MCU_BCM2835) || \ + TU_CHECK_MCU(OPT_MCU_BCM2837, OPT_MCU_XMC4000) ) #include "device/dcd.h" #include "dwc2_type.h" @@ -44,7 +45,7 @@ #include "dwc2_esp32.h" #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #include "dwc2_gd32.h" -#elif TU_CHECK_MCU(OPT_MCU_BCM2711) +#elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #include "dwc2_bcm.h" #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #include "dwc2_efm32.h" diff --git a/src/portable/synopsys/dwc2/dwc2_bcm.h b/src/portable/synopsys/dwc2/dwc2_bcm.h index 353bc21ee..14194e754 100644 --- a/src/portable/synopsys/dwc2/dwc2_bcm.h +++ b/src/portable/synopsys/dwc2/dwc2_bcm.h @@ -31,6 +31,7 @@ extern "C" { #endif +#include "broadcom/defines.h" #include "broadcom/interrupts.h" #include "broadcom/caches.h" @@ -47,7 +48,6 @@ static inline void dwc2_dcd_int_enable(uint8_t rhport) { (void) rhport; BP_EnableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } TU_ATTR_ALWAYS_INLINE @@ -55,7 +55,6 @@ static inline void dwc2_dcd_int_disable (uint8_t rhport) { (void) rhport; BP_DisableIRQ(USB_IRQn); - __asm__ volatile("isb"); // needed if TIMER1 IRQ is not enabled !? } static inline void dwc2_remote_wakeup_delay(void) diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index 837d0c0ce..51fb8b401 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -24,6 +24,10 @@ * This file is part of the TinyUSB stack. */ +#include "tusb_option.h" + +#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) + #ifndef DEBUG #define DEBUG 0 #endif @@ -32,10 +36,6 @@ #define LOG_USB 0 #endif -#include "tusb_option.h" - -#if TUSB_OPT_DEVICE_ENABLED && (CFG_TUSB_MCU == OPT_MCU_VALENTYUSB_EPTRI) - #include "device/dcd.h" #include "dcd_eptri.h" #include "csr.h" diff --git a/src/tusb_option.h b/src/tusb_option.h index 2edd310fa..c7c7b2454 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -132,6 +132,8 @@ // Broadcom #define OPT_MCU_BCM2711 1700 ///< Broadcom BCM2711 +#define OPT_MCU_BCM2835 1701 ///< Broadcom BCM2835 +#define OPT_MCU_BCM2837 1702 ///< Broadcom BCM2837 // Infineon #define OPT_MCU_XMC4000 1800 ///< Infineon XMC4000 diff --git a/tools/build_board.py b/tools/build_board.py index 9397c754f..b2a80c680 100644 --- a/tools/build_board.py +++ b/tools/build_board.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -50,7 +52,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -82,33 +84,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - ex_dir = 'examples/' + example - board_mk = 'hw/bsp/{}/board.mk'.format(board) - with open(board_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if '-DCFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in board.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = '-DCFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) diff --git a/tools/build_esp32sx.py b/tools/build_esp32sx.py index 91953f080..2947a0a6b 100644 --- a/tools/build_esp32sx.py +++ b/tools/build_esp32sx.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -51,7 +53,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -83,9 +85,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) print(build_separator) diff --git a/tools/build_family.py b/tools/build_family.py index 4195c259b..4094d07db 100644 --- a/tools/build_family.py +++ b/tools/build_family.py @@ -4,6 +4,8 @@ import sys import subprocess import time +import build_utils + SUCCEEDED = "\033[32msucceeded\033[0m" FAILED = "\033[31mfailed\033[0m" SKIPPED = "\033[33mskipped\033[0m" @@ -38,7 +40,7 @@ all_examples.sort() # If family are not specified in arguments, build all all_families = [] for entry in os.scandir("hw/bsp"): - if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name != "esp32s2" and entry.name != "esp32s3": + if entry.is_dir() and os.path.isdir(entry.path + "/boards") and entry.name not in ("esp32s2", "esp32s3"): all_families.append(entry.name) filter_with_input(all_families) @@ -62,7 +64,7 @@ def build_board(example, board): sram_size = "-" # Check if board is skipped - if skip_example(example, board): + if build_utils.skip_example(example, board): success = SKIPPED skip_count += 1 print(build_format.format(example, board, success, '-', flash_size, sram_size)) @@ -95,46 +97,6 @@ def build_size(example, board): sram_size = int(size_list[1]) + int(size_list[2]) return (flash_size, sram_size) -def skip_example(example, board): - ex_dir = 'examples/' + example - - # Check if example is skipped by family or board directory - skip_file = ".skip." + example.replace('/', '.'); - if os.path.isfile("hw/bsp/{}/{}".format(family, skip_file)) or os.path.isfile("hw/bsp/{}/boards/{}/{}".format(family, board, skip_file)): - return 1 - - # Otherwise check if mcu is excluded by example directory - - # family CMake - family_mk = 'hw/bsp/{}/family.cmake'.format(family) - - # family.mk - if not os.path.exists(family_mk): - family_mk = 'hw/bsp/{}/family.mk'.format(family) - - with open(family_mk) as mk: - mk_contents = mk.read() - - # Skip all OPT_MCU_NONE these are WIP port - if 'CFG_TUSB_MCU=OPT_MCU_NONE' in mk_contents: - return 1 - - # Skip if CFG_TUSB_MCU in family.mk to match skip file - for skip_file in glob.iglob(ex_dir + '/.skip.MCU_*'): - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(skip_file).split('.')[2] - if mcu_cflag in mk_contents: - return 1 - - # Build only list, if exists only these MCU are built - only_list = list(glob.iglob(ex_dir + '/.only.MCU_*')) - if len(only_list) > 0: - for only_file in only_list: - mcu_cflag = 'CFG_TUSB_MCU=OPT_' + os.path.basename(only_file).split('.')[2] - if mcu_cflag in mk_contents: - return 0 - return 1 - return 0 - print(build_separator) print(build_format.format('Example', 'Board', '\033[39mResult\033[0m', 'Time', 'Flash', 'SRAM')) diff --git a/tools/build_utils.py b/tools/build_utils.py new file mode 100644 index 000000000..299fffa4d --- /dev/null +++ b/tools/build_utils.py @@ -0,0 +1,61 @@ +import pathlib + +def skip_example(example, board): + ex_dir = pathlib.Path('examples/') / example + bsp = pathlib.Path("hw/bsp") + + board_dir = list(bsp.glob("*/boards/" + board)) + if not board_dir: + # Skip unknown boards + return True + + board_dir = list(board_dir)[0] + + family_dir = board_dir.parent.parent + family = family_dir.name + + # family CMake + family_mk = family_dir / "family.cmake" + + # family.mk + if not family_mk.exists(): + family_mk = family_dir / "family.mk" + + mk_contents = family_mk.read_text() + + # Find the mcu + if "CFG_TUSB_MCU=OPT_MCU_" not in mk_contents: + board_mk = board_dir / "board.cmake" + if not board_mk.exists(): + board_mk = board_dir / "board.mk" + + mk_contents = board_mk.read_text() + + for token in mk_contents.split(): + if "CFG_TUSB_MCU=OPT_MCU_" in token: + # Strip " because cmake files has them. + token = token.strip("\"") + _, opt_mcu = token.split("=") + mcu = opt_mcu[len("OPT_MCU_"):] + + # Skip all OPT_MCU_NONE these are WIP port + if mcu == "NONE": + return True + + skip_file = ex_dir / "skip.txt" + only_file = ex_dir / "only.txt" + + if skip_file.exists() and only_file.exists(): + raise RuntimeError("Only have a skip or only file. Not both.") + elif skip_file.exists(): + skips = skip_file.read_text().split() + return ("mcu:" + mcu in skips or + "board:" + board in skips or + "family:" + family in skips) + elif only_file.exists(): + onlys = only_file.read_text().split() + return not ("mcu:" + mcu in onlys or + "board:" + board in onlys or + "family:" + family in onlys) + + return False