From b18a8fbcd5eacf948b430a996fe54b62da285ccd Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 2 Oct 2025 15:48:36 +0700 Subject: update for release 0.19.0 --- docs/info/changelog.rst | 213 ++++++++++++++++++++++++++++++++++++++++ docs/reference/dependencies.rst | 10 +- 2 files changed, 219 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index 6024bb9e3..16d4dffae 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,219 @@ Changelog ********* +0.19.0 +====== + +General +------- + +- New MCUs and Boards: + + - Add ESP32-H4, ESP32-C5, ESP32-C61 support + - Add STM32U083C-DK, STM32WBA, STM32N6570-DK, STM32N657 Nucleo + - Add AT32F405, AT32F403A, AT32F415, AT32F423 support + - Add CH32V305 support and CH32V20x USB host support + - Add MCXA156 SDK 2.16 support and FRDM-MCXA156 board + - Update all STM32 HAL and CMSIS dependencies to latest versions + +- Build System and CI Improvements + - Improve build system with GCC 14 support + - Add ARM IAR toolchain build support via CircleCI and GitHub Actions + - Add comprehensive CMake build documentation + - Improve hardware-in-the-loop (HIL) testing infrastructure + - Add Claude Code AI assistant workflows and documentation + +- Add ``tusb_deinit()`` function for stack cleanup + +API Changes +----------- + +- Core APIs + - Add weak callbacks with new syntax for better compiler compatibility + - Add ``tusb_deinit()`` to cleanup stack + - Add time functions: ``tusb_time_millis_api()`` and ``tusb_time_delay_ms_api()`` + - Add ``osal_critical`` APIs for critical section handling + - Introduce ``xfer_isr()`` callback for ISO transfer optimization in device classes + +- Device APIs + - CDC: Add ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, + ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` + - MSC: Add ``tud_msc_inquiry2_cb()`` with bufsize parameter, update ``tud_msc_async_io_done()`` + with ``in_isr`` parameter + - Audio: Add ``tud_audio_n_mounted()`` and various FIFO access functions + - MTP: Add ``tud_mtp_mounted()``, ``tud_mtp_data_send()``, ``tud_mtp_data_receive()``, + ``tud_mtp_response_send()``, ``tud_mtp_event_send()`` + +- Host APIs + - Core: Add ``tuh_edpt_close()``, ``tuh_address_set()``, ``tuh_descriptor_get_device_local()``, + ``tuh_descriptor_get_string_langid()``, ``tuh_connected()``, ``tuh_bus_info_get()`` + - Add enumeration callbacks: ``tuh_enum_descriptor_device_cb()``, + ``tuh_enum_descriptor_configuration_cb()`` + - CDC: Add ``tuh_cdc_get_control_line_state_local()``, ``tuh_cdc_get/set_dtr/rts()``, + ``tuh_cdc_connect/disconnect()`` and sync versions of all control APIs + - MIDI: Add ``tuh_midi_itf_get_info()``, ``tuh_midi_packet_read_n()``, + ``tuh_midi_packet_write_n()``, ``tuh_midi_read_available()``, ``tuh_midi_write_flush()``, + ``tuh_midi_descriptor_cb()`` + +Controller Driver (DCD & HCD) +----------------------------- + +- DWC2 + - Support DWC2 v4.30a with improved reset procedure + - Fix core reset: wait for AHB idle before reset + - Add STM32 DWC2 data cache support with proper alignment + - Host improvements: + - Fix disconnect detection and SOF flag handling + - Fix HFIR timing off-by-one error + - Retry IN token immediately for bInterval=1 + - Proper attach debouncing (200ms) + - Fix all retry intervals + - Resume OUT transfer when PING ACKed + - Fix enumeration racing conditions + - Refactor bitfields for better code generation + +- FSDEV (STM32) + - Fix AT32 compile issues after single-buffered endpoint changes + - Add configurable single-buffered isochronous endpoints + - Fix STM32H7 recurrent suspend ISR + - Fix STM32L4 GPIOD clock enable for variants without GPIOD + - Fix STM32 PHYC PLL stability wait + - Improve PMA size handling for STM32U0 + +- EHCI + - Fix removed QHD getting reused + - Fix NXP USBPHY disconnection detection + +- Chipidea/NXP + - Fix race condition with spinlock + - Add async I/O support for MSC + - Improve iMXRT support: fix build, disable BOARD_ConfigMPU, fix attach debouncing on port1 highspeed + - Fix iMXRT1064 and add to HIL test pool + +- MAX3421E + - Use spinlock for thread safety instead of atomic flag + - Implement ``hcd_edpt_close()`` + +- RP2040 + - Fix audio ISO transfer: reset state before notifying stack + - Fix CMake RTOS cache variable + - Abort transfer if active in ``iso_activate()`` + +- SAMD + - Add host controller driver support + +Device Stack +------------ + +- USBD Core + - Introduce ``xfer_isr()`` callback for interrupt-time transfer handling + - Add ``usbd_edpt_xfer_fifo()`` stub + - Revert endpoint busy/claim status if ``xfer_isr()`` defers to ``xfer_cb()`` + +- Audio + - Major simplification of UAC driver and alt settings management + - Move ISO transfers into ``xfer_isr()`` for better performance + - Remove FIFO mutex (single producer/consumer optimization) + - Add implicit feedback support for data IN endpoints + - Fix alignment issues + - Update buffer macros with cache line size alignment + +- CDC + - Add notification support: ``CFG_TUD_CDC_NOTIFY``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` + - Reduce default bInterval from 16ms to 1ms for better responsiveness + - Rename ``tud_cdc_configure_fifo()`` to ``tud_cdc_configure()`` and add ``tx_overwritable_if_not_connected`` option + - Fix web serial robustness with major overhaul and logic cleanup + +- HID + - Add Usage Page and Table for Power Devices (0x84 - 0x85) + - Fix HID descriptor parser variable size and 4-byte item handling + - Add consumer page configurations + +- MIDI + - Fix MIDI interface descriptor handling after audio streaming interface + - Skip RX data with all zeroes + +- MSC + - Add ``tud_msc_inquiry2_cb()`` with bufsize for full inquiry response + - Refactor async I/O: add ``in_isr`` argument to ``tud_msc_async_io_done()`` + +- MTP + - Add new Media Transfer Protocol (MTP) device class driver + - Support MTP operations: GetDeviceInfo, SendObjectInfo, SendObject + - Add MTP event support with ``tud_mtp_event_send()`` + - Implement filesystem example with callbacks + - Add hardware-in-the-loop testing support + +- NCM + - Add USB NCM link state control support + - Fix DHCP offer/ACK destination + +- USBTMC + - Add vendor-specific message support + +- Vendor + - Fix vendor device reset and open issues + - Fix descriptor parsing for ``CFG_TUD_VENDOR > 1`` + - Fix vendor FIFO argument calculation + +Host Stack +---------- + +- USBH Core + - Major enumeration improvements: + - Fix enumeration racing conditions + - Add proper attach debouncing with hub/rootport handling (200ms delay) + - Reduce ``ENUM_DEBOUNCING_DELAY_MS`` to 200ms + - Always get language ID, manufacturer, product, and serial strings during enumeration + - Always get first 2 bytes of string descriptor to determine length (prevents buffer overflow) + - Support devices with multiple configurations + - Add ``tuh_enum_descriptor_device_cb()`` and ``tuh_enum_descriptor_configuration_cb()`` callbacks + - Add ``tuh_descriptor_get_string_langid()`` API + - Hub improvements: + - Check status before getting first device descriptor + - Properly handle port status and change detection + - Queue status endpoint for detach/remove events + - Fix hub status change endpoint handling + - Fix endpoint management: + - ``hcd_edpt_open()`` returns false if endpoint already opened + - Add ``hcd_edpt_close()`` implementation + - Abort pending transfers on close + - Add roothub debouncing flag to ignore attach/remove during debouncing + - Move address setting and bus info management to separate structures + - Force removed devices in same bus info before setting address + +- CDC Serial Host + - Major refactor to generalize CDC serial drivers (FTDI, CP210x, CH34x, PL2303, ACM) + - Add common 2-stage set line coding for drivers without direct support + - Add ``cdch_process_line_state_on_enum()`` for line state configuration during enumeration + - Refactor control transfer handling with ``cdch_internal_control_complete()`` + - Add explicit ``sync()`` API with ``TU_API_SYNC()`` returning ``tusb_xfer_result_t`` + - Rename ``tuh_cdc_get_local_line_coding()`` to ``tuh_cdc_get_line_coding_local()`` + - Add ``tuh_cdc_get_control_line_state_local()`` + - Implement ``tuh_cdc_get/set_dtr/rts()`` as inline functions + - Add ``get_itf_by_xfer()`` for better CDC interface determination + - Union FTDI/PL2303/ACM data structures to save memory + - Remove local device descriptor storage + +- MIDI Host + - Major API changes: + - Rename ``tuh_midi_stream_flush()`` to ``tuh_midi_write_flush()`` + - Add ``tuh_midi_packet_read_n()`` and ``tuh_midi_packet_write_n()`` + - Add ``CFG_TUH_MIDI_STREAM_API`` to opt out of stream API + - Change API to use index instead of device address (supports multiple MIDI per device) + - Add ``tuh_midi_mount_cb_t`` struct for mount callback + - Change ``tuh_midi_rx/tx_cb()`` to include ``xferred_bytes`` + - Rename ``tuh_midi_get_num_rx/tx_cables()`` to ``tuh_midi_get_rx/tx_cable_count()`` + - Add ``tuh_midi_descriptor_cb()`` and ``tuh_midi_itf_get_info()`` + - Fix ``iInterface`` value in ``tuh_midi_itf_get_info()`` + - Remove ``CFG_MIDI_HOST_DEVSTRINGS`` support + +- MSC Host + - Continue async I/O improvements + +- HID Host + - Fix version string to actually show version + 0.18.0 ====== diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index ca5c84151..1a088c989 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral driver and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -31,6 +31,7 @@ hw/mcu/renesas/fsp https://github.com/renesas/fsp.git hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx hw/mcu/silabs/cmsis-dfp-efm32gg12b https://github.com/cmsis-packs/cmsis-dfp-efm32gg12b.git f1c31b7887669cb230b3ea63f9b56769078960bc efm32 hw/mcu/sony/cxd56/spresense-exported-sdk https://github.com/sonydevworld/spresense-exported-sdk.git 2ec2a1538362696118dc3fdf56f33dacaf8f4067 spresense +hw/mcu/st/cmsis-device-u0 https://github.com/STMicroelectronics/cmsis-device-u0.git e3a627c6a5bc4eb2388e1885a95cc155e1672253 stm32u0 hw/mcu/st/cmsis-device-wba https://github.com/STMicroelectronics/cmsis-device-wba.git 647d8522e5fd15049e9a1cc30ed19d85e5911eaf stm32wba hw/mcu/st/cmsis_device_c0 https://github.com/STMicroelectronics/cmsis_device_c0.git 517611273f835ffe95318947647bc1408f69120d stm32c0 hw/mcu/st/cmsis_device_f0 https://github.com/STMicroelectronics/cmsis_device_f0.git cbb5da5d48b4b5f2efacdc2f033be30f9d29889f stm32f0 @@ -70,6 +71,7 @@ hw/mcu/st/stm32l1xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32l4xx_hal_driver https://github.com/STMicroelectronics/stm32l4xx_hal_driver.git 3e039bbf62f54bbd834d578185521cff80596efe stm32l4 hw/mcu/st/stm32l5xx_hal_driver https://github.com/STMicroelectronics/stm32l5xx_hal_driver.git 3340b9a597bcf75cc173345a90a74aa2a4a37510 stm32l5 hw/mcu/st/stm32n6xx_hal_driver https://github.com/STMicroelectronics/stm32n6xx-hal-driver.git bc6c41f8f67d61b47af26695d0bf67762a000666 stm32n6 +hw/mcu/st/stm32u0xx_hal_driver https://github.com/STMicroelectronics/stm32u0xx-hal-driver.git cbfb5ac654256445237fd32b3587ac6a238d24f1 stm32u0 hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2c5e2568fbdb1900a13ca3b2901fdd302cac3444 stm32u5 hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb @@ -78,10 +80,10 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32n6 stm32u5 stm32wb sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32n6 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git b0bbb0423b278ca632cfe1474eb227961d835fd2 ra lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== -- cgit v1.3.1 From 8832d22df9607050ecff7ce19bbfbaabce88311d Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 3 Oct 2025 22:13:59 +0700 Subject: update docs --- docs/info/changelog.rst | 3 +-- 1 file changed, 1 insertion(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index 16d4dffae..b0f411528 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -87,7 +87,6 @@ Controller Driver (DCD & HCD) - Chipidea/NXP - Fix race condition with spinlock - - Add async I/O support for MSC - Improve iMXRT support: fix build, disable BOARD_ConfigMPU, fix attach debouncing on port1 highspeed - Fix iMXRT1064 and add to HIL test pool @@ -135,8 +134,8 @@ Device Stack - Skip RX data with all zeroes - MSC + - Add async I/O support for MSC using ``tud_msc_async_io_done()`` - Add ``tud_msc_inquiry2_cb()`` with bufsize for full inquiry response - - Refactor async I/O: add ``in_isr`` argument to ``tud_msc_async_io_done()`` - MTP - Add new Media Transfer Protocol (MTP) device class driver -- cgit v1.3.1 From 8d7e8a11f6eb25724c8ec14fb7f0c243fdc02157 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 4 Oct 2025 12:19:51 +0700 Subject: update docs --- docs/info/changelog.rst | 24 ++---------------------- 1 file changed, 2 insertions(+), 22 deletions(-) (limited to 'docs') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index b0f411528..b4423f81e 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -11,20 +11,10 @@ General - New MCUs and Boards: - Add ESP32-H4, ESP32-C5, ESP32-C61 support - - Add STM32U083C-DK, STM32WBA, STM32N6570-DK, STM32N657 Nucleo + - Add STM32U0, STM32WBA, STM32N6 - Add AT32F405, AT32F403A, AT32F415, AT32F423 support - Add CH32V305 support and CH32V20x USB host support - Add MCXA156 SDK 2.16 support and FRDM-MCXA156 board - - Update all STM32 HAL and CMSIS dependencies to latest versions - -- Build System and CI Improvements - - Improve build system with GCC 14 support - - Add ARM IAR toolchain build support via CircleCI and GitHub Actions - - Add comprehensive CMake build documentation - - Improve hardware-in-the-loop (HIL) testing infrastructure - - Add Claude Code AI assistant workflows and documentation - -- Add ``tusb_deinit()`` function for stack cleanup API Changes ----------- @@ -37,7 +27,7 @@ API Changes - Introduce ``xfer_isr()`` callback for ISO transfer optimization in device classes - Device APIs - - CDC: Add ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, + - CDC: Add notification support ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - MSC: Add ``tud_msc_inquiry2_cb()`` with bufsize parameter, update ``tud_msc_async_io_done()`` with ``in_isr`` parameter @@ -184,16 +174,10 @@ Host Stack - CDC Serial Host - Major refactor to generalize CDC serial drivers (FTDI, CP210x, CH34x, PL2303, ACM) - - Add common 2-stage set line coding for drivers without direct support - - Add ``cdch_process_line_state_on_enum()`` for line state configuration during enumeration - - Refactor control transfer handling with ``cdch_internal_control_complete()`` - Add explicit ``sync()`` API with ``TU_API_SYNC()`` returning ``tusb_xfer_result_t`` - Rename ``tuh_cdc_get_local_line_coding()`` to ``tuh_cdc_get_line_coding_local()`` - Add ``tuh_cdc_get_control_line_state_local()`` - Implement ``tuh_cdc_get/set_dtr/rts()`` as inline functions - - Add ``get_itf_by_xfer()`` for better CDC interface determination - - Union FTDI/PL2303/ACM data structures to save memory - - Remove local device descriptor storage - MIDI Host - Major API changes: @@ -201,12 +185,8 @@ Host Stack - Add ``tuh_midi_packet_read_n()`` and ``tuh_midi_packet_write_n()`` - Add ``CFG_TUH_MIDI_STREAM_API`` to opt out of stream API - Change API to use index instead of device address (supports multiple MIDI per device) - - Add ``tuh_midi_mount_cb_t`` struct for mount callback - - Change ``tuh_midi_rx/tx_cb()`` to include ``xferred_bytes`` - Rename ``tuh_midi_get_num_rx/tx_cables()`` to ``tuh_midi_get_rx/tx_cable_count()`` - Add ``tuh_midi_descriptor_cb()`` and ``tuh_midi_itf_get_info()`` - - Fix ``iInterface`` value in ``tuh_midi_itf_get_info()`` - - Remove ``CFG_MIDI_HOST_DEVSTRINGS`` support - MSC Host - Continue async I/O improvements -- cgit v1.3.1 From 5a82112f5af0ba4dc2ccf93cb56a881c2e771f45 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Thu, 9 Oct 2025 05:50:55 +0000 Subject: docs: fix .rst links to use Sphinx :doc: role for proper HTML generation Co-authored-by: hathach <249515+hathach@users.noreply.github.com> --- docs/reference/getting_started.rst | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst index f1a755804..b891d911b 100644 --- a/docs/reference/getting_started.rst +++ b/docs/reference/getting_started.rst @@ -50,7 +50,7 @@ To incorporate tinyusb to your project Examples -------- -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of `the supported boards `_. Firstly we need to ``git clone`` if not already +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already .. code-block:: bash @@ -77,7 +77,7 @@ The hardware code is located in ``hw/bsp`` folder, and is organized by family/bo $ cd examples/device/cdc_msc $ make BOARD=feather_nrf52840_express get-deps -You only need to do this once per family. Check out `complete list of dependencies and their designated path here `_ +You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` Build Examples ^^^^^^^^^^^^^^ -- cgit v1.3.1 From 84f0cda013c83e8fa61c9d85f061f5f88cf30b9d Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 13 Oct 2025 14:53:28 +0700 Subject: rename pca10056 to nrf52840dk, pca10059 to nrf52840dongle --- docs/reference/boards.rst | 11 +- docs/reference/dependencies.rst | 2 +- hw/bsp/nrf/boards/nrf52840dk/board.cmake | 10 + hw/bsp/nrf/boards/nrf52840dk/board.h | 65 ++++++ hw/bsp/nrf/boards/nrf52840dk/board.mk | 5 + hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug | 238 +++++++++++++++++++++ hw/bsp/nrf/boards/nrf52840dongle/board.cmake | 5 + hw/bsp/nrf/boards/nrf52840dongle/board.h | 57 +++++ hw/bsp/nrf/boards/nrf52840dongle/board.mk | 15 ++ hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld | 13 ++ hw/bsp/nrf/boards/nrf54h20dk/board.h | 2 +- hw/bsp/nrf/boards/pca10056/board.cmake | 10 - hw/bsp/nrf/boards/pca10056/board.h | 65 ------ hw/bsp/nrf/boards/pca10056/board.mk | 5 - hw/bsp/nrf/boards/pca10056/ozone/nrf52840.jdebug | 238 --------------------- hw/bsp/nrf/boards/pca10059/board.cmake | 5 - hw/bsp/nrf/boards/pca10059/board.h | 57 ----- hw/bsp/nrf/boards/pca10059/board.mk | 15 -- hw/bsp/nrf/boards/pca10059/pca10059.ld | 13 -- 19 files changed, 416 insertions(+), 415 deletions(-) create mode 100644 hw/bsp/nrf/boards/nrf52840dk/board.cmake create mode 100644 hw/bsp/nrf/boards/nrf52840dk/board.h create mode 100644 hw/bsp/nrf/boards/nrf52840dk/board.mk create mode 100644 hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug create mode 100644 hw/bsp/nrf/boards/nrf52840dongle/board.cmake create mode 100644 hw/bsp/nrf/boards/nrf52840dongle/board.h create mode 100644 hw/bsp/nrf/boards/nrf52840dongle/board.mk create mode 100644 hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld delete mode 100644 hw/bsp/nrf/boards/pca10056/board.cmake delete mode 100644 hw/bsp/nrf/boards/pca10056/board.h delete mode 100644 hw/bsp/nrf/boards/pca10056/board.mk delete mode 100644 hw/bsp/nrf/boards/pca10056/ozone/nrf52840.jdebug delete mode 100644 hw/bsp/nrf/boards/pca10059/board.cmake delete mode 100644 hw/bsp/nrf/boards/pca10059/board.h delete mode 100644 hw/bsp/nrf/boards/pca10059/board.mk delete mode 100644 hw/bsp/nrf/boards/pca10059/pca10059.ld (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 3f8277247..e668e2693 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -202,10 +202,11 @@ circuitplayground_bluefruit Adafruit Circuit Playground Bluefruit nrf ht feather_nrf52840_express Adafruit Feather nRF52840 Express nrf https://www.adafruit.com/product/4062 feather_nrf52840_sense Adafruit Feather nRF52840 Sense nrf https://www.adafruit.com/product/4516 itsybitsy_nrf52840 Adafruit ItsyBitsy nRF52840 Express nrf https://www.adafruit.com/product/4481 -pca10056 Nordic nRF52840DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK -pca10059 Nordic nRF52840 Dongle nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle -pca10095 Nordic nRF5340 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK -pca10100 Nordic nRF52833 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK +nrf52833dk Nordic nRF52833 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52833-DK +nrf52840dk Nordic nRF52840DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK +nrf52840dongle Nordic nRF52840 Dongle nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle +nrf5340dk Nordic nRF5340 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK +nrf54h20dk Nordic nRF54H20 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK =========================== ===================================== ======== ============================================================================== ====== Raspberry Pi @@ -298,8 +299,8 @@ stm32l4p5nucleo STM32 L4P5 Nucleo stm32l4 https://www.s stm32l4r5nucleo STM32 L4R5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html stm32n6570dk STM32 N6570-DK stm32n6 https://www.st.com/en/evaluation-tools/stm32n6570-dk.html stm32n657nucleo STM32 N657X0-Q Nucleo stm32n6 https://www.st.com/en/evaluation-tools/nucleo-n657x0-q.html +stm32u083cdk STM32U083C-DK Discovery Kit stm32u0 https://www.st.com/en/evaluation-tools/stm32u083c-dk.html b_u585i_iot2a STM32 B-U585i IOT2A Discovery kit stm32u5 https://www.st.com/en/evaluation-tools/b-u585i-iot02a.html -stm32u083cdk STM32 U083C Discovery Kit stm32u0 https://www.st.com/en/evaluation-tools/stm32u083c-dk.html stm32u545nucleo STM32 U545 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u545re-q.html stm32u575eval STM32 U575 Eval stm32u5 https://www.st.com/en/evaluation-tools/stm32u575i-ev.html stm32u575nucleo STM32 U575 Nucleo stm32u5 https://www.st.com/en/evaluation-tools/nucleo-u575zi-q.html diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 1a088c989..9ca9b0b54 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -22,7 +22,7 @@ hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuc hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 -hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 7c47cc0a56ce44658e6da2458e86cd8783ccc4a2 nrf +hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt diff --git a/hw/bsp/nrf/boards/nrf52840dk/board.cmake b/hw/bsp/nrf/boards/nrf52840dk/board.cmake new file mode 100644 index 000000000..85314f3bc --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dk/board.cmake @@ -0,0 +1,10 @@ +set(MCU_VARIANT nrf52840) + +function(update_board TARGET) +endfunction() + +#board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000") +#include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) +#include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) +#include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) +#include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/hw/bsp/nrf/boards/nrf52840dk/board.h b/hw/bsp/nrf/boards/nrf52840dk/board.h new file mode 100644 index 000000000..ec632e769 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dk/board.h @@ -0,0 +1,65 @@ +/* + * 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. + */ + +/* metadata: + name: Nordic nRF52840DK + url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +// LED +#define LED_PIN 13 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PIN 25 // button 4 +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_RX_PIN 8 +#define UART_TX_PIN 6 + +// SPI for USB host shield +// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? +//#define MAX3421_SCK_PIN _PINNUM(1, 15) +//#define MAX3421_MOSI_PIN _PINNUM(1, 13) +//#define MAX3421_MISO_PIN _PINNUM(1, 14) +//#define MAX3421_CS_PIN _PINNUM(1, 12) +//#define MAX3421_INTR_PIN _PINNUM(1, 11) + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/nrf52840dk/board.mk b/hw/bsp/nrf/boards/nrf52840dk/board.mk new file mode 100644 index 000000000..d8bbd41f8 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dk/board.mk @@ -0,0 +1,5 @@ +MCU_VARIANT = nrf52840 +CFLAGS += -DNRF52840_XXAA + +# flash using jlink +flash: flash-jlink diff --git a/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug b/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug new file mode 100644 index 000000000..fa7ab9e23 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dk/ozone/nrf52840.jdebug @@ -0,0 +1,238 @@ + +/********************************************************************* +* +* OnProjectLoad +* +* Function description +* Project load routine. Required. +* +********************************************************************** +*/ +void OnProjectLoad (void) { + // Dialog-generated settings + Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); + Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); + + Project.SetDevice ("nRF52840_xxAA"); + Project.SetHostIF ("USB", ""); + Project.SetTargetIF ("SWD"); + Project.SetTIFSpeed ("8 MHz"); + Project.SetTraceSource ("Trace Pins"); + Project.SetTracePortWidth (4); + + // User settings + File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10056/cdc_msc.elf"); +} + +/********************************************************************* +* +* TargetReset +* +* Function description +* Replaces the default target device reset routine. Optional. +* +* Notes +* This example demonstrates the usage when +* debugging a RAM program on a Cortex-M target device +* +********************************************************************** +*/ +//void TargetReset (void) { +// +// unsigned int SP; +// unsigned int PC; +// unsigned int VectorTableAddr; +// +// Exec.Reset(); +// +// VectorTableAddr = Elf.GetBaseAddr(); +// +// if (VectorTableAddr != 0xFFFFFFFF) { +// +// Util.Log("Resetting Program."); +// +// SP = Target.ReadU32(VectorTableAddr); +// Target.SetReg("SP", SP); +// +// PC = Target.ReadU32(VectorTableAddr + 4); +// Target.SetReg("PC", PC); +// } +//} + +/********************************************************************* +* +* BeforeTargetReset +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetReset (void) { +//} + +/********************************************************************* +* +* AfterTargetReset +* +* Function description +* Event handler routine. +* - Sets the PC register to program reset value. +* - Sets the SP register to program reset value on Cortex-M. +* +********************************************************************** +*/ +void AfterTargetReset (void) { + unsigned int SP; + unsigned int PC; + unsigned int VectorTableAddr; + + VectorTableAddr = Elf.GetBaseAddr(); + + if (VectorTableAddr == 0xFFFFFFFF) { + Util.Log("Project file error: failed to get program base"); + } else { + SP = Target.ReadU32(VectorTableAddr); + Target.SetReg("SP", SP); + + PC = Target.ReadU32(VectorTableAddr + 4); + Target.SetReg("PC", PC); + } +} + +/********************************************************************* +* +* DebugStart +* +* Function description +* Replaces the default debug session startup routine. Optional. +* +********************************************************************** +*/ +//void DebugStart (void) { +//} + +/********************************************************************* +* +* TargetConnect +* +* Function description +* Replaces the default target IF connection routine. Optional. +* +********************************************************************** +*/ +//void TargetConnect (void) { +//} + +/********************************************************************* +* +* BeforeTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +void BeforeTargetConnect (void) { +} + +/********************************************************************* +* +* AfterTargetConnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetConnect (void) { +//} + +/********************************************************************* +* +* TargetDownload +* +* Function description +* Replaces the default program download routine. Optional. +* +********************************************************************** +*/ +//void TargetDownload (void) { +//} + +/********************************************************************* +* +* BeforeTargetDownload +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDownload (void) { +//} + +/********************************************************************* +* +* AfterTargetDownload +* +* Function description +* Event handler routine. +* - Sets the PC register to program reset value. +* - Sets the SP register to program reset value on Cortex-M. +* +********************************************************************** +*/ +void AfterTargetDownload (void) { + unsigned int SP; + unsigned int PC; + unsigned int VectorTableAddr; + + VectorTableAddr = Elf.GetBaseAddr(); + + if (VectorTableAddr == 0xFFFFFFFF) { + Util.Log("Project file error: failed to get program base"); + } else { + SP = Target.ReadU32(VectorTableAddr); + Target.SetReg("SP", SP); + + PC = Target.ReadU32(VectorTableAddr + 4); + Target.SetReg("PC", PC); + } +} + +/********************************************************************* +* +* BeforeTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void BeforeTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetDisconnect +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetDisconnect (void) { +//} + +/********************************************************************* +* +* AfterTargetHalt +* +* Function description +* Event handler routine. Optional. +* +********************************************************************** +*/ +//void AfterTargetHalt (void) { +//} diff --git a/hw/bsp/nrf/boards/nrf52840dongle/board.cmake b/hw/bsp/nrf/boards/nrf52840dongle/board.cmake new file mode 100644 index 000000000..5ec769192 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dongle/board.cmake @@ -0,0 +1,5 @@ +set(MCU_VARIANT nrf52840) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/${BOARD}.ld) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf52840dongle/board.h b/hw/bsp/nrf/boards/nrf52840dongle/board.h new file mode 100644 index 000000000..3b95481ad --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dongle/board.h @@ -0,0 +1,57 @@ +/* + * 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. + */ + +/* metadata: + name: Nordic nRF52840 Dongle + url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +// LED +#define LED_PIN 8 +#define LED_STATE_ON 0 + +// Button +#define BUTTON_PIN _PINNUM(1, 6) +#define BUTTON_STATE_ACTIVE 0 + +// UART +#define UART_RX_PIN 8 +#define UART_TX_PIN 6 + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/nrf52840dongle/board.mk b/hw/bsp/nrf/boards/nrf52840dongle/board.mk new file mode 100644 index 000000000..0b82ecdbb --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dongle/board.mk @@ -0,0 +1,15 @@ +MCU_VARIANT = nrf52840 +CFLAGS += -DNRF52840_XXAA + +LD_FILE = $(BOARD_PATH)/$(BOARD).ld + +# flash using Nordic nrfutil (pip2 install nrfutil) +# make BOARD=pca10059 SERIAL=/dev/ttyACM0 all flash +NRFUTIL = nrfutil + +$(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex + $(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@ + +flash: $(BUILD)/$(PROJECT).zip + @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) + $(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200 diff --git a/hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld b/hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld new file mode 100644 index 000000000..32cc6eada --- /dev/null +++ b/hw/bsp/nrf/boards/nrf52840dongle/nrf52840dongle.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000 + RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 +} + + +INCLUDE "nrf_common.ld" diff --git a/hw/bsp/nrf/boards/nrf54h20dk/board.h b/hw/bsp/nrf/boards/nrf54h20dk/board.h index 1c7981049..c8ed5779f 100644 --- a/hw/bsp/nrf/boards/nrf54h20dk/board.h +++ b/hw/bsp/nrf/boards/nrf54h20dk/board.h @@ -25,7 +25,7 @@ */ /* metadata: - name: Nordic nRF5340 DK + name: Nordic nRF54H20 DK url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK */ diff --git a/hw/bsp/nrf/boards/pca10056/board.cmake b/hw/bsp/nrf/boards/pca10056/board.cmake deleted file mode 100644 index 85314f3bc..000000000 --- a/hw/bsp/nrf/boards/pca10056/board.cmake +++ /dev/null @@ -1,10 +0,0 @@ -set(MCU_VARIANT nrf52840) - -function(update_board TARGET) -endfunction() - -#board_runner_args(jlink "--device=nRF52840_xxAA" "--speed=4000") -#include(${ZEPHYR_BASE}/boards/common/nrfjprog.board.cmake) -#include(${ZEPHYR_BASE}/boards/common/nrfutil.board.cmake) -#include(${ZEPHYR_BASE}/boards/common/jlink.board.cmake) -#include(${ZEPHYR_BASE}/boards/common/openocd-nrf5.board.cmake) diff --git a/hw/bsp/nrf/boards/pca10056/board.h b/hw/bsp/nrf/boards/pca10056/board.h deleted file mode 100644 index ec632e769..000000000 --- a/hw/bsp/nrf/boards/pca10056/board.h +++ /dev/null @@ -1,65 +0,0 @@ -/* - * 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. - */ - -/* metadata: - name: Nordic nRF52840DK - url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-DK -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define _PINNUM(port, pin) ((port)*32 + (pin)) - -// LED -#define LED_PIN 13 -#define LED_STATE_ON 0 - -// Button -#define BUTTON_PIN 25 // button 4 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_RX_PIN 8 -#define UART_TX_PIN 6 - -// SPI for USB host shield -// Pin is correct but not working probably due to signal incompatible (1.8V 3v3) with MAC3421E !? -//#define MAX3421_SCK_PIN _PINNUM(1, 15) -//#define MAX3421_MOSI_PIN _PINNUM(1, 13) -//#define MAX3421_MISO_PIN _PINNUM(1, 14) -//#define MAX3421_CS_PIN _PINNUM(1, 12) -//#define MAX3421_INTR_PIN _PINNUM(1, 11) - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/pca10056/board.mk b/hw/bsp/nrf/boards/pca10056/board.mk deleted file mode 100644 index d8bbd41f8..000000000 --- a/hw/bsp/nrf/boards/pca10056/board.mk +++ /dev/null @@ -1,5 +0,0 @@ -MCU_VARIANT = nrf52840 -CFLAGS += -DNRF52840_XXAA - -# flash using jlink -flash: flash-jlink diff --git a/hw/bsp/nrf/boards/pca10056/ozone/nrf52840.jdebug b/hw/bsp/nrf/boards/pca10056/ozone/nrf52840.jdebug deleted file mode 100644 index fa7ab9e23..000000000 --- a/hw/bsp/nrf/boards/pca10056/ozone/nrf52840.jdebug +++ /dev/null @@ -1,238 +0,0 @@ - -/********************************************************************* -* -* OnProjectLoad -* -* Function description -* Project load routine. Required. -* -********************************************************************** -*/ -void OnProjectLoad (void) { - // Dialog-generated settings - Project.AddSvdFile ("$(InstallDir)/Config/CPU/Cortex-M4F.svd"); - Project.AddSvdFile ("$(InstallDir)/Config/Peripherals/ARMv7M.svd"); - - Project.SetDevice ("nRF52840_xxAA"); - Project.SetHostIF ("USB", ""); - Project.SetTargetIF ("SWD"); - Project.SetTIFSpeed ("8 MHz"); - Project.SetTraceSource ("Trace Pins"); - Project.SetTracePortWidth (4); - - // User settings - File.Open ("../../../../../../examples/device/cdc_msc/cmake-build-pca10056/cdc_msc.elf"); -} - -/********************************************************************* -* -* TargetReset -* -* Function description -* Replaces the default target device reset routine. Optional. -* -* Notes -* This example demonstrates the usage when -* debugging a RAM program on a Cortex-M target device -* -********************************************************************** -*/ -//void TargetReset (void) { -// -// unsigned int SP; -// unsigned int PC; -// unsigned int VectorTableAddr; -// -// Exec.Reset(); -// -// VectorTableAddr = Elf.GetBaseAddr(); -// -// if (VectorTableAddr != 0xFFFFFFFF) { -// -// Util.Log("Resetting Program."); -// -// SP = Target.ReadU32(VectorTableAddr); -// Target.SetReg("SP", SP); -// -// PC = Target.ReadU32(VectorTableAddr + 4); -// Target.SetReg("PC", PC); -// } -//} - -/********************************************************************* -* -* BeforeTargetReset -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void BeforeTargetReset (void) { -//} - -/********************************************************************* -* -* AfterTargetReset -* -* Function description -* Event handler routine. -* - Sets the PC register to program reset value. -* - Sets the SP register to program reset value on Cortex-M. -* -********************************************************************** -*/ -void AfterTargetReset (void) { - unsigned int SP; - unsigned int PC; - unsigned int VectorTableAddr; - - VectorTableAddr = Elf.GetBaseAddr(); - - if (VectorTableAddr == 0xFFFFFFFF) { - Util.Log("Project file error: failed to get program base"); - } else { - SP = Target.ReadU32(VectorTableAddr); - Target.SetReg("SP", SP); - - PC = Target.ReadU32(VectorTableAddr + 4); - Target.SetReg("PC", PC); - } -} - -/********************************************************************* -* -* DebugStart -* -* Function description -* Replaces the default debug session startup routine. Optional. -* -********************************************************************** -*/ -//void DebugStart (void) { -//} - -/********************************************************************* -* -* TargetConnect -* -* Function description -* Replaces the default target IF connection routine. Optional. -* -********************************************************************** -*/ -//void TargetConnect (void) { -//} - -/********************************************************************* -* -* BeforeTargetConnect -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -void BeforeTargetConnect (void) { -} - -/********************************************************************* -* -* AfterTargetConnect -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void AfterTargetConnect (void) { -//} - -/********************************************************************* -* -* TargetDownload -* -* Function description -* Replaces the default program download routine. Optional. -* -********************************************************************** -*/ -//void TargetDownload (void) { -//} - -/********************************************************************* -* -* BeforeTargetDownload -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void BeforeTargetDownload (void) { -//} - -/********************************************************************* -* -* AfterTargetDownload -* -* Function description -* Event handler routine. -* - Sets the PC register to program reset value. -* - Sets the SP register to program reset value on Cortex-M. -* -********************************************************************** -*/ -void AfterTargetDownload (void) { - unsigned int SP; - unsigned int PC; - unsigned int VectorTableAddr; - - VectorTableAddr = Elf.GetBaseAddr(); - - if (VectorTableAddr == 0xFFFFFFFF) { - Util.Log("Project file error: failed to get program base"); - } else { - SP = Target.ReadU32(VectorTableAddr); - Target.SetReg("SP", SP); - - PC = Target.ReadU32(VectorTableAddr + 4); - Target.SetReg("PC", PC); - } -} - -/********************************************************************* -* -* BeforeTargetDisconnect -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void BeforeTargetDisconnect (void) { -//} - -/********************************************************************* -* -* AfterTargetDisconnect -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void AfterTargetDisconnect (void) { -//} - -/********************************************************************* -* -* AfterTargetHalt -* -* Function description -* Event handler routine. Optional. -* -********************************************************************** -*/ -//void AfterTargetHalt (void) { -//} diff --git a/hw/bsp/nrf/boards/pca10059/board.cmake b/hw/bsp/nrf/boards/pca10059/board.cmake deleted file mode 100644 index c79eb5964..000000000 --- a/hw/bsp/nrf/boards/pca10059/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(MCU_VARIANT nrf52840) -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/pca10059.ld) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/nrf/boards/pca10059/board.h b/hw/bsp/nrf/boards/pca10059/board.h deleted file mode 100644 index 3b95481ad..000000000 --- a/hw/bsp/nrf/boards/pca10059/board.h +++ /dev/null @@ -1,57 +0,0 @@ -/* - * 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. - */ - -/* metadata: - name: Nordic nRF52840 Dongle - url: https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus - extern "C" { -#endif - -#define _PINNUM(port, pin) ((port)*32 + (pin)) - -// LED -#define LED_PIN 8 -#define LED_STATE_ON 0 - -// Button -#define BUTTON_PIN _PINNUM(1, 6) -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_RX_PIN 8 -#define UART_TX_PIN 6 - -#ifdef __cplusplus - } -#endif - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/pca10059/board.mk b/hw/bsp/nrf/boards/pca10059/board.mk deleted file mode 100644 index 0b82ecdbb..000000000 --- a/hw/bsp/nrf/boards/pca10059/board.mk +++ /dev/null @@ -1,15 +0,0 @@ -MCU_VARIANT = nrf52840 -CFLAGS += -DNRF52840_XXAA - -LD_FILE = $(BOARD_PATH)/$(BOARD).ld - -# flash using Nordic nrfutil (pip2 install nrfutil) -# make BOARD=pca10059 SERIAL=/dev/ttyACM0 all flash -NRFUTIL = nrfutil - -$(BUILD)/$(PROJECT).zip: $(BUILD)/$(PROJECT).hex - $(NRFUTIL) pkg generate --hw-version 52 --sd-req 0x0000 --debug-mode --application $^ $@ - -flash: $(BUILD)/$(PROJECT).zip - @:$(call check_defined, SERIAL, example: SERIAL=/dev/ttyACM0) - $(NRFUTIL) dfu usb-serial --package $^ -p $(SERIAL) -b 115200 diff --git a/hw/bsp/nrf/boards/pca10059/pca10059.ld b/hw/bsp/nrf/boards/pca10059/pca10059.ld deleted file mode 100644 index 32cc6eada..000000000 --- a/hw/bsp/nrf/boards/pca10059/pca10059.ld +++ /dev/null @@ -1,13 +0,0 @@ -/* Linker script to configure memory regions. */ - -SEARCH_DIR(.) -/*GROUP(-lgcc -lc -lnosys) not compatible with clang*/ - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x1000, LENGTH = 0xff000 - RAM (rwx) : ORIGIN = 0x20000008, LENGTH = 0x3fff8 -} - - -INCLUDE "nrf_common.ld" -- cgit v1.3.1 From e4ff88f3640458f820838efd047a3831333446d8 Mon Sep 17 00:00:00 2001 From: c1570 Date: Mon, 22 Sep 2025 23:31:13 +0200 Subject: WIP improved docs (feat. LLM) --- docs/conf.py | 20 ++ docs/explanation/architecture.rst | 305 +++++++++++++++++++++++ docs/explanation/index.rst | 11 + docs/explanation/usb_concepts.rst | 352 ++++++++++++++++++++++++++ docs/faq.rst | 210 ++++++++++++++++ docs/guides/index.rst | 10 + docs/guides/integration.rst | 494 +++++++++++++++++++++++++++++++++++++ docs/index.rst | 64 ++++- docs/reference/concurrency.rst | 10 +- docs/reference/configuration.rst | 296 ++++++++++++++++++++++ docs/reference/dependencies.rst | 2 +- docs/reference/getting_started.rst | 269 -------------------- docs/reference/glossary.rst | 89 +++++++ docs/reference/index.rst | 12 +- docs/reference/usb_classes.rst | 290 ++++++++++++++++++++++ docs/troubleshooting.rst | 318 ++++++++++++++++++++++++ docs/tutorials/first_device.rst | 147 +++++++++++ docs/tutorials/first_host.rst | 160 ++++++++++++ docs/tutorials/getting_started.rst | 293 ++++++++++++++++++++++ docs/tutorials/index.rst | 12 + 20 files changed, 3079 insertions(+), 285 deletions(-) create mode 100644 docs/explanation/architecture.rst create mode 100644 docs/explanation/index.rst create mode 100644 docs/explanation/usb_concepts.rst create mode 100644 docs/faq.rst create mode 100644 docs/guides/index.rst create mode 100644 docs/guides/integration.rst create mode 100644 docs/reference/configuration.rst delete mode 100644 docs/reference/getting_started.rst create mode 100644 docs/reference/glossary.rst create mode 100644 docs/reference/usb_classes.rst create mode 100644 docs/troubleshooting.rst create mode 100644 docs/tutorials/first_device.rst create mode 100644 docs/tutorials/first_host.rst create mode 100644 docs/tutorials/getting_started.rst create mode 100644 docs/tutorials/index.rst (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index 4249d41f7..be9aeaaf9 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -24,9 +24,29 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', + 'sphinx.ext.viewcode', + 'sphinx.ext.napoleon', 'sphinx_autodoc_typehints', ] +# Autodoc configuration +autodoc_default_options = { + 'members': True, + 'undoc-members': True, + 'show-inheritance': True, +} + +# Napoleon configuration for Google/NumPy style docstrings +napoleon_google_docstring = True +napoleon_numpy_docstring = True +napoleon_include_init_with_doc = False +napoleon_include_private_with_doc = False + +# Intersphinx mapping for cross-references +intersphinx_mapping = { + 'python': ('https://docs.python.org/3', None), +} + templates_path = ['_templates'] exclude_patterns = ['_build'] diff --git a/docs/explanation/architecture.rst b/docs/explanation/architecture.rst new file mode 100644 index 000000000..4c63b198d --- /dev/null +++ b/docs/explanation/architecture.rst @@ -0,0 +1,305 @@ +************ +Architecture +************ + +This document explains TinyUSB's internal architecture, design principles, and how different components work together. + +Design Principles +================= + +Memory Safety +------------- + +TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: + +- **No dynamic allocation**: All memory is statically allocated at compile time +- **Bounded buffers**: All buffers have compile-time defined sizes +- **Stack-based design**: No heap usage in the core stack +- **Predictable memory usage**: Memory consumption is deterministic + +Thread Safety +------------- + +TinyUSB achieves thread safety through a deferred interrupt model: + +- **ISR deferral**: USB interrupts are captured and deferred to task context +- **Single-threaded processing**: All USB protocol handling occurs in task context +- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` +- **RTOS integration**: Proper semaphore/mutex usage for shared resources + +Portability +----------- + +The stack is designed to work across diverse microcontroller families: + +- **Hardware abstraction**: MCU-specific code isolated in portable drivers +- **OS abstraction**: RTOS dependencies isolated in OSAL layer +- **Modular design**: Features can be enabled/disabled at compile time +- **Standard compliance**: Strict adherence to USB specifications + +Core Architecture +================= + +Layer Structure +--------------- + +TinyUSB follows a layered architecture from hardware to application: + +.. code-block:: none + + ┌─────────────────────────────────────────┐ + │ Application Layer │ ← Your code + ├─────────────────────────────────────────┤ + │ USB Class Drivers │ ← CDC, HID, MSC, etc. + ├─────────────────────────────────────────┤ + │ Device/Host Stack Core │ ← USB protocol handling + ├─────────────────────────────────────────┤ + │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers + ├─────────────────────────────────────────┤ + │ OS Abstraction (OSAL) │ ← RTOS integration + ├─────────────────────────────────────────┤ + │ Common Utilities & FIFO │ ← Shared components + └─────────────────────────────────────────┘ + +Component Overview +------------------ + +**Application Layer**: Your main application code that uses TinyUSB APIs. + +**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. + +**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. + +**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. + +**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. + +**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. + +Device Stack Architecture +========================= + +Core Components +--------------- + +**Device Controller Driver (DCD)**: +- MCU-specific USB device peripheral driver +- Handles endpoint configuration and data transfers +- Abstracts hardware differences between MCU families +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Device Core (USBD)**: +- Implements USB device state machine +- Handles standard USB requests (Chapter 9) +- Manages device configuration and enumeration +- Located in ``src/device/`` + +**Class Drivers**: +- Implement USB class specifications +- Handle class-specific requests and data transfer +- Provide application APIs +- Located in ``src/class/*/`` + +Data Flow +--------- + +**Control Transfers (Setup Requests)**: + +.. code-block:: none + + USB Bus → DCD → USBD Core → Class Driver → Application + ↓ + Standard requests handled in core + ↓ + Class-specific requests → Class Driver + +**Data Transfers**: + +.. code-block:: none + + Application → Class Driver → USBD Core → DCD → USB Bus + USB Bus → DCD → USBD Core → Class Driver → Application + +Event Processing +---------------- + +TinyUSB uses a deferred interrupt model for thread safety: + +1. **Interrupt Occurs**: USB hardware generates interrupt +2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing +3. **Event Queuing**: Events queued for later processing +4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events +5. **Callback Execution**: Application callbacks executed in task context + +.. code-block:: none + + USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application + +Host Stack Architecture +======================= + +Core Components +--------------- + +**Host Controller Driver (HCD)**: +- MCU-specific USB host peripheral driver +- Manages USB pipes and data transfers +- Handles host controller hardware +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Host Core (USBH)**: +- Implements USB host functionality +- Manages device enumeration and configuration +- Handles pipe management and scheduling +- Located in ``src/host/`` + +**Hub Driver**: +- Manages USB hub devices +- Handles port management and device detection +- Supports multi-level hub topologies +- Located in ``src/host/`` + +Device Enumeration +------------------ + +The host stack follows USB enumeration process: + +1. **Device Detection**: Hub or root hub detects device connection +2. **Reset and Address**: Reset device, assign unique address +3. **Descriptor Retrieval**: Get device, configuration, and class descriptors +4. **Driver Matching**: Find appropriate class driver for device +5. **Configuration**: Configure device and start communication +6. **Class Operation**: Normal class-specific communication + +.. code-block:: none + + Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate + +Class Architecture +================== + +Common Class Structure +---------------------- + +All USB classes follow a similar architecture: + +**Device Classes**: +- ``*_device.c``: Device-side implementation +- ``*_device.h``: Device API definitions +- Implement class-specific descriptors +- Handle class requests and data transfer + +**Host Classes**: +- ``*_host.c``: Host-side implementation +- ``*_host.h``: Host API definitions +- Manage connected devices of this class +- Provide application interface + +Class Driver Interface +---------------------- + +**Required Functions**: +- ``init()``: Initialize class driver +- ``reset()``: Reset class state +- ``open()``: Configure class endpoints +- ``control_xfer_cb()``: Handle control requests +- ``xfer_cb()``: Handle data transfer completion + +**Optional Functions**: +- ``close()``: Clean up class resources +- ``sof_cb()``: Start-of-frame processing + +Descriptor Management +--------------------- + +Each class is responsible for: +- **Interface Descriptors**: Define class type and endpoints +- **Class-Specific Descriptors**: Additional class requirements +- **Endpoint Descriptors**: Define data transfer characteristics + +Memory Management +================= + +Static Allocation Model +----------------------- + +TinyUSB uses only static memory allocation: + +- **Endpoint Buffers**: Fixed-size buffers for each endpoint +- **Class Buffers**: Static buffers for class-specific data +- **Control Buffers**: Fixed buffer for control transfers +- **Queue Buffers**: Static event queues + +Buffer Management +----------------- + +**Endpoint Buffers**: +- Allocated per endpoint at compile time +- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros +- Used for USB data transfers + +**FIFO Buffers**: +- Ring buffers for streaming data +- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros +- Separate read/write pointers + +**DMA Considerations**: +- Buffers must be DMA-accessible on some MCUs +- Alignment requirements vary by hardware +- Cache coherency handled in portable drivers + +Threading Model +=============== + +Task-Based Design +----------------- + +TinyUSB uses a cooperative task model: + +- **Main Tasks**: ``tud_task()`` for device, ``tuh_task()`` for host +- **Regular Execution**: Tasks must be called regularly (< 1ms typical) +- **Event Processing**: All USB events processed in task context +- **Callback Execution**: Application callbacks run in task context + +RTOS Integration +---------------- + +**Bare Metal**: +- Application calls ``tud_task()`` in main loop +- No threading primitives needed +- Simplest integration method + +**FreeRTOS**: +- USB task runs at high priority +- Semaphores used for synchronization +- Queue for inter-task communication + +**Other RTOS**: +- Similar patterns with RTOS-specific primitives +- OSAL layer abstracts RTOS differences + +Interrupt Handling +------------------ + +**Interrupt Service Routine**: +- Minimal processing in ISR +- Event capture and queuing only +- Quick return to avoid blocking + +**Deferred Processing**: +- All complex processing in task context +- Thread-safe access to data structures +- Application callbacks in known context + +Memory Usage Patterns +--------------------- + +**Flash Memory**: +- Core stack: 8-15KB depending on features +- Each class: 1-4KB additional +- Portable driver: 2-8KB depending on MCU + +**RAM Usage**: +- Core stack: 1-2KB +- Endpoint buffers: User configurable +- Class buffers: Depends on configuration diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst new file mode 100644 index 000000000..695efd9e0 --- /dev/null +++ b/docs/explanation/index.rst @@ -0,0 +1,11 @@ +*********** +Explanation +*********** + +Deep understanding of TinyUSB's design, architecture, and concepts. + +.. toctree:: + :maxdepth: 2 + + architecture + usb_concepts \ No newline at end of file diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst new file mode 100644 index 000000000..02ba76770 --- /dev/null +++ b/docs/explanation/usb_concepts.rst @@ -0,0 +1,352 @@ +************ +USB Concepts +************ + +This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. + +USB Protocol Basics +==================== + +Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. + +Host and Device Roles +---------------------- + +**USB Host**: The controlling side of a USB connection (typically a computer). The host: +- Initiates all communication +- Provides power to devices +- Manages the USB bus +- Enumerates and configures devices + +**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See :doc:`../tutorials/first_host` for implementation details. + +**USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: +- Respond to host requests +- Cannot initiate communication +- Receive power from the host +- Must be enumerated by the host before use + +**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See :doc:`../tutorials/first_device` for implementation details. + +**OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. + +USB Transfers +============= + +Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. +Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. + +USB defines four transfer types, each intended for different use cases: + +Control Transfers +----------------- + +Used for device configuration and control commands. + +**Characteristics**: +- Bidirectional (uses both IN and OUT) +- Guaranteed delivery with error detection +- Limited data size (8-64 bytes per packet) +- All devices must support control transfers on endpoint 0 + +**Usage**: Device enumeration, configuration changes, class-specific commands + +**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). + +Bulk Transfers +-------------- + +Used for large amounts of data that don't require guaranteed timing. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Large packet sizes (up to 512 bytes for High Speed) +- Uses available bandwidth when no other transfers are active + +**Usage**: File transfers, large data communication, CDC serial data + +**TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. + +Interrupt Transfers +------------------- + +Used for small, time-sensitive data with guaranteed maximum latency. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Small packet sizes (up to 64 bytes for Full Speed) +- Regular polling interval (1ms to 255ms) + +**Usage**: Keyboard/mouse input, sensor data, status updates + +**TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. + +Isochronous Transfers +--------------------- + +Used for time-critical streaming data. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- No error correction (speed over reliability) +- Guaranteed bandwidth +- Real-time delivery + +**Usage**: Audio, video streaming + +**TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. + +Endpoints and Addressing +========================= + +Endpoint Basics +--------------- + +**Endpoint**: A communication channel between host and device. + +- Each endpoint has a number (0-15) and direction +- Endpoint 0 is reserved for control transfers +- Other endpoints are assigned by device class requirements + +**TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. + +**Direction**: +- **OUT**: Host to device (host sends data out) +- **IN**: Device to host (host reads data in) +- Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). + +**Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) + +Endpoint Configuration +---------------------- + +Each endpoint is configured with: +- **Transfer type**: Control, bulk, interrupt, or isochronous +- **Direction**: IN, OUT, or bidirectional (control only) +- **Maximum packet size**: Depends on USB speed and transfer type +- **Interval**: For interrupt and isochronous endpoints + +**TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. + +Error Handling and Flow Control +------------------------------- + +**Transfer Results**: USB transfers can complete with different results: +- **ACK**: Successful transfer +- **NAK**: Device not ready (used for flow control) +- **STALL**: Error condition or unsupported request +- **Timeout**: Transfer failed to complete in time + +**Flow Control in USB**: Unlike network protocols, USB doesn't use congestion control. Instead: +- Devices use NAK responses when not ready to receive data +- Applications implement buffering and proper timing +- Some classes (like CDC) support hardware flow control (RTS/CTS) + +**TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. + +USB Device States +================= + +A USB device progresses through several states: + +1. **Attached**: Device is physically connected +2. **Powered**: Device receives power from host +3. **Default**: Device responds to address 0 +4. **Address**: Device has been assigned a unique address +5. **Configured**: Device is ready for normal operation +6. **Suspended**: Device is in low-power state + +**TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. + +Device Enumeration Process +========================== + +When a device is connected, the host follows this process: + +1. **Detection**: Host detects device connection +2. **Reset**: Host resets the device +3. **Descriptor Requests**: Host requests device descriptors +4. **Address Assignment**: Host assigns unique address to device +5. **Configuration**: Host selects and configures device +6. **Class Loading**: Host loads appropriate drivers +7. **Normal Operation**: Device is ready for use + +**TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. + +USB Descriptors +=============== + +Descriptors are data structures that describe device capabilities: + +Device Descriptor +----------------- +Describes the device (VID, PID, USB version, etc.) + +Configuration Descriptor +------------------------ +Describes device configuration (power requirements, interfaces, etc.) + +Interface Descriptor +-------------------- +Describes a functional interface (class, endpoints, etc.) + +Endpoint Descriptor +------------------- +Describes endpoint characteristics (type, direction, size, etc.) + +String Descriptors +------------------ +Human-readable strings (manufacturer, product name, etc.) + +**TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: +- ``tud_descriptor_device_cb()`` - Device descriptor +- ``tud_descriptor_configuration_cb()`` - Configuration descriptor +- ``tud_descriptor_string_cb()`` - String descriptors + +The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. + +USB Classes +=========== + +USB classes define standardized protocols for device types: + +**Class Code**: Identifies the device type in descriptors +**Class Driver**: Software that implements the class protocol +**Class Requests**: Standardized commands for the class + +**Common TinyUSB-Supported Classes**: +- **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` +- **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` +- **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` +- **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` +- **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` +- **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` +- **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` + +See :doc:`../reference/usb_classes` for detailed class information and :doc:`../reference/configuration` for configuration options. + +USB Speeds +========== + +USB supports multiple speed modes: + +**Low Speed (1.5 Mbps)**: +- Simple devices (mice, keyboards) +- Limited endpoint types and sizes + +**Full Speed (12 Mbps)**: +- Most common for embedded devices +- All transfer types supported +- Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) + +**High Speed (480 Mbps)**: +- High-performance devices +- Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) +- Requires more complex hardware + +**Super Speed (5 Gbps)**: +- USB 3.0 and later +- Not supported by TinyUSB + +**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. + +USB Device Controllers +====================== + +USB device controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. + +Controller Fundamentals +----------------------- + +**What Controllers Do**: +- Handle USB signaling and protocol timing +- Manage endpoint buffers and data transfers +- Generate interrupts for USB events +- Implement USB electrical specifications + +**Key Components**: +- **Physical Layer**: USB signal drivers and receivers +- **Protocol Engine**: Handles USB packets, ACK/NAK responses +- **Endpoint Buffers**: Hardware FIFOs or RAM for data storage +- **Interrupt Controller**: Generates events for software processing + +Controller Architecture Types +----------------------------- + +Different MCU vendors implement USB controllers with varying architectures. +To list a few common patterns: + +**FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): +- Shared or dedicated FIFOs for endpoint data +- Software manages FIFO allocation and data flow +- Common in higher-end MCUs with flexible configurations + +**Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): +- Fixed packet memory areas for each endpoint +- Hardware automatically handles packet placement +- Simpler programming model, common in smaller MCUs + +**Descriptor-Based Controllers** (e.g., NXP EHCI-style): +- Use descriptor chains to describe transfers +- Hardware processes transfer descriptors independently +- More complex but can handle larger transfers autonomously + +TinyUSB Controller Abstraction +------------------------------ + +TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. +These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. + +**Portable Interface** (``src/device/usbd.h``): +- Standardized function signatures for all controllers +- Common endpoint and transfer management APIs +- Unified interrupt and event handling + +**Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): +- Implement the DCD interface for specific hardware +- Handle vendor-specific register layouts and behaviors +- Manage controller-specific quirks and workarounds + +**Common DCD Functions**: +- ``dcd_init()`` - Initialize controller hardware +- ``dcd_edpt_open()`` - Configure endpoint with type and size +- ``dcd_edpt_xfer()`` - Start data transfer on endpoint +- ``dcd_int_handler()`` - Process USB interrupts +- ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection + +Controller Event Flow +--------------------- + +**Typical USB Event Processing**: + +1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) +2. **Interrupt Generation**: Controller generates interrupt to CPU +3. **ISR Processing**: ``dcd_int_handler()`` reads controller status +4. **Event Queuing**: Events are queued for later processing (thread safety) +5. **Task Processing**: ``tud_task()`` processes queued events +6. **Class Notification**: Appropriate class drivers handle the event +7. **Application Callback**: User code responds to the event + +Power Management +================ + +USB provides power to devices: + +**Bus-Powered**: Device draws power from USB bus (up to 500mA) +**Self-Powered**: Device has its own power source +**Suspend/Resume**: Devices must enter low-power mode when bus is idle + +**TinyUSB Power Management**: +- Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management +- Configure power requirements in device descriptor (``bMaxPower`` field) +- Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) +- Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` + +Next Steps +========== + +- Start with :doc:`../tutorials/getting_started` for basic setup +- Review :doc:`../reference/configuration` for configuration options +- Check :doc:`../guides/integration` for advanced integration scenarios diff --git a/docs/faq.rst b/docs/faq.rst new file mode 100644 index 000000000..ede97032d --- /dev/null +++ b/docs/faq.rst @@ -0,0 +1,210 @@ +************************** +Frequently Asked Questions +************************** + +General Questions +================= + +**Q: What microcontrollers does TinyUSB support?** + +TinyUSB supports 30+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. + +**Q: Can I use TinyUSB in commercial projects?** + +Yes, TinyUSB is released under the MIT license, allowing commercial use with minimal restrictions. + +**Q: Does TinyUSB require an RTOS?** + +No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, and Mynewt. + +**Q: How much memory does TinyUSB use?** + +Typical usage: 8-20KB flash, 1-4KB RAM depending on enabled classes and configuration. The stack uses static allocation only. + +Build and Setup +================ + +**Q: Why do I get "arm-none-eabi-gcc: command not found"?** + +Install the ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` on Ubuntu/Debian, or download from ARM's website for other platforms. + +**Q: Build fails with "Board 'X' not found"** + +Check available boards: ``ls hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` to list all supported boards. + +**Q: What are the dependencies and how do I get them?** + +Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., stm32f4, rp2040). This downloads MCU-specific drivers and libraries. + +**Q: Can I use my own build system instead of Make/CMake?** + +Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`guides/integration` for details. + +**Q: Error: "tusb_config.h: No such file or directory"** + +This is a very common issue. You need to create ``tusb_config.h`` in your project and ensure it's in your include path. The file must define ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS`` at minimum. Copy from ``examples/device/*/tusb_config.h`` as a starting point. + +**Q: RP2040 + pico-sdk ignores my tusb_config.h settings** + +The pico-sdk build system can override ``tusb_config.h`` settings. The ``CFG_TUSB_OS`` setting is often ignored because pico-sdk sets it to ``OPT_OS_PICO`` internally. Use pico-sdk specific configuration methods or modify the CMake configuration. + +**Q: "multiple definition of dcd_..." errors with STM32** + +This happens when multiple USB drivers are included. Ensure you're only including the correct portable driver for your STM32 family. Check that ``CFG_TUSB_MCU`` is set correctly and you don't have conflicting source files. + +Device Development +================== + +**Q: My USB device isn't recognized by the host** + +Common causes: +- Invalid USB descriptors - validate with ``LOG=2`` build +- ``tud_task()`` not called regularly in main loop +- Incorrect ``tusb_config.h`` settings +- USB cable doesn't support data (charging-only cable) + +**Q: Windows shows "Device Descriptor Request Failed"** + +This typically indicates: +- Malformed device descriptor +- USB timing issues (check crystal/clock configuration) +- Power supply problems during enumeration +- Conflicting devices on the same USB hub + +**Q: How do I implement a custom USB class?** + +Use the vendor class interface (``CFG_TUD_VENDOR``) or implement a custom class driver. See ``src/class/vendor/`` for examples. + +**Q: Can I have multiple configurations or interfaces?** + +Yes, TinyUSB supports multiple configurations and composite devices. Modify the descriptors in ``usb_descriptors.c`` accordingly. + +**Q: How do I change Vendor ID/Product ID?** + +Edit the device descriptor in ``usb_descriptors.c``. For production, obtain your own VID from USB-IF or use one from your silicon vendor. + +**Q: Device works alone but fails when connected through USB hub** + +This is a known issue where some devices interfere with each other when connected to the same hub. Try: +- Using different USB hubs +- Connecting devices to separate USB ports +- Checking for power supply issues with the hub + +Host Development +================ + +**Q: Why doesn't my host application detect any devices?** + +Check: +- Power supply - host mode requires more power than device mode +- USB connector type - use USB-A for host applications +- Board supports host mode on the selected port +- Enable logging with ``LOG=2`` to see enumeration details + +**Q: Can I connect multiple devices simultaneously?** + +Yes, through a USB hub. TinyUSB supports multi-level hubs and multiple device connections. + +**Q: Does TinyUSB support USB 3.0?** + +No, TinyUSB currently supports USB 2.0 and earlier. USB 3.0 devices typically work in USB 2.0 compatibility mode. + +Configuration and Features +========================== + +**Q: How do I enable/disable specific USB classes?** + +Edit ``tusb_config.h`` and set the corresponding ``CFG_TUD_*`` or ``CFG_TUH_*`` macros to 1 (enable) or 0 (disable). + +**Q: Can I use both device and host modes simultaneously?** + +Yes, with dual-role/OTG capable hardware. See ``examples/dual/`` for implementation examples. + +**Q: How do I optimize for code size?** + +- Disable unused classes in ``tusb_config.h`` +- Use ``CFG_TUSB_DEBUG = 0`` for release builds +- Compile with ``-Os`` optimization +- Consider using only required endpoints/interfaces + +**Q: Does TinyUSB support low power/suspend modes?** + +Yes, TinyUSB handles USB suspend/resume. Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for custom power management. + +**Q: What CFG_TUSB_MCU should I use for x86/PC platforms?** + +For PC/motherboard applications, there's no standard MCU option. You may need to use a generic option or modify TinyUSB for your specific use case. Consider using libusb or other PC-specific USB libraries instead. + +**Q: RP2040 FreeRTOS configuration issues** + +The RP2040 pico-sdk has specific requirements for FreeRTOS integration. The ``CFG_TUSB_OS`` setting may be overridden by the SDK. Use pico-sdk specific configuration methods and ensure proper task stack sizes for the USB task. + +Debugging and Troubleshooting +============================= + +**Q: How do I debug USB communication issues?** + +1. Enable logging: build with ``LOG=2`` +2. Use ``LOGGER=rtt`` or ``LOGGER=swo`` for high-speed logging +3. Use USB protocol analyzers for detailed traffic analysis +4. Check with different host systems (Windows/Linux/macOS) + +**Q: My application crashes or hard faults** + +Common causes: +- Stack overflow - increase stack size in linker script +- Incorrect interrupt configuration +- Buffer overruns in USB callbacks +- Build with ``DEBUG=1`` and use a debugger + +**Q: Performance is poor or USB transfers are slow** + +- Ensure ``tud_task()``/``tuh_task()`` called frequently (< 1ms intervals) +- Use DMA for USB transfers if supported by your MCU +- Optimize endpoint buffer sizes +- Consider using high-speed USB if available + +**Q: Some USB devices don't work with my host application** + +- Not all devices follow USB standards perfectly +- Some may need device-specific handling +- Composite devices may have partial support +- Check device descriptors and implement custom drivers if needed + +**Q: ESP32-S3 USB host/device issues** + +ESP32-S3 has specific USB implementation challenges: +- Ensure proper USB pin configuration +- Check power supply requirements for host mode +- Some features may be limited compared to other MCUs +- Use ESP32-S3 specific examples and documentation + +STM32CubeIDE Integration +======================== + +**Q: How do I integrate TinyUSB with STM32CubeIDE?** + +1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode +2. Enable the USB global interrupt in NVIC Settings +3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c +4. Call ``tud_task()`` in your main loop +5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` +6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files + +**Q: STM32CubeIDE generated code conflicts with TinyUSB** + +Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. + +**Q: STM32 USB interrupt handler setup** + +Replace the generated USB interrupt handler with a call to TinyUSB: + +.. code-block:: c + + void OTG_FS_IRQHandler(void) { + tud_int_handler(0); + } + +**Q: Which STM32 families work best with TinyUSB?** + +STM32F4, F7, and H7 families have the most mature TinyUSB support. STM32F0, F1, F3, L4 families are also supported but may have more limitations. Check the supported boards list for your specific variant. \ No newline at end of file diff --git a/docs/guides/index.rst b/docs/guides/index.rst new file mode 100644 index 000000000..cad3dd27f --- /dev/null +++ b/docs/guides/index.rst @@ -0,0 +1,10 @@ +********** +How-to Guides +********** + +Problem-solving guides for common TinyUSB development tasks. + +.. toctree:: + :maxdepth: 2 + + integration \ No newline at end of file diff --git a/docs/guides/integration.rst b/docs/guides/integration.rst new file mode 100644 index 000000000..c135c5ec6 --- /dev/null +++ b/docs/guides/integration.rst @@ -0,0 +1,494 @@ +********************* +Integration Guide +********************* + +This guide covers integrating TinyUSB into production projects with your own build system, custom hardware, and specific requirements. + +Project Integration Methods +============================ + +Method 1: Git Submodule (Recommended) +-------------------------------------- + +Best for projects using git version control. + +.. code-block:: bash + + # Add TinyUSB as submodule + git submodule add https://github.com/hathach/tinyusb.git lib/tinyusb + git submodule update --init --recursive + +**Advantages:** +- Pinned to specific TinyUSB version +- Easy to update with ``git submodule update`` +- Version control tracks exact TinyUSB commit + +Method 2: Package Manager Integration +------------------------------------- + +**PlatformIO:** + +.. code-block:: ini + + ; platformio.ini + [env:myboard] + platform = your_platform + board = your_board + framework = arduino ; or other framework + lib_deps = + https://github.com/hathach/tinyusb.git + +**CMake FetchContent:** + +.. code-block:: cmake + + include(FetchContent) + FetchContent_Declare( + tinyusb + GIT_REPOSITORY https://github.com/hathach/tinyusb.git + GIT_TAG master # or specific version tag + ) + FetchContent_MakeAvailable(tinyusb) + +Method 3: Direct Copy +--------------------- + +Copy TinyUSB source files directly into your project. + +.. code-block:: bash + + # Copy only source files + cp -r tinyusb/src/ your_project/lib/tinyusb/ + +**Note:** You'll need to manually update when TinyUSB releases new versions. + +Build System Integration +======================== + +Make/GCC Integration +-------------------- + +**Makefile example:** + +.. code-block:: make + + # TinyUSB settings + TUSB_DIR = lib/tinyusb + TUSB_SRC_DIR = $(TUSB_DIR)/src + + # Include paths + CFLAGS += -I$(TUSB_SRC_DIR) + CFLAGS += -I. # For tusb_config.h + + # MCU and OS settings (pass to compiler) + CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32F4 + CFLAGS += -DCFG_TUSB_OS=OPT_OS_NONE + + # TinyUSB source files + SRC_C += $(wildcard $(TUSB_SRC_DIR)/*.c) + SRC_C += $(wildcard $(TUSB_SRC_DIR)/common/*.c) + SRC_C += $(wildcard $(TUSB_SRC_DIR)/device/*.c) + SRC_C += $(wildcard $(TUSB_SRC_DIR)/class/*/*.c) + SRC_C += $(wildcard $(TUSB_SRC_DIR)/portable/$(VENDOR)/$(CHIP_FAMILY)/*.c) + +**Finding the right portable driver:** + +.. code-block:: bash + + # List available drivers + find lib/tinyusb/src/portable -name "*.c" | grep stm32 + # Use: lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + +CMake Integration +----------------- + +**CMakeLists.txt example:** + +.. code-block:: cmake + + # TinyUSB configuration + set(FAMILY_MCUS STM32F4) # Set your MCU family + set(CFG_TUSB_MCU OPT_MCU_STM32F4) + set(CFG_TUSB_OS OPT_OS_FREERTOS) # or OPT_OS_NONE + + # Add TinyUSB + add_subdirectory(lib/tinyusb) + + # Your project + add_executable(your_app + src/main.c + src/usb_descriptors.c + # other sources + ) + + # Link TinyUSB + target_link_libraries(your_app + tinyusb_device # or tinyusb_host + # other libraries + ) + + # Include paths + target_include_directories(your_app PRIVATE + src/ # For tusb_config.h + ) + + # Compile definitions + target_compile_definitions(your_app PRIVATE + CFG_TUSB_MCU=${CFG_TUSB_MCU} + CFG_TUSB_OS=${CFG_TUSB_OS} + ) + +IAR Embedded Workbench +---------------------- + +Use project connection files for easy integration: + +1. Open IAR project +2. Add TinyUSB project connection: ``Tools → Configure Custom Argument Variables`` +3. Create ``TUSB`` group, add ``TUSB_DIR`` variable +4. Import ``tinyusb/tools/iar_template.ipcf`` + +Keil µVision +------------ + +.. code-block:: none + + # Add to project groups: + TinyUSB/Common: src/common/*.c + TinyUSB/Device: src/device/*.c, src/class/*/*.c + TinyUSB/Portable: src/portable/vendor/family/*.c + + # Include paths: + src/ # tusb_config.h location + lib/tinyusb/src/ + + # Preprocessor defines: + CFG_TUSB_MCU=OPT_MCU_STM32F4 + CFG_TUSB_OS=OPT_OS_NONE + +Configuration Setup +=================== + +Create tusb_config.h +-------------------- + +This is the most critical file for TinyUSB integration: + +.. code-block:: c + + // tusb_config.h + #ifndef _TUSB_CONFIG_H_ + #define _TUSB_CONFIG_H_ + + // MCU selection - REQUIRED + #ifndef CFG_TUSB_MCU + #define CFG_TUSB_MCU OPT_MCU_STM32F4 + #endif + + // OS selection - REQUIRED + #ifndef CFG_TUSB_OS + #define CFG_TUSB_OS OPT_OS_NONE + #endif + + // Debug level + #define CFG_TUSB_DEBUG 0 + + // Device stack + #define CFG_TUD_ENABLED 1 + #define CFG_TUD_ENDPOINT0_SIZE 64 + + // Device classes + #define CFG_TUD_CDC 1 + #define CFG_TUD_HID 0 + #define CFG_TUD_MSC 0 + + // CDC configuration + #define CFG_TUD_CDC_EP_BUFSIZE 512 + #define CFG_TUD_CDC_RX_BUFSIZE 512 + #define CFG_TUD_CDC_TX_BUFSIZE 512 + + #endif + +USB Descriptors +--------------- + +Create or modify ``usb_descriptors.c`` for your device: + +.. code-block:: c + + #include "tusb.h" + + // Device descriptor + tusb_desc_device_t const desc_device = { + .bLength = sizeof(tusb_desc_device_t), + .bDescriptorType = TUSB_DESC_DEVICE, + .bcdUSB = 0x0200, + .bDeviceClass = TUSB_CLASS_MISC, + .bDeviceSubClass = MISC_SUBCLASS_COMMON, + .bDeviceProtocol = MISC_PROTOCOL_IAD, + .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, + .idVendor = 0xCafe, // Your VID + .idProduct = 0x4000, // Your PID + .bcdDevice = 0x0100, + .iManufacturer = 0x01, + .iProduct = 0x02, + .iSerialNumber = 0x03, + .bNumConfigurations = 0x01 + }; + + // Get device descriptor + uint8_t const* tud_descriptor_device_cb(void) { + return (uint8_t const*)&desc_device; + } + + // Configuration descriptor - implement based on your needs + uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { + // Return configuration descriptor + } + + // String descriptors + uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { + // Return string descriptors + } + +Application Integration +====================== + +Main Loop Integration +-------------------- + +.. code-block:: c + + #include "tusb.h" + + int main(void) { + // Board/MCU initialization + board_init(); // Your board setup + + // USB stack initialization + tusb_init(); + + while (1) { + // USB device task - MUST be called regularly + tud_task(); + + // Your application code + your_app_task(); + } + } + +Interrupt Handler Setup +----------------------- + +**STM32 example:** + +.. code-block:: c + + // USB interrupt handler + void OTG_FS_IRQHandler(void) { + tud_int_handler(0); + } + +**RP2040 example:** + +.. code-block:: c + + void isr_usbctrl(void) { + tud_int_handler(0); + } + +Class Implementation +-------------------- + +Implement required callbacks for enabled classes: + +.. code-block:: c + + // CDC class callbacks + void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { + // Handle line coding changes + } + + void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { + // Handle DTR/RTS changes + } + +RTOS Integration +=============== + +FreeRTOS Integration +------------------- + +.. code-block:: c + + // USB task + void usb_device_task(void* param) { + while (1) { + tud_task(); + vTaskDelay(1); // 1ms delay + } + } + + // Create USB task + xTaskCreate(usb_device_task, "usbd", + 256, NULL, configMAX_PRIORITIES-1, NULL); + +**Configuration:** + +.. code-block:: c + + // In tusb_config.h + #define CFG_TUSB_OS OPT_OS_FREERTOS + #define CFG_TUD_TASK_QUEUE_SZ 16 + +RT-Thread Integration +-------------------- + +.. code-block:: c + + // In tusb_config.h + #define CFG_TUSB_OS OPT_OS_RTTHREAD + + // USB thread + void usb_thread_entry(void* parameter) { + tusb_init(); + while (1) { + tud_task(); + rt_thread_mdelay(1); + } + } + +Custom Hardware Integration +=========================== + +Clock Configuration +------------------- + +USB requires precise 48MHz clock: + +**STM32 example:** + +.. code-block:: c + + // Configure PLL for 48MHz USB clock + RCC_OscInitStruct.PLL.PLLQ = 7; // Adjust for 48MHz + HAL_RCC_OscConfig(&RCC_OscInitStruct); + +**RP2040 example:** + +.. code-block:: c + + // USB clock is automatically configured by SDK + +Pin Configuration +----------------- + +Configure USB pins correctly: + +**STM32 example:** + +.. code-block:: c + + // USB pins: PA11 (DM), PA12 (DP) + GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; + GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; + GPIO_InitStruct.Pull = GPIO_NOPULL; + GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; + GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; + HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); + +Power Management +--------------- + +For battery-powered applications: + +.. code-block:: c + + // Implement suspend/resume callbacks + void tud_suspend_cb(bool remote_wakeup_en) { + // Enter low power mode + } + + void tud_resume_cb(void) { + // Exit low power mode + } + +Testing and Validation +====================== + +Build Verification +------------------ + +.. code-block:: bash + + # Test build + make clean && make all + + # Check binary size + arm-none-eabi-size build/firmware.elf + + # Verify no undefined symbols + arm-none-eabi-nm build/firmware.elf | grep " U " + +Runtime Testing +--------------- + +1. **Device Recognition**: Check if device appears in system +2. **Enumeration**: Verify all descriptors are valid +3. **Class Functionality**: Test class-specific features +4. **Performance**: Measure transfer rates and latency +5. **Stress Testing**: Long-running tests with connect/disconnect + +Debugging Integration Issues +============================ + +Common Problems +--------------- + +1. **Device not recognized**: Check descriptors and configuration +2. **Build errors**: Verify include paths and source files +3. **Link errors**: Check library dependencies +4. **Runtime crashes**: Enable debug builds and use debugger +5. **Poor performance**: Profile code and optimize critical paths + +Debug Builds +------------ + +.. code-block:: c + + // In tusb_config.h for debugging + #define CFG_TUSB_DEBUG 2 + #define CFG_TUSB_DEBUG_PRINTF printf + +Enable logging to identify issues quickly. + +Production Considerations +========================= + +Code Size Optimization +---------------------- + +.. code-block:: c + + // Minimal configuration + #define CFG_TUSB_DEBUG 0 + #define CFG_TUD_CDC 1 + #define CFG_TUD_HID 0 + #define CFG_TUD_MSC 0 + // Disable unused classes + +Performance Optimization +------------------------ + +- Use DMA for USB transfers if available +- Optimize descriptor sizes +- Use appropriate endpoint buffer sizes +- Consider high-speed USB for high bandwidth applications + +Compliance and Certification +---------------------------- + +- Validate descriptors against USB specifications +- Test with USB-IF compliance tools +- Consider USB-IF certification for commercial products +- Test with multiple host operating systems \ No newline at end of file diff --git a/docs/index.rst b/docs/index.rst index c1c8e4d99..9fbc5bd30 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,14 +1,64 @@ -:hide-toc: +TinyUSB Documentation +===================== -.. include:: ../README_processed.rst +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. + +For Developers +-------------- + +TinyUSB provides a complete USB stack implementation supporting both device and host modes across a wide range of microcontrollers. The stack is designed for resource-constrained embedded systems with emphasis on code size, memory efficiency, and real-time performance. + +**Key Features:** + +* **Thread-safe design**: All USB interrupts are deferred to task context +* **Memory-safe**: No dynamic allocation, all buffers are statically allocated +* **Portable**: Supports 30+ MCU families from major vendors +* **Comprehensive**: Device classes (CDC, HID, MSC, Audio, etc.) and Host stack +* **RTOS support**: Works with bare metal, FreeRTOS, RT-Thread, and Mynewt + +**Quick Navigation:** + +* New to TinyUSB? Start with :doc:`tutorials/getting_started` +* Need to solve a specific problem? Check :doc:`guides/index` +* Looking for API details? See :doc:`reference/index` +* Want to understand the design? Read :doc:`explanation/architecture` +* Having issues? Check :doc:`faq` and :doc:`troubleshooting` + +Documentation Structure +----------------------- .. toctree:: - :caption: Index - :hidden: + :maxdepth: 2 + :caption: Learning + + tutorials/index + +.. toctree:: + :maxdepth: 2 + :caption: Problem Solving + + guides/index + faq + troubleshooting + +.. toctree:: + :maxdepth: 2 + :caption: Information + + reference/index + +.. toctree:: + :maxdepth: 2 + :caption: Understanding + + explanation/index + +.. toctree:: + :maxdepth: 1 + :caption: Project Info - Info - Reference - Contributing + info/index + contributing/index .. toctree:: :caption: External Links diff --git a/docs/reference/concurrency.rst b/docs/reference/concurrency.rst index 776fa4b6d..99e7e7b70 100644 --- a/docs/reference/concurrency.rst +++ b/docs/reference/concurrency.rst @@ -3,17 +3,17 @@ Concurrency *********** The TinyUSB library is designed to operate on single-core MCUs with multi-threaded applications in mind. Interaction with interrupts is especially important to pay attention to. -It is compatible with optionally using a RTOS. +It is compatible with optionally using an RTOS. General ------- -When writing code, keep in mind that the OS (if using a RTOS) may swap out your code at any time. Also, your code can be preempted by an interrupt at any time. +When writing code, keep in mind that the OS (if using an RTOS) may swap out your code at any time. Also, your code can be preempted by an interrupt at any time. Application Code ---------------- -The USB core does not execute application callbacks while in an interrupt context. Calls to application code are from within the USB core task context. Note that the application core will call class drivers from within their own task. +The USB core does not execute application callbacks while in an interrupt context. Calls to application code are from within the USB core task context. Note that the application core will call class drivers from within its own task. Class Drivers ------------- @@ -38,5 +38,5 @@ Much of the processing of the USB stack is done in an interrupt context, and car In particular: -* Ensure that all memory-mapped registers (including packet memory) are marked as volatile. GCC's optimizer will even combine memory access (like two 16-bit to be a 32-bit) if you don't mark the pointers as volatile. On some architectures, this can use macros like _I , _O , or _IO. -* All defined global variables are marked as ``static``. +* Ensure that all memory-mapped registers (including packet memory) are marked as volatile. GCC's optimizer will even combine memory accesses (like two 16-bit to be a 32-bit) if you don't mark the pointers as volatile. On some architectures, this can use macros like _I , _O , or _IO. +* All defined global variables are marked as ``static``. diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst new file mode 100644 index 000000000..8d6dd6190 --- /dev/null +++ b/docs/reference/configuration.rst @@ -0,0 +1,296 @@ +************* +Configuration +************* + +TinyUSB behavior is controlled through compile-time configuration in ``tusb_config.h``. This reference covers all available configuration options. + +Basic Configuration +=================== + +Required Settings +----------------- + +.. code-block:: c + + // Target MCU family - REQUIRED + #define CFG_TUSB_MCU OPT_MCU_STM32F4 + + // OS abstraction layer - REQUIRED + #define CFG_TUSB_OS OPT_OS_NONE + + // Enable device or host stack + #define CFG_TUD_ENABLED 1 // Device stack + #define CFG_TUH_ENABLED 1 // Host stack + +Debug and Logging +----------------- + +.. code-block:: c + + // Debug level (0=off, 1=error, 2=warning, 3=info) + #define CFG_TUSB_DEBUG 2 + + // Memory alignment for buffers (usually 4) + #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) + +Device Stack Configuration +========================== + +Endpoint Configuration +---------------------- + +.. code-block:: c + + // Control endpoint buffer size + #define CFG_TUD_ENDPOINT0_SIZE 64 + + // Number of endpoints (excluding EP0) + #define CFG_TUD_ENDPOINT_MAX 16 + +Device Classes +-------------- + +**CDC (Communication Device Class)**: + +.. code-block:: c + + #define CFG_TUD_CDC 1 // Number of CDC interfaces + #define CFG_TUD_CDC_EP_BUFSIZE 512 // CDC endpoint buffer size + #define CFG_TUD_CDC_RX_BUFSIZE 256 // CDC RX FIFO size + #define CFG_TUD_CDC_TX_BUFSIZE 256 // CDC TX FIFO size + +**HID (Human Interface Device)**: + +.. code-block:: c + + #define CFG_TUD_HID 1 // Number of HID interfaces + #define CFG_TUD_HID_EP_BUFSIZE 16 // HID endpoint buffer size + +**MSC (Mass Storage Class)**: + +.. code-block:: c + + #define CFG_TUD_MSC 1 // Number of MSC interfaces + #define CFG_TUD_MSC_EP_BUFSIZE 512 // MSC endpoint buffer size + +**Audio Class**: + +.. code-block:: c + + #define CFG_TUD_AUDIO 1 // Number of audio interfaces + #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN 220 + #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 + #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 + #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 + #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 + #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 2 + +**MIDI**: + +.. code-block:: c + + #define CFG_TUD_MIDI 1 // Number of MIDI interfaces + #define CFG_TUD_MIDI_RX_BUFSIZE 128 // MIDI RX buffer size + #define CFG_TUD_MIDI_TX_BUFSIZE 128 // MIDI TX buffer size + +**DFU (Device Firmware Update)**: + +.. code-block:: c + + #define CFG_TUD_DFU 1 // Enable DFU mode + #define CFG_TUD_DFU_XFER_BUFSIZE 512 // DFU transfer buffer size + +**Vendor Class**: + +.. code-block:: c + + #define CFG_TUD_VENDOR 1 // Number of vendor interfaces + #define CFG_TUD_VENDOR_EPSIZE 64 // Vendor endpoint size + +Host Stack Configuration +======================== + +Port and Hub Configuration +-------------------------- + +.. code-block:: c + + // Number of host root hub ports + #define CFG_TUH_HUB 1 + + // Number of connected devices (including hub) + #define CFG_TUH_DEVICE_MAX 5 + + // Control transfer buffer size + #define CFG_TUH_ENUMERATION_BUFSIZE 512 + +Host Classes +------------ + +**CDC Host**: + +.. code-block:: c + + #define CFG_TUH_CDC 2 // Number of CDC host instances + #define CFG_TUH_CDC_FTDI 1 // FTDI serial support + #define CFG_TUH_CDC_CP210X 1 // CP210x serial support + #define CFG_TUH_CDC_CH34X 1 // CH34x serial support + +**HID Host**: + +.. code-block:: c + + #define CFG_TUH_HID 4 // Number of HID instances + #define CFG_TUH_HID_EPIN_BUFSIZE 64 // HID endpoint buffer size + #define CFG_TUH_HID_EPOUT_BUFSIZE 64 + +**MSC Host**: + +.. code-block:: c + + #define CFG_TUH_MSC 1 // Number of MSC instances + #define CFG_TUH_MSC_MAXLUN 4 // Max LUNs per device + +Advanced Configuration +====================== + +Memory Management +----------------- + +.. code-block:: c + + // Enable stack protection + #define CFG_TUSB_DEBUG_PRINTF printf + + // Custom memory allocation (if needed) + #define CFG_TUSB_MEM_SECTION __attribute__((section(".usb_ram"))) + +RTOS Configuration +------------------ + +**FreeRTOS**: + +.. code-block:: c + + #define CFG_TUSB_OS OPT_OS_FREERTOS + #define CFG_TUD_TASK_QUEUE_SZ 16 + #define CFG_TUH_TASK_QUEUE_SZ 16 + +**RT-Thread**: + +.. code-block:: c + + #define CFG_TUSB_OS OPT_OS_RTTHREAD + +Low Power Configuration +----------------------- + +.. code-block:: c + + // Enable remote wakeup + #define CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP 1 + + // Suspend/resume callbacks + // Implement tud_suspend_cb() and tud_resume_cb() + +MCU-Specific Options +==================== + +The ``CFG_TUSB_MCU`` option selects the target microcontroller family: + +.. code-block:: c + + // STM32 families + #define CFG_TUSB_MCU OPT_MCU_STM32F0 + #define CFG_TUSB_MCU OPT_MCU_STM32F1 + #define CFG_TUSB_MCU OPT_MCU_STM32F4 + #define CFG_TUSB_MCU OPT_MCU_STM32F7 + #define CFG_TUSB_MCU OPT_MCU_STM32H7 + + // NXP families + #define CFG_TUSB_MCU OPT_MCU_LPC18XX + #define CFG_TUSB_MCU OPT_MCU_LPC40XX + #define CFG_TUSB_MCU OPT_MCU_LPC43XX + #define CFG_TUSB_MCU OPT_MCU_KINETIS_KL + #define CFG_TUSB_MCU OPT_MCU_IMXRT + + // Other vendors + #define CFG_TUSB_MCU OPT_MCU_RP2040 + #define CFG_TUSB_MCU OPT_MCU_ESP32S2 + #define CFG_TUSB_MCU OPT_MCU_ESP32S3 + #define CFG_TUSB_MCU OPT_MCU_SAMD21 + #define CFG_TUSB_MCU OPT_MCU_SAMD51 + #define CFG_TUSB_MCU OPT_MCU_NRF5X + +Configuration Examples +====================== + +Minimal Device (CDC only) +-------------------------- + +.. code-block:: c + + #define CFG_TUSB_MCU OPT_MCU_STM32F4 + #define CFG_TUSB_OS OPT_OS_NONE + #define CFG_TUSB_DEBUG 0 + + #define CFG_TUD_ENABLED 1 + #define CFG_TUD_ENDPOINT0_SIZE 64 + + #define CFG_TUD_CDC 1 + #define CFG_TUD_CDC_EP_BUFSIZE 512 + #define CFG_TUD_CDC_RX_BUFSIZE 512 + #define CFG_TUD_CDC_TX_BUFSIZE 512 + + // Disable other classes + #define CFG_TUD_HID 0 + #define CFG_TUD_MSC 0 + #define CFG_TUD_MIDI 0 + #define CFG_TUD_AUDIO 0 + #define CFG_TUD_VENDOR 0 + +Full-Featured Host +------------------ + +.. code-block:: c + + #define CFG_TUSB_MCU OPT_MCU_STM32F4 + #define CFG_TUSB_OS OPT_OS_FREERTOS + #define CFG_TUSB_DEBUG 2 + + #define CFG_TUH_ENABLED 1 + #define CFG_TUH_HUB 1 + #define CFG_TUH_DEVICE_MAX 8 + #define CFG_TUH_ENUMERATION_BUFSIZE 512 + + #define CFG_TUH_CDC 2 + #define CFG_TUH_HID 4 + #define CFG_TUH_MSC 2 + #define CFG_TUH_VENDOR 2 + +Validation +========== + +Use these checks to validate your configuration: + +.. code-block:: c + + // In your main.c, add compile-time checks + #if !defined(CFG_TUSB_MCU) || (CFG_TUSB_MCU == OPT_MCU_NONE) + #error "CFG_TUSB_MCU must be defined" + #endif + + #if CFG_TUD_ENABLED && !defined(CFG_TUD_ENDPOINT0_SIZE) + #error "CFG_TUD_ENDPOINT0_SIZE must be defined for device stack" + #endif + +Common Configuration Issues +=========================== + +1. **Endpoint buffer size too small**: Causes transfer failures +2. **Missing CFG_TUSB_MCU**: Build will fail +3. **Incorrect OS setting**: RTOS functions won't work properly +4. **Insufficient endpoint count**: Device enumeration will fail +5. **Buffer size mismatches**: Data corruption or transfer failures + +For configuration examples specific to your board, check ``examples/device/*/tusb_config.h``. \ No newline at end of file diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 9ca9b0b54..e04cc2c2f 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -2,7 +2,7 @@ Dependencies ************ -MCU low-level peripheral driver and external libraries for building TinyUSB examples +MCU low-level peripheral drivers and external libraries for building TinyUSB examples ======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by diff --git a/docs/reference/getting_started.rst b/docs/reference/getting_started.rst deleted file mode 100644 index b891d911b..000000000 --- a/docs/reference/getting_started.rst +++ /dev/null @@ -1,269 +0,0 @@ -*************** -Getting Started -*************** - -Add TinyUSB to your project ---------------------------- - -To incorporate tinyusb to your project - -* Copy or ``git submodule`` this repo into your project in a subfolder. Let's say it is ``your_project/tinyusb`` -* Add all the ``.c`` in the ``tinyusb/src`` folder to your project -* Add ``your_project/tinyusb/src`` to your include path. Also make sure your current include path also contains the configuration file ``tusb_config.h``. -* Make sure all required macros are all defined properly in ``tusb_config.h`` (configure file in demo application is sufficient, but you need to add a few more such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS`` since they are passed by make/cmake to maintain a unique configure for all boards). -* If you use the device stack, make sure you have created/modified usb descriptors for your own need. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. -* Add ``tusb_init(rhport, role)`` call to your reset initialization code. -* Call ``tusb_int_handler(rhport, in_isr)`` in your USB IRQ Handler -* Implement all enabled classes's callbacks. -* If you don't use any RTOSes at all, you need to continuously and/or periodically call ``tud_task()``/``tuh_task()`` function. All of the callbacks and functionality are handled and invoked within the call of that task runner. - -.. code-block:: c - - int main(void) { - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(0, &dev_init); // initialize device stack on roothub port 0 - - tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_HOST, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(1, &host_init); // initialize host stack on roothub port 1 - - while(1) { // the mainloop - your_application_code(); - tud_task(); // device task - tuh_task(); // host task - } - } - - void USB0_IRQHandler(void) { - tusb_int_handler(0, true); - } - - void USB1_IRQHandler(void) { - tusb_int_handler(1, true); - } - -Examples --------- - -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already - -.. code-block:: bash - - $ git clone https://github.com/hathach/tinyusb tinyusb - $ cd tinyusb - -Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for tinyusb, you should download/install it first according to its manufacturer guide. - -Dependencies -^^^^^^^^^^^^ - -The hardware code is located in ``hw/bsp`` folder, and is organized by family/boards. e.g raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. Before building, we firstly need to download dependencies such as: MCU low-level peripheral driver and external libraries e.g FreeRTOS (required by some examples). We can do that by either ways: - -1. Run ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a family as follow. Note: For TinyUSB developer to download all dependencies, use FAMILY=all. - -.. code-block:: bash - - $ python tools/get_deps.py rp2040 - -2. Or run the ``get-deps`` target in one of the example folder as follow. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=feather_nrf52840_express get-deps - -You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` - -Build Examples -^^^^^^^^^^^^^^ - -Examples support make and cmake build system for most MCUs, however some MCU families such as espressif or rp2040 only support cmake. First change directory to an example folder. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - -Then compile with make or cmake - -.. code-block:: bash - - $ # make - $ make BOARD=feather_nrf52840_express all - - $ # cmake - $ mkdir build && cd build - $ cmake -DBOARD=raspberry_pi_pico .. - $ make - -To list all available targets with cmake - -.. code-block:: bash - - $ cmake --build . --target help - -Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``99-tinyusb.rules`` and reload your udev is good to go - -.. code-block:: bash - - $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ - $ sudo udevadm control --reload-rules && sudo udevadm trigger - -RootHub Port Selection -~~~~~~~~~~~~~~~~~~~~~~ - -If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. - -Port Speed -~~~~~~~~~~ - -A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force F723 operate at full instead of default high speed - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. - -Size Analysis -~~~~~~~~~~~~~ - -First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap - -Debug -^^^^^ - -To compile for debugging add ``DEBUG=1``\ , for example - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express DEBUG=1 all - - $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. - -Log -~~~ - -Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional ``LOG=``. ``LOG=1`` will only print out error message, ``LOG=2`` print more information with on-going events. ``LOG=3`` or higher is not used yet. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. - -Logger -~~~~~~ - -By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols: - - -* `LOGGER=rtt`: use `Segger RTT protocol `_ - - * Cons: requires jlink as the debugger. - * Pros: work with most if not all MCUs - * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. - -* ``LOGGER=swo`` : Use dedicated SWO pin of ARM Cortex SWD debug header. - - * Cons: only work with ARM Cortex MCUs minus M0 - * Pros: should be compatible with more debugger that support SWO. - * Software viewer should be provided along with your debugger driver. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. - -Flash -^^^^^ - -``flash`` target will use the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary, please install those support software in advance. Some board use bootloader/DFU via serial which is required to pass to make command - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash - $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash - -Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash-jlink - $ make BOARD=feather_nrf52840_express flash-openocd - - $ cmake --build . --target cdc_msc-jlink - $ cmake --build . --target cdc_msc-openocd - -Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can be generated with ``uf2`` target - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express all uf2 - - $ cmake --build . --target cdc_msc-uf2 - -IAR Support -^^^^^^^^^^^ - -Use project connection -~~~~~~~~~~~~~~~~~~~~~~ - -IAR Project Connection files are provided to import TinyUSB stack into your project. - -* A buildable project of your MCU need to be created in advance. - - * Take example of STM32F0: - - - You need ``stm32l0xx.h``, ``startup_stm32f0xx.s``, ``system_stm32f0xx.c``. - - - ``STM32L0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. - -* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) - Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, - for example ``C:\\tinyusb`` - -**Import stack only** - -Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. - -**Run examples** - -1. Run ``iar_gen.py`` to generate .ipcf files of examples: - - .. code-block:: - - > cd C:\tinyusb\tools - > python iar_gen.py - -2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. - For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` - -Native CMake support -~~~~~~~~~~~~~~~~~~~~ - -With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. - -Following these steps: - -1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. -2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. -3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. -4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst new file mode 100644 index 000000000..e6e92738f --- /dev/null +++ b/docs/reference/glossary.rst @@ -0,0 +1,89 @@ +******** +Glossary +******** + +.. glossary:: + + Bulk Transfer + USB transfer type used for large amounts of data that doesn't require guaranteed timing. Used by mass storage devices and CDC class. + + CDC + Communications Device Class. USB class for devices that communicate serial data, creating virtual serial ports. + + Control Transfer + USB transfer type used for device configuration and control. All USB devices must support control transfers on endpoint 0. + + DCD + Device Controller Driver. The hardware abstraction layer for USB device controllers in TinyUSB. + + Descriptor + Data structures that describe USB device capabilities, configuration, and interfaces to the host. + + Device Class + USB specification defining how devices of a particular type (e.g., storage, audio, HID) communicate with hosts. + + DFU + Device Firmware Update. USB class that allows firmware updates over USB. + + Endpoint + Communication channel between host and device. Each endpoint has a direction (IN/OUT) and transfer type. + + Enumeration + Process where USB host discovers and configures a newly connected device. + + HCD + Host Controller Driver. The hardware abstraction layer for USB host controllers in TinyUSB. + + HID + Human Interface Device. USB class for input devices like keyboards, mice, and game controllers. + + High Speed + USB 2.0 speed mode operating at 480 Mbps. + + Full Speed + USB speed mode operating at 12 Mbps, supported by USB 1.1 and 2.0. + + Low Speed + USB speed mode operating at 1.5 Mbps, typically used by simple input devices. + + Interrupt Transfer + USB transfer type for small, time-sensitive data with guaranteed maximum latency. + + Isochronous Transfer + USB transfer type for time-critical data like audio/video with guaranteed bandwidth but no error correction. + + MSC + Mass Storage Class. USB class for storage devices like USB drives. + + OSAL + Operating System Abstraction Layer. TinyUSB component that abstracts RTOS differences. + + OTG + On-The-Go. USB specification allowing devices to act as both host and device. + + Pipe + Host-side communication channel to a device endpoint. + + Root Hub + The USB hub built into the host controller, where devices connect directly. + + Stall + USB protocol mechanism where an endpoint responds with a STALL handshake to indicate an error condition or unsupported request. Used for error handling, not flow control. + + Super Speed + USB 3.0 speed mode operating at 5 Gbps. Not supported by TinyUSB. + + UAC + USB Audio Class. USB class for audio devices. + + UVC + USB Video Class. USB class for video devices like cameras. + + VID + Vendor Identifier. 16-bit number assigned by USB-IF to identify device manufacturers. + + PID + Product Identifier. 16-bit number assigned by vendor to identify specific products. + + USB-IF + USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. \ No newline at end of file diff --git a/docs/reference/index.rst b/docs/reference/index.rst index 8ac3cf924..cb35dd1b9 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -1,10 +1,16 @@ -Index -===== +********* +Reference +********* + +Complete reference documentation for TinyUSB APIs, configuration, and supported hardware. .. toctree:: :maxdepth: 2 - getting_started + api/index + configuration + usb_classes boards dependencies concurrency + glossary diff --git a/docs/reference/usb_classes.rst b/docs/reference/usb_classes.rst new file mode 100644 index 000000000..00a251ffb --- /dev/null +++ b/docs/reference/usb_classes.rst @@ -0,0 +1,290 @@ +*********** +USB Classes +*********** + +TinyUSB supports multiple USB device and host classes. This reference describes the features, capabilities, and requirements for each class. + +Device Classes +============== + +CDC (Communication Device Class) +-------------------------------- + +Implements USB CDC specification for serial communication. + +**Supported Features:** +- CDC-ACM (Abstract Control Model) for virtual serial ports +- Data terminal ready (DTR) and request to send (RTS) control lines +- Line coding configuration (baud rate, parity, stop bits) +- Break signal support + +**Configuration:** +- ``CFG_TUD_CDC``: Number of CDC interfaces (1-4) +- ``CFG_TUD_CDC_EP_BUFSIZE``: Endpoint buffer size (typically 512) +- ``CFG_TUD_CDC_RX_BUFSIZE``: Receive FIFO size +- ``CFG_TUD_CDC_TX_BUFSIZE``: Transmit FIFO size + +**Key Functions:** +- ``tud_cdc_available()``: Check bytes available to read +- ``tud_cdc_read()``: Read data from host +- ``tud_cdc_write()``: Write data to host +- ``tud_cdc_write_flush()``: Flush transmit buffer + +**Callbacks:** +- ``tud_cdc_line_coding_cb()``: Line coding changed +- ``tud_cdc_line_state_cb()``: DTR/RTS state changed + +HID (Human Interface Device) +---------------------------- + +Implements USB HID specification for input devices. + +**Supported Features:** +- Boot protocol (keyboard/mouse) +- Report protocol with custom descriptors +- Input, output, and feature reports +- Multiple HID interfaces + +**Configuration:** +- ``CFG_TUD_HID``: Number of HID interfaces +- ``CFG_TUD_HID_EP_BUFSIZE``: Endpoint buffer size + +**Key Functions:** +- ``tud_hid_ready()``: Check if ready to send report +- ``tud_hid_report()``: Send HID report +- ``tud_hid_keyboard_report()``: Send keyboard report +- ``tud_hid_mouse_report()``: Send mouse report + +**Callbacks:** +- ``tud_hid_descriptor_report_cb()``: Provide report descriptor +- ``tud_hid_get_report_cb()``: Handle get report request +- ``tud_hid_set_report_cb()``: Handle set report request + +MSC (Mass Storage Class) +------------------------ + +Implements USB mass storage for file systems. + +**Supported Features:** +- SCSI transparent command set +- Multiple logical units (LUNs) +- Read/write operations +- Inquiry and capacity commands + +**Configuration:** +- ``CFG_TUD_MSC``: Number of MSC interfaces +- ``CFG_TUD_MSC_EP_BUFSIZE``: Endpoint buffer size + +**Key Functions:** +- Storage operations handled via callbacks + +**Required Callbacks:** +- ``tud_msc_inquiry_cb()``: Device inquiry information +- ``tud_msc_test_unit_ready_cb()``: Test if LUN is ready +- ``tud_msc_capacity_cb()``: Get LUN capacity +- ``tud_msc_start_stop_cb()``: Start/stop LUN +- ``tud_msc_read10_cb()``: Read data from LUN +- ``tud_msc_write10_cb()``: Write data to LUN + +Audio Class +----------- + +Implements USB Audio Class 2.0 specification. + +**Supported Features:** +- Audio streaming (input/output) +- Multiple sampling rates +- Volume and mute controls +- Feedback endpoints for asynchronous mode + +**Configuration:** +- ``CFG_TUD_AUDIO``: Number of audio functions +- Multiple configuration options for channels, sample rates, bit depth + +**Key Functions:** +- ``tud_audio_read()``: Read audio data +- ``tud_audio_write()``: Write audio data +- ``tud_audio_clear_ep_out_ff()``: Clear output FIFO + +MIDI +---- + +Implements USB MIDI specification. + +**Supported Features:** +- MIDI 1.0 message format +- Multiple virtual MIDI cables +- Standard MIDI messages + +**Configuration:** +- ``CFG_TUD_MIDI``: Number of MIDI interfaces +- ``CFG_TUD_MIDI_RX_BUFSIZE``: Receive buffer size +- ``CFG_TUD_MIDI_TX_BUFSIZE``: Transmit buffer size + +**Key Functions:** +- ``tud_midi_available()``: Check available MIDI messages +- ``tud_midi_read()``: Read MIDI packet +- ``tud_midi_write()``: Send MIDI packet + +DFU (Device Firmware Update) +---------------------------- + +Implements USB DFU specification for firmware updates. + +**Supported Modes:** +- DFU Mode: Device enters DFU for firmware update +- DFU Runtime: Request transition to DFU mode + +**Configuration:** +- ``CFG_TUD_DFU``: Enable DFU mode +- ``CFG_TUD_DFU_RUNTIME``: Enable DFU runtime + +**Key Functions:** +- Firmware update operations handled via callbacks + +**Required Callbacks:** +- ``tud_dfu_download_cb()``: Receive firmware data +- ``tud_dfu_manifest_cb()``: Complete firmware update + +Vendor Class +------------ + +Custom vendor-specific USB class implementation. + +**Features:** +- Configurable endpoints +- Custom protocol implementation +- WebUSB support +- Microsoft OS descriptors + +**Configuration:** +- ``CFG_TUD_VENDOR``: Number of vendor interfaces +- ``CFG_TUD_VENDOR_EPSIZE``: Endpoint size + +**Key Functions:** +- ``tud_vendor_available()``: Check available data +- ``tud_vendor_read()``: Read vendor data +- ``tud_vendor_write()``: Write vendor data + +Host Classes +============ + +CDC Host +-------- + +Connect to CDC devices (virtual serial ports). + +**Supported Devices:** +- CDC-ACM devices +- FTDI USB-to-serial converters +- CP210x USB-to-serial converters +- CH34x USB-to-serial converters + +**Configuration:** +- ``CFG_TUH_CDC``: Number of CDC host instances +- ``CFG_TUH_CDC_FTDI``: Enable FTDI support +- ``CFG_TUH_CDC_CP210X``: Enable CP210x support + +**Key Functions:** +- ``tuh_cdc_available()``: Check available data +- ``tuh_cdc_read()``: Read from CDC device +- ``tuh_cdc_write()``: Write to CDC device +- ``tuh_cdc_set_baudrate()``: Configure serial settings + +HID Host +-------- + +Connect to HID devices (keyboards, mice, etc.). + +**Supported Devices:** +- Boot keyboards and mice +- Generic HID devices with report descriptors +- Composite HID devices + +**Configuration:** +- ``CFG_TUH_HID``: Number of HID host instances +- ``CFG_TUH_HID_EPIN_BUFSIZE``: Input endpoint buffer size + +**Key Functions:** +- ``tuh_hid_receive_report()``: Start receiving reports +- ``tuh_hid_send_report()``: Send report to device +- ``tuh_hid_parse_report_descriptor()``: Parse HID descriptors + +MSC Host +-------- + +Connect to mass storage devices (USB drives). + +**Supported Features:** +- SCSI transparent command set +- FAT file system support (with FatFS integration) +- Multiple LUNs per device + +**Configuration:** +- ``CFG_TUH_MSC``: Number of MSC host instances +- ``CFG_TUH_MSC_MAXLUN``: Maximum LUNs per device + +**Key Functions:** +- ``tuh_msc_ready()``: Check if device is ready +- ``tuh_msc_read10()``: Read sectors from device +- ``tuh_msc_write10()``: Write sectors to device + +Hub +--- + +Support for USB hubs to connect multiple devices. + +**Features:** +- Multi-level hub support +- Port power management +- Device connect/disconnect detection + +**Configuration:** +- ``CFG_TUH_HUB``: Number of hub instances +- ``CFG_TUH_DEVICE_MAX``: Total connected devices + +Class Implementation Guidelines +=============================== + +Descriptor Requirements +----------------------- + +Each USB class requires specific descriptors: + +1. **Interface Descriptor**: Defines the class type +2. **Endpoint Descriptors**: Define communication endpoints +3. **Class-Specific Descriptors**: Additional class requirements +4. **String Descriptors**: Human-readable device information + +Callback Implementation +----------------------- + +Most classes require callback functions: + +- **Mandatory callbacks**: Must be implemented for class to function +- **Optional callbacks**: Provide additional functionality +- **Event callbacks**: Called when specific events occur + +Performance Considerations +-------------------------- + +- **Buffer Sizes**: Match endpoint buffer sizes to expected data rates +- **Transfer Types**: Use appropriate USB transfer types (bulk, interrupt, isochronous) +- **CPU Usage**: Minimize processing in interrupt context +- **Memory Usage**: Static allocation only, no dynamic memory + +Testing and Validation +---------------------- + +- **USB-IF Compliance**: Ensure descriptors meet USB standards +- **Host Compatibility**: Test with multiple operating systems +- **Performance Testing**: Verify transfer rates and latency +- **Error Handling**: Test disconnect/reconnect scenarios + +Class-Specific Resources +======================== + +- **USB-IF Specifications**: Official USB class specifications +- **Example Code**: Reference implementations in ``examples/`` directory +- **Test Applications**: Host-side test applications for validation +- **Debugging Tools**: USB protocol analyzers and debugging utilities \ No newline at end of file diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst new file mode 100644 index 000000000..1f0f388df --- /dev/null +++ b/docs/troubleshooting.rst @@ -0,0 +1,318 @@ +*************** +Troubleshooting +*************** + +This guide helps you diagnose and fix common issues when developing with TinyUSB. + +Build Issues +============ + +Toolchain Problems +------------------ + +**"arm-none-eabi-gcc: command not found"** + +The ARM GCC toolchain is not installed or not in PATH. + +*Solution*: +.. code-block:: bash + + # Ubuntu/Debian + sudo apt-get update && sudo apt-get install gcc-arm-none-eabi + + # macOS with Homebrew + brew install --cask gcc-arm-embedded + + # Windows: Download from ARM website and add to PATH + +**"make: command not found" or CMake errors** + +Build tools are missing. + +*Solution*: +.. code-block:: bash + + # Ubuntu/Debian + sudo apt-get install build-essential cmake + + # macOS + xcode-select --install + brew install cmake + +Dependency Issues +----------------- + +**"No rule to make target" or missing header files** + +Dependencies for your MCU family are not downloaded. + +*Solution*: +.. code-block:: bash + + # Download dependencies for specific family + python tools/get_deps.py stm32f4 # Replace with your family + + # Or from example directory + cd examples/device/cdc_msc + make BOARD=your_board get-deps + +**Board Not Found** + +Invalid board name in build command. + +*Diagnosis*: +.. code-block:: bash + + # List available boards for a family + ls hw/bsp/stm32f4/boards/ + + # List all supported boards + python tools/build.py -l + +*Solution*: Use exact board name from the listing. + +Runtime Issues +============== + +Device Mode Problems +-------------------- + +**Device not recognized by host** + +The most common issue - host doesn't see your USB device. + +*Diagnosis steps*: +1. Check USB cable (must support data, not just power) +2. Enable logging: build with ``LOG=2`` +3. Use different USB ports/hosts +4. Check device manager (Windows) or ``dmesg`` (Linux) + +*Common causes and solutions*: + +- **Invalid descriptors**: Review ``usb_descriptors.c`` carefully +- **``tud_task()`` not called**: Ensure regular calls in main loop (< 1ms interval) +- **Wrong USB configuration**: Check ``tusb_config.h`` settings +- **Hardware issues**: Verify USB pins, crystal/clock configuration + +**Enumeration starts but fails** + +Device is detected but configuration fails. + +*Diagnosis*: +.. code-block:: bash + + # Build with logging enabled + make BOARD=your_board LOG=2 all + +*Look for*: +- Setup request handling errors +- Endpoint configuration problems +- String descriptor issues + +*Solutions*: +- Implement all required descriptors +- Check endpoint sizes match descriptors +- Ensure control endpoint (EP0) handling is correct + +**Data transfer issues** + +Device enumerates but data doesn't transfer correctly. + +*Common causes*: +- Buffer overruns in class callbacks +- Incorrect endpoint usage (IN vs OUT) +- Flow control issues in CDC class + +*Solutions*: +- Check buffer sizes in callbacks +- Verify endpoint directions in descriptors +- Implement proper flow control + +Host Mode Problems +------------------ + +**No devices detected** + +Host application doesn't see connected devices. + +*Hardware checks*: +- Power supply adequate for host mode +- USB-A connector for host (not micro-USB) +- Board supports host mode on selected port + +*Software checks*: +- ``tuh_task()`` called regularly +- Host stack enabled in ``tusb_config.h`` +- Correct root hub port configuration + +**Device enumeration fails** + +Devices connect but enumeration fails. + +*Diagnosis*: +.. code-block:: bash + + # Enable host logging + make BOARD=your_board LOG=2 RHPORT_HOST=1 all + +*Common issues*: +- Power supply insufficient during enumeration +- Timing issues with slow devices +- USB hub compatibility problems + +**Class driver issues** + +Device enumerates but class-specific communication fails. + +*Troubleshooting*: +- Check device descriptors match expected class +- Verify interface/endpoint assignments +- Some devices need device-specific handling + +Performance Issues +================== + +Slow Transfer Speeds +-------------------- + +**Symptoms**: Lower than expected USB transfer rates + +*Causes and solutions*: +- **Task scheduling**: Call ``tud_task()``/``tuh_task()`` more frequently +- **Endpoint buffer sizes**: Increase buffer sizes for bulk transfers +- **DMA usage**: Enable DMA for USB transfers if supported +- **USB speed**: Use High Speed (480 Mbps) instead of Full Speed (12 Mbps) + +High CPU Usage +-------------- + +**Symptoms**: MCU spending too much time in USB handling + +*Solutions*: +- Use efficient logging (RTT/SWO instead of UART) +- Reduce log level in production builds +- Optimize descriptor parsing +- Use DMA for data transfers + +Memory Issues +============= + +Stack Overflow +-------------- + +**Symptoms**: Hard faults, random crashes, especially during enumeration + +*Diagnosis*: +- Build with ``DEBUG=1`` and use debugger +- Check stack pointer before/after USB operations +- Monitor stack usage with RTOS tools + +*Solutions*: +- Increase stack size in linker script +- Reduce local variable usage in callbacks +- Use static buffers instead of large stack arrays + +Heap Issues +----------- + +**Note**: TinyUSB doesn't use dynamic allocation, but your application might. + +*Check*: +- Application code using malloc/free +- RTOS heap usage +- Third-party library allocations + +Hardware-Specific Issues +======================== + +STM32 Issues +------------ + +**Clock configuration problems**: +- USB requires precise 48MHz clock +- HSE crystal must be configured correctly +- PLL settings affect USB timing + +**Pin configuration**: +- USB pins need specific alternate function settings +- VBUS sensing configuration +- ID pin for OTG applications + +RP2040 Issues +------------- + +**PIO-USB for host mode**: +- Requires specific pin assignments +- CPU overclocking may be needed for reliable operation +- Timing-sensitive - avoid long interrupt disable periods + +**Flash/RAM constraints**: +- Large USB applications may exceed RP2040 limits +- Use code optimization and remove unused features + +ESP32 Issues +------------ + +**USB peripheral differences**: +- ESP32-S2/S3 have different USB capabilities +- Some variants only support device mode +- DMA configuration varies between models + +Advanced Debugging +================== + +Using USB Analyzers +------------------- + +For complex issues, hardware USB analyzers provide detailed protocol traces: + +- **Wireshark** with USBPcap (Windows) or usbmon (Linux) +- **Hardware analyzers**: Total Phase Beagle, LeCroy USB analyzers +- **Logic analyzers**: For timing analysis of USB signals + +Debugging with GDB +------------------ + +.. code-block:: bash + + # Build with debug info + make BOARD=your_board DEBUG=1 all + + # Use with debugger + arm-none-eabi-gdb build/your_app.elf + +*Useful breakpoints*: +- ``dcd_int_handler()`` - USB interrupt entry +- ``tud_task()`` - Main device task +- Class-specific callbacks + +Custom Logging +-------------- + +For production debugging, implement custom logging: + +.. code-block:: c + + // In tusb_config.h + #define CFG_TUSB_DEBUG_PRINTF my_printf + + // Your implementation + void my_printf(const char* format, ...) { + // Send to RTT, SWO, or custom interface + } + +Getting Help +============ + +When reporting issues: + +1. **Minimal reproducible example**: Simplify to bare minimum +2. **Build information**: Board, toolchain version, build flags +3. **Logs**: Include output with ``LOG=2`` enabled +4. **Hardware details**: Board revision, USB connections, power supply +5. **Host environment**: OS version, USB port type + +**Resources**: +- GitHub Discussions: https://github.com/hathach/tinyusb/discussions +- Issue Tracker: https://github.com/hathach/tinyusb/issues +- Documentation: https://docs.tinyusb.org \ No newline at end of file diff --git a/docs/tutorials/first_device.rst b/docs/tutorials/first_device.rst new file mode 100644 index 000000000..9fac2df49 --- /dev/null +++ b/docs/tutorials/first_device.rst @@ -0,0 +1,147 @@ +********************* +Your First USB Device +********************* + +This tutorial walks you through creating a simple USB CDC (serial) device using TinyUSB. By the end, you'll have a working USB device that appears as a serial port on your computer. + +Prerequisites +============= + +* Completed :doc:`getting_started` tutorial +* Development board with USB device capability (e.g., STM32F4 Discovery, Raspberry Pi Pico) +* Basic understanding of C programming + +Understanding USB Device Basics +=============================== + +A USB device needs three key components: + +1. **USB Descriptors**: Tell the host what kind of device this is +2. **Class Implementation**: Handle USB class-specific requests (CDC, HID, etc.) +3. **Application Logic**: Your main application code + +Step 1: Choose Your Starting Point +================================== + +We'll start with the ``cdc_msc`` example as it's the most commonly used and well-tested. + +.. code-block:: bash + + cd examples/device/cdc_msc + +This example implements both CDC (virtual serial port) and MSC (mass storage) classes. + +Step 2: Understand the Code Structure +===================================== + +Key files in the example: + +* ``main.c`` - Main application loop and board initialization +* ``usb_descriptors.c`` - USB device descriptors +* ``tusb_config.h`` - TinyUSB stack configuration + +**Main Loop Pattern**: + +.. code-block:: c + + int main(void) { + board_init(); + tusb_init(); + + while (1) { + tud_task(); // TinyUSB device task + cdc_task(); // Application-specific CDC handling + } + } + +**Device Task**: ``tud_task()`` must be called regularly to handle USB events and maintain the connection. + +Step 3: Build and Test +====================== + +.. code-block:: bash + + # Fetch dependencies for your board family + python ../../../tools/get_deps.py stm32f4 # Replace with your family + + # Build for your board + make BOARD=stm32f407disco all + + # Flash to device + make BOARD=stm32f407disco flash + +**Expected Result**: After flashing, connect the USB port to your computer. You should see: + +* A new serial port device (e.g., ``/dev/ttyACM0`` on Linux, ``COMx`` on Windows) +* A small mass storage device + +Step 4: Customize for Your Needs +================================= + +**Simplify to CDC-only**: + +1. In ``tusb_config.h``, disable MSC: + +.. code-block:: c + + #define CFG_TUD_MSC 0 // Disable Mass Storage + +2. Remove MSC-related code from ``main.c`` and ``usb_descriptors.c`` + +**Modify Device Information**: + +In ``usb_descriptors.c``: + +.. code-block:: c + + tusb_desc_device_t const desc_device = { + .idVendor = 0xCafe, // Your vendor ID + .idProduct = 0x4000, // Your product ID + .bcdDevice = 0x0100, // Device version + // ... other fields + }; + +**Add Application Logic**: + +In the CDC task function, add your serial communication logic: + +.. code-block:: c + + void cdc_task(void) { + if (tud_cdc_available()) { + uint8_t buf[64]; + uint32_t count = tud_cdc_read(buf, sizeof(buf)); + + // Echo back what was received + tud_cdc_write(buf, count); + tud_cdc_write_flush(); + } + } + +Common Issues and Solutions +=========================== + +**Device Not Recognized**: + +* Check USB cable (must support data, not just power) +* Verify descriptors are valid using ``LOG=2`` build option +* Ensure ``tud_task()`` is called regularly in main loop + +**Build Errors**: + +* Missing dependencies: Run ``python tools/get_deps.py FAMILY`` +* Wrong board name: Check ``hw/bsp/FAMILY/boards/`` for valid names +* Compiler issues: Install ``gcc-arm-none-eabi`` + +**Runtime Issues**: + +* Hard faults: Check stack size in linker script +* USB not working: Verify clock configuration and USB pin setup +* Serial data corruption: Ensure proper flow control in CDC implementation + +Next Steps +========== + +* Learn about other device classes in :doc:`../reference/usb_classes` +* Understand advanced integration in :doc:`../guides/integration` +* Explore TinyUSB architecture in :doc:`../explanation/architecture` \ No newline at end of file diff --git a/docs/tutorials/first_host.rst b/docs/tutorials/first_host.rst new file mode 100644 index 000000000..5b406ad34 --- /dev/null +++ b/docs/tutorials/first_host.rst @@ -0,0 +1,160 @@ +****************** +Your First USB Host +****************** + +This tutorial guides you through creating a simple USB host application that can connect to and communicate with USB devices. + +Prerequisites +============= + +* Completed :doc:`getting_started` and :doc:`first_device` tutorials +* Development board with USB host capability (e.g., STM32F4 Discovery with USB-A connector) +* USB device to test with (USB drive, mouse, keyboard, or CDC device) + +Understanding USB Host Basics +============================= + +A USB host application needs: + +1. **Device Enumeration**: Detect and configure connected devices +2. **Class Drivers**: Handle communication with specific device types +3. **Application Logic**: Process data from/to the connected devices + +Step 1: Start with an Example +============================= + +Use the ``cdc_msc_hid`` host example: + +.. code-block:: bash + + cd examples/host/cdc_msc_hid + +This example can communicate with CDC (serial), MSC (storage), and HID (keyboard/mouse) devices. + +Step 2: Understand the Code Structure +===================================== + +Key components: + +* ``main.c`` - Main loop and device event handling +* Host callbacks - Functions called when devices connect/disconnect +* Class-specific handlers - Process data from different device types + +**Main Loop Pattern**: + +.. code-block:: c + + int main(void) { + board_init(); + tusb_init(); + + while (1) { + tuh_task(); // TinyUSB host task + // Handle connected devices + } + } + +**Connection Events**: TinyUSB calls your callbacks when devices connect: + +.. code-block:: c + + void tuh_mount_cb(uint8_t dev_addr) { + printf("Device connected, address = %d\\n", dev_addr); + } + + void tuh_umount_cb(uint8_t dev_addr) { + printf("Device disconnected, address = %d\\n", dev_addr); + } + +Step 3: Build and Test +====================== + +.. code-block:: bash + + # Fetch dependencies + python ../../../tools/get_deps.py stm32f4 + + # Build + make BOARD=stm32f407disco all + + # Flash + make BOARD=stm32f407disco flash + +**Testing**: Connect different USB devices and observe the output via serial console. + +Step 4: Handle Specific Device Types +==================================== + +**Mass Storage (USB Drive)**: + +.. code-block:: c + + void tuh_msc_mount_cb(uint8_t dev_addr) { + printf("USB Drive mounted\\n"); + // Read/write files + } + +**HID Devices (Keyboard/Mouse)**: + +.. code-block:: c + + void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, + uint8_t const* desc_report, uint16_t desc_len) { + uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); + if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { + printf("Keyboard connected\\n"); + } + } + +**CDC Devices (Serial)**: + +.. code-block:: c + + void tuh_cdc_mount_cb(uint8_t idx) { + printf("CDC device mounted\\n"); + // Configure serial settings + tuh_cdc_set_baudrate(idx, 115200, NULL, 0); + } + +Common Issues and Solutions +=========================== + +**No Device Detection**: + +* Check power supply - host mode requires more power than device mode +* Verify USB connector wiring and type (USB-A for host vs USB micro/C for device) +* Enable logging with ``LOG=2`` to see enumeration process + +**Enumeration Failures**: + +* Some devices need more time - increase timeouts +* Check USB hub support if using a hub +* Verify device is USB 2.0 compatible (USB 3.0 devices should work in USB 2.0 mode) + +**Class Driver Issues**: + +* Not all devices follow standards perfectly - may need custom handling +* Check device descriptors with USB analyzer tools +* Some composite devices may not be fully supported + +Hardware Considerations +======================= + +**Power Requirements**: + +* Host mode typically requires external power or powered USB hub +* Check board documentation for power limitations +* Some boards need jumper changes to enable host power + +**Pin Configuration**: + +* Host and device modes often use different USB connectors/pins +* Verify board supports host mode on your chosen port +* Check if OTG (On-The-Go) configuration is needed + +Next Steps +========== + +* Learn about supported USB classes in :doc:`../reference/usb_classes` +* Understand advanced integration in :doc:`../guides/integration` +* Explore TinyUSB architecture in :doc:`../explanation/architecture` \ No newline at end of file diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst new file mode 100644 index 000000000..7853a9cc0 --- /dev/null +++ b/docs/tutorials/getting_started.rst @@ -0,0 +1,293 @@ +*************** +Getting Started +*************** + +This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example. + +Add TinyUSB to your project +--------------------------- + +To incorporate TinyUSB into your project: + +* Copy or ``git submodule`` this repository into your project in a subfolder. Let's say it is ``your_project/tinyusb`` +* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project +* Add ``your_project/tinyusb/src`` to your include path. Also make sure your current include path contains the configuration file ``tusb_config.h``. +* Make sure all required macros are defined properly in ``tusb_config.h`` (the configuration file in demo applications is sufficient, but you need to add a few more such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS`` since they are passed by make/cmake to maintain a unique configuration for all boards). +* If you use the device stack, make sure you have created/modified USB descriptors for your own needs. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. +* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. +* Call ``tusb_int_handler(rhport, in_isr)`` in your USB IRQ handler +* Implement all enabled classes' callbacks. +* If you don't use any RTOS at all, you need to continuously and/or periodically call the ``tud_task()``/``tuh_task()`` functions. All of the callbacks and functionality are handled and invoked within the call of that task runner. + +.. code-block:: c + + int main(void) { + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_AUTO + }; + tusb_init(0, &dev_init); // initialize device stack on roothub port 0 + + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_HOST, + .speed = TUSB_SPEED_AUTO + }; + tusb_init(1, &host_init); // initialize host stack on roothub port 1 + + while(1) { // the mainloop + your_application_code(); + tud_task(); // device task + tuh_task(); // host task + } + } + + void USB0_IRQHandler(void) { + tusb_int_handler(0, true); + } + + void USB1_IRQHandler(void) { + tusb_int_handler(1, true); + } + +Examples +-------- + +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already + +.. code-block:: bash + + $ git clone https://github.com/hathach/tinyusb tinyusb + $ cd tinyusb + +Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for TinyUSB, you should download/install them first according to the manufacturer's guide. + +Dependencies +^^^^^^^^^^^^ + +The hardware code is located in the ``hw/bsp`` folder, and is organized by family/boards. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. Before building, we first need to download dependencies such as: MCU low-level peripheral drivers and external libraries like FreeRTOS (required by some examples). We can do this in either of two ways: + +1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a family as follows. Note: For TinyUSB developers to download all dependencies, use FAMILY=all. + +.. code-block:: bash + + $ python tools/get_deps.py rp2040 + +2. Or run the ``get-deps`` target in one of the example folders as follows. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=feather_nrf52840_express get-deps + +You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` + +Build Examples +^^^^^^^^^^^^^^ + +Examples support make and cmake build systems for most MCUs, however some MCU families such as Espressif or RP2040 only support cmake. First change directory to an example folder. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + +Then compile with make or cmake + +.. code-block:: bash + + $ # make + $ make BOARD=feather_nrf52840_express all + + $ # cmake + $ mkdir build && cd build + $ cmake -DBOARD=raspberry_pi_pico .. + $ make + +To list all available targets with cmake + +.. code-block:: bash + + $ cmake --build . --target help + +Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``99-tinyusb.rules`` and reload your udev is good to go + +.. code-block:: bash + + $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ + $ sudo udevadm control --reload-rules && sudo udevadm trigger + +RootHub Port Selection +~~~~~~~~~~~~~~~~~~~~~~ + +If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. + +Port Speed +~~~~~~~~~~ + +A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force F723 operate at full instead of default high speed + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. + +Size Analysis +~~~~~~~~~~~~~ + +First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap + +Debug +^^^^^ + +To compile for debugging add ``DEBUG=1``\ , for example + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express DEBUG=1 all + + $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. + +Log +~~~ + +Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional ``LOG=``. ``LOG=1`` will only print out error message, ``LOG=2`` print more information with on-going events. ``LOG=3`` or higher is not used yet. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. + +Logger +~~~~~~ + +By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols: + + +* `LOGGER=rtt`: use `Segger RTT protocol `_ + + * Cons: requires jlink as the debugger. + * Pros: work with most if not all MCUs + * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. + +* ``LOGGER=swo`` : Use dedicated SWO pin of ARM Cortex SWD debug header. + + * Cons: only work with ARM Cortex MCUs minus M0 + * Pros: should be compatible with more debugger that support SWO. + * Software viewer should be provided along with your debugger driver. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. + +Flash +^^^^^ + +``flash`` target will use the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary, please install those support software in advance. Some board use bootloader/DFU via serial which is required to pass to make command + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash + $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash + +Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash-jlink + $ make BOARD=feather_nrf52840_express flash-openocd + + $ cmake --build . --target cdc_msc-jlink + $ cmake --build . --target cdc_msc-openocd + +Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can be generated with ``uf2`` target + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express all uf2 + + $ cmake --build . --target cdc_msc-uf2 + +IAR Support +^^^^^^^^^^^ + +Use project connection +~~~~~~~~~~~~~~~~~~~~~~ + +IAR Project Connection files are provided to import TinyUSB stack into your project. + +* A buildable project of your MCU need to be created in advance. + + * Take example of STM32F0: + + - You need ``stm32l0xx.h``, ``startup_stm32f0xx.s``, ``system_stm32f0xx.c``. + + - ``STM32L0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. + +* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) + Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, + for example ``C:\\tinyusb`` + +**Import stack only** + +Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. + +**Run examples** + +1. Run ``iar_gen.py`` to generate .ipcf files of examples: + + .. code-block:: + + > cd C:\tinyusb\tools + > python iar_gen.py + +2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. + For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` + +Native CMake support +~~~~~~~~~~~~~~~~~~~~ + +With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. + +Following these steps: + +1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. +2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. +3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. +4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. + +Common Issues and Solutions +--------------------------- + +**Build Errors** + +* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` +* **"Board 'X' not found"**: Check available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` +* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board + +**Runtime Issues** + +* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings +* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors +* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation + +Next Steps +---------- + +* Try the :doc:`first_device` tutorial to implement a simple USB device +* Read about :doc:`../guides/integration` for production projects +* Check :doc:`../reference/boards` for board-specific information diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst new file mode 100644 index 000000000..6cf8f6ded --- /dev/null +++ b/docs/tutorials/index.rst @@ -0,0 +1,12 @@ +********* +Tutorials +********* + +Step-by-step learning guides for TinyUSB development. + +.. toctree:: + :maxdepth: 2 + + getting_started + first_device + first_host \ No newline at end of file -- cgit v1.3.1 From e7b851d9ac2657e591f772dd3fa326e2d8d00270 Mon Sep 17 00:00:00 2001 From: c1570 Date: Thu, 25 Sep 2025 00:20:45 +0200 Subject: Naming conventions, buffer handling --- docs/explanation/usb_concepts.rst | 94 ++++++++++++++++++++++++++++++++++++-- docs/reference/configuration.rst | 5 ++ docs/reference/glossary.rst | 10 +++- docs/tutorials/getting_started.rst | 3 ++ 4 files changed, 107 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst index 02ba76770..e276b4c96 100644 --- a/docs/explanation/usb_concepts.rst +++ b/docs/explanation/usb_concepts.rst @@ -4,6 +4,18 @@ USB Concepts This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. +TinyUSB API Naming Conventions +=============================== + +TinyUSB uses consistent function prefixes to organize its API: + +* **tusb_**: Core stack functions (initialization, interrupt handling) +* **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) +* **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) +* **tu_**: Internal utility functions (generally not used by applications) + +This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. + USB Protocol Basics ==================== @@ -252,10 +264,10 @@ USB supports multiple speed modes: **TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. -USB Device Controllers -====================== +USB Controller Abstraction +=========================== -USB device controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. +USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. Controller Fundamentals ----------------------- @@ -316,6 +328,42 @@ These internal details don't matter to users of TinyUSB typically; however, when - ``dcd_int_handler()`` - Process USB interrupts - ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection +Host Controller Driver (HCD) +----------------------------- + +TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. + +**Portable Interface** (``src/host/usbh.h``): +- Standardized interface for all host controllers +- Common device enumeration and pipe management +- Unified transfer scheduling and completion handling + +**Common HCD Functions**: +- ``hcd_init()`` - Initialize host controller hardware +- ``hcd_port_connect_status()`` - Check device connection status +- ``hcd_port_reset()`` - Reset connected device +- ``hcd_edpt_open()`` - Open communication pipe to device endpoint +- ``hcd_edpt_xfer()`` - Transfer data to/from connected device + +**Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. + +TinyUSB Event System & Thread Safety +==================================== + +Deferred Interrupt Processing +----------------------------- + +**Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. + +**Event Flow**: + +1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) +2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue +3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events +4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks + +**Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. + Controller Event Flow --------------------- @@ -329,6 +377,46 @@ Controller Event Flow 6. **Class Notification**: Appropriate class drivers handle the event 7. **Application Callback**: User code responds to the event +USB Class Driver Architecture +============================== + +TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. + +Class Driver Pattern +--------------------- + +**Standardized Entry Points**: Each class driver implements these core functions: + +- ``*_init()`` - Initialize class driver state and buffers +- ``*_reset()`` - Reset to initial state on USB bus reset +- ``*_open()`` - Parse and configure interfaces during enumeration +- ``*_control_xfer_cb()`` - Handle class-specific control requests +- ``*_xfer_cb()`` - Handle transfer completion callbacks + +**Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: + +.. code-block:: c + + // Single instance (default instance 0) + tud_cdc_write(data, len); + + // Multiple instances + tud_cdc_n_write(0, data, len); // Instance 0 + tud_cdc_n_write(1, data, len); // Instance 1 + +**Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. + +Class Driver Types +------------------- + +TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. + +Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. + +The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. + +**Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. + Power Management ================ diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst index 8d6dd6190..79aeb15d8 100644 --- a/docs/reference/configuration.rst +++ b/docs/reference/configuration.rst @@ -106,6 +106,11 @@ Device Classes #define CFG_TUD_VENDOR 1 // Number of vendor interfaces #define CFG_TUD_VENDOR_EPSIZE 64 // Vendor endpoint size + #define CFG_TUD_VENDOR_RX_BUFSIZE 64 // RX buffer size (0 = no buffering) + #define CFG_TUD_VENDOR_TX_BUFSIZE 64 // TX buffer size (0 = no buffering) + +.. note:: + Unlike other classes, vendor class supports setting buffer sizes to 0 to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. Host Stack Configuration ======================== diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index e6e92738f..56ee49619 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -14,7 +14,7 @@ Glossary USB transfer type used for device configuration and control. All USB devices must support control transfers on endpoint 0. DCD - Device Controller Driver. The hardware abstraction layer for USB device controllers in TinyUSB. + Device Controller Driver. The hardware abstraction layer for USB device controllers in TinyUSB. See also HCD. Descriptor Data structures that describe USB device capabilities, configuration, and interfaces to the host. @@ -32,7 +32,7 @@ Glossary Process where USB host discovers and configures a newly connected device. HCD - Host Controller Driver. The hardware abstraction layer for USB host controllers in TinyUSB. + Host Controller Driver. The hardware abstraction layer for USB host controllers in TinyUSB. See also DCD. HID Human Interface Device. USB class for input devices like keyboards, mice, and game controllers. @@ -73,6 +73,12 @@ Glossary Super Speed USB 3.0 speed mode operating at 5 Gbps. Not supported by TinyUSB. + tud + TinyUSB Device. Function prefix for all device stack APIs (e.g., ``tud_task()``, ``tud_cdc_write()``). + + tuh + TinyUSB Host. Function prefix for all host stack APIs (e.g., ``tuh_task()``, ``tuh_cdc_receive()``). + UAC USB Audio Class. USB class for audio devices. diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst index 7853a9cc0..432b0b682 100644 --- a/docs/tutorials/getting_started.rst +++ b/docs/tutorials/getting_started.rst @@ -19,6 +19,9 @@ To incorporate TinyUSB into your project: * Implement all enabled classes' callbacks. * If you don't use any RTOS at all, you need to continuously and/or periodically call the ``tud_task()``/``tuh_task()`` functions. All of the callbacks and functionality are handled and invoked within the call of that task runner. +.. note:: + TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. + .. code-block:: c int main(void) { -- cgit v1.3.1 From 75f2a8451e6ab622f8974b77b76b16ac2d057349 Mon Sep 17 00:00:00 2001 From: c1570 Date: Thu, 25 Sep 2025 01:01:01 +0200 Subject: improve flow --- docs/explanation/architecture.rst | 25 ++++++++--------------- docs/explanation/usb_concepts.rst | 23 ++++----------------- docs/reference/configuration.rst | 14 +++++++++---- docs/reference/usb_classes.rst | 5 +---- docs/troubleshooting.rst | 43 +++++---------------------------------- docs/tutorials/first_device.rst | 8 ++++++-- 6 files changed, 34 insertions(+), 84 deletions(-) (limited to 'docs') diff --git a/docs/explanation/architecture.rst b/docs/explanation/architecture.rst index 4c63b198d..aa0c76128 100644 --- a/docs/explanation/architecture.rst +++ b/docs/explanation/architecture.rst @@ -12,10 +12,7 @@ Memory Safety TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: -- **No dynamic allocation**: All memory is statically allocated at compile time -- **Bounded buffers**: All buffers have compile-time defined sizes -- **Stack-based design**: No heap usage in the core stack -- **Predictable memory usage**: Memory consumption is deterministic +TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. Thread Safety ------------- @@ -54,7 +51,7 @@ TinyUSB follows a layered architecture from hardware to application: ├─────────────────────────────────────────┤ │ Device/Host Stack Core │ ← USB protocol handling ├─────────────────────────────────────────┤ - │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers + │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers ├─────────────────────────────────────────┤ │ OS Abstraction (OSAL) │ ← RTOS integration ├─────────────────────────────────────────┤ @@ -79,6 +76,8 @@ Component Overview Device Stack Architecture ========================= +This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). + Core Components --------------- @@ -138,6 +137,8 @@ TinyUSB uses a deferred interrupt model for thread safety: Host Stack Architecture ======================= +This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. + Core Components --------------- @@ -223,12 +224,7 @@ Memory Management Static Allocation Model ----------------------- -TinyUSB uses only static memory allocation: - -- **Endpoint Buffers**: Fixed-size buffers for each endpoint -- **Class Buffers**: Static buffers for class-specific data -- **Control Buffers**: Fixed buffer for control transfers -- **Queue Buffers**: Static event queues +TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. Buffer Management ----------------- @@ -254,12 +250,7 @@ Threading Model Task-Based Design ----------------- -TinyUSB uses a cooperative task model: - -- **Main Tasks**: ``tud_task()`` for device, ``tuh_task()`` for host -- **Regular Execution**: Tasks must be called regularly (< 1ms typical) -- **Event Processing**: All USB events processed in task context -- **Callback Execution**: Application callbacks run in task context +TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. RTOS Integration ---------------- diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst index e276b4c96..8b315aea2 100644 --- a/docs/explanation/usb_concepts.rst +++ b/docs/explanation/usb_concepts.rst @@ -134,27 +134,16 @@ Endpoint Basics Endpoint Configuration ---------------------- -Each endpoint is configured with: -- **Transfer type**: Control, bulk, interrupt, or isochronous -- **Direction**: IN, OUT, or bidirectional (control only) -- **Maximum packet size**: Depends on USB speed and transfer type -- **Interval**: For interrupt and isochronous endpoints +Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. **TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. Error Handling and Flow Control ------------------------------- -**Transfer Results**: USB transfers can complete with different results: -- **ACK**: Successful transfer -- **NAK**: Device not ready (used for flow control) -- **STALL**: Error condition or unsupported request -- **Timeout**: Transfer failed to complete in time +**Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. -**Flow Control in USB**: Unlike network protocols, USB doesn't use congestion control. Instead: -- Devices use NAK responses when not ready to receive data -- Applications implement buffering and proper timing -- Some classes (like CDC) support hardware flow control (RTS/CTS) +**Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. **TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. @@ -278,11 +267,7 @@ Controller Fundamentals - Generate interrupts for USB events - Implement USB electrical specifications -**Key Components**: -- **Physical Layer**: USB signal drivers and receivers -- **Protocol Engine**: Handles USB packets, ACK/NAK responses -- **Endpoint Buffers**: Hardware FIFOs or RAM for data storage -- **Interrupt Controller**: Generates events for software processing +**Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. Controller Architecture Types ----------------------------- diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst index 79aeb15d8..fa0a874f5 100644 --- a/docs/reference/configuration.rst +++ b/docs/reference/configuration.rst @@ -173,15 +173,21 @@ Memory Management RTOS Configuration ------------------ -**FreeRTOS**: +TinyUSB supports multiple operating systems through its OSAL (Operating System Abstraction Layer). Choose the appropriate configuration based on your target environment. + +**FreeRTOS Integration**: + +When using FreeRTOS, configure the task queue sizes to handle USB events efficiently: .. code-block:: c #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUD_TASK_QUEUE_SZ 16 - #define CFG_TUH_TASK_QUEUE_SZ 16 + #define CFG_TUD_TASK_QUEUE_SZ 16 // Device task queue size + #define CFG_TUH_TASK_QUEUE_SZ 16 // Host task queue size + +**RT-Thread Integration**: -**RT-Thread**: +RT-Thread requires only the OS selection, as it uses the RTOS's built-in primitives: .. code-block:: c diff --git a/docs/reference/usb_classes.rst b/docs/reference/usb_classes.rst index 00a251ffb..387587b48 100644 --- a/docs/reference/usb_classes.rst +++ b/docs/reference/usb_classes.rst @@ -268,10 +268,7 @@ Most classes require callback functions: Performance Considerations -------------------------- -- **Buffer Sizes**: Match endpoint buffer sizes to expected data rates -- **Transfer Types**: Use appropriate USB transfer types (bulk, interrupt, isochronous) -- **CPU Usage**: Minimize processing in interrupt context -- **Memory Usage**: Static allocation only, no dynamic memory +When implementing USB classes, match **buffer sizes** to expected data rates to avoid bottlenecks. Choose appropriate **transfer types** based on your application's requirements. Keep **callback processing** lightweight for optimal performance. Avoid **memory allocations in critical paths** where possible to maintain consistent performance. Testing and Validation ---------------------- diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 1f0f388df..e30210d01 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -177,11 +177,7 @@ Slow Transfer Speeds **Symptoms**: Lower than expected USB transfer rates -*Causes and solutions*: -- **Task scheduling**: Call ``tud_task()``/``tuh_task()`` more frequently -- **Endpoint buffer sizes**: Increase buffer sizes for bulk transfers -- **DMA usage**: Enable DMA for USB transfers if supported -- **USB speed**: Use High Speed (480 Mbps) instead of Full Speed (12 Mbps) +*Causes and solutions*: Improve **task scheduling** by calling ``tud_task()``/``tuh_task()`` more frequently to ensure timely USB event processing. Consider increasing **endpoint buffer sizes** for bulk transfers to reduce the frequency of small transfers. Enable **DMA usage** for USB transfers if your hardware supports it to offload CPU processing. Finally, use **High Speed** (480 Mbps) instead of Full Speed (12 Mbps) when possible to achieve better throughput. High CPU Usage -------------- @@ -194,34 +190,6 @@ High CPU Usage - Optimize descriptor parsing - Use DMA for data transfers -Memory Issues -============= - -Stack Overflow --------------- - -**Symptoms**: Hard faults, random crashes, especially during enumeration - -*Diagnosis*: -- Build with ``DEBUG=1`` and use debugger -- Check stack pointer before/after USB operations -- Monitor stack usage with RTOS tools - -*Solutions*: -- Increase stack size in linker script -- Reduce local variable usage in callbacks -- Use static buffers instead of large stack arrays - -Heap Issues ------------ - -**Note**: TinyUSB doesn't use dynamic allocation, but your application might. - -*Check*: -- Application code using malloc/free -- RTOS heap usage -- Third-party library allocations - Hardware-Specific Issues ======================== @@ -246,10 +214,6 @@ RP2040 Issues - CPU overclocking may be needed for reliable operation - Timing-sensitive - avoid long interrupt disable periods -**Flash/RAM constraints**: -- Large USB applications may exceed RP2040 limits -- Use code optimization and remove unused features - ESP32 Issues ------------ @@ -273,6 +237,9 @@ For complex issues, hardware USB analyzers provide detailed protocol traces: Debugging with GDB ------------------ +Debugging with traditional debuggers is limited due to the real time nature of USB. +However, especially for diagnosis of crashes, it can still be useful. + .. code-block:: bash # Build with debug info @@ -315,4 +282,4 @@ When reporting issues: **Resources**: - GitHub Discussions: https://github.com/hathach/tinyusb/discussions - Issue Tracker: https://github.com/hathach/tinyusb/issues -- Documentation: https://docs.tinyusb.org \ No newline at end of file +- Documentation: https://docs.tinyusb.org diff --git a/docs/tutorials/first_device.rst b/docs/tutorials/first_device.rst index 9fac2df49..1b9ed5b0a 100644 --- a/docs/tutorials/first_device.rst +++ b/docs/tutorials/first_device.rst @@ -40,7 +40,7 @@ Key files in the example: * ``usb_descriptors.c`` - USB device descriptors * ``tusb_config.h`` - TinyUSB stack configuration -**Main Loop Pattern**: +The main loop follows a simple pattern that combines board initialization, TinyUSB initialization, and continuous task processing: .. code-block:: c @@ -54,11 +54,13 @@ Key files in the example: } } -**Device Task**: ``tud_task()`` must be called regularly to handle USB events and maintain the connection. +The ``tud_task()`` function must be called regularly to handle USB events and maintain the connection with the host. This function processes all queued USB events and triggers appropriate callbacks in your application code. Step 3: Build and Test ====================== +With a clear understanding of the code structure, you're ready to build and test the example. This process involves fetching dependencies, compiling for your target board, and flashing the firmware: + .. code-block:: bash # Fetch dependencies for your board family @@ -78,6 +80,8 @@ Step 3: Build and Test Step 4: Customize for Your Needs ================================= +Once you have the basic example working, you can customize it for your specific application. The following modifications demonstrate common customization patterns. + **Simplify to CDC-only**: 1. In ``tusb_config.h``, disable MSC: -- cgit v1.3.1 From a332acf5ead28089c732428a4254354baec9afd6 Mon Sep 17 00:00:00 2001 From: c1570 Date: Thu, 25 Sep 2025 01:18:56 +0200 Subject: rearrage TOC --- docs/index.rst | 26 ++++++++------------------ 1 file changed, 8 insertions(+), 18 deletions(-) (limited to 'docs') diff --git a/docs/index.rst b/docs/index.rst index 9fbc5bd30..3a70f2471 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -29,30 +29,15 @@ Documentation Structure .. toctree:: :maxdepth: 2 - :caption: Learning + :caption: Information + explanation/index tutorials/index - -.. toctree:: - :maxdepth: 2 - :caption: Problem Solving - guides/index + reference/index faq troubleshooting -.. toctree:: - :maxdepth: 2 - :caption: Information - - reference/index - -.. toctree:: - :maxdepth: 2 - :caption: Understanding - - explanation/index - .. toctree:: :maxdepth: 1 :caption: Project Info @@ -67,3 +52,8 @@ Documentation Structure Source Code Issue Tracker Discussions + +GitHub Project Main README +========================== + +.. include:: ../README_processed.rst -- cgit v1.3.1 From 39e2e5167c3b59176293023eaf0249a5b3955f0c Mon Sep 17 00:00:00 2001 From: c1570 Date: Fri, 26 Sep 2025 18:34:10 +0200 Subject: improved getting_started, integrated "first device/host" --- docs/explanation/usb_concepts.rst | 6 +- docs/faq.rst | 2 +- docs/guides/index.rst | 10 - docs/guides/integration.rst | 494 ------------------------------------- docs/reference/glossary.rst | 3 + docs/tutorials/first_device.rst | 151 ------------ docs/tutorials/first_host.rst | 160 ------------ docs/tutorials/getting_started.rst | 176 ++++++++----- docs/tutorials/index.rst | 4 +- 9 files changed, 126 insertions(+), 880 deletions(-) delete mode 100644 docs/guides/index.rst delete mode 100644 docs/guides/integration.rst delete mode 100644 docs/tutorials/first_device.rst delete mode 100644 docs/tutorials/first_host.rst (limited to 'docs') diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst index 8b315aea2..e3d400921 100644 --- a/docs/explanation/usb_concepts.rst +++ b/docs/explanation/usb_concepts.rst @@ -30,7 +30,7 @@ Host and Device Roles - Manages the USB bus - Enumerates and configures devices -**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See :doc:`../tutorials/first_host` for implementation details. +**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. **USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: - Respond to host requests @@ -38,7 +38,7 @@ Host and Device Roles - Receive power from the host - Must be enumerated by the host before use -**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See :doc:`../tutorials/first_device` for implementation details. +**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. **OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. @@ -422,4 +422,4 @@ Next Steps - Start with :doc:`../tutorials/getting_started` for basic setup - Review :doc:`../reference/configuration` for configuration options -- Check :doc:`../guides/integration` for advanced integration scenarios +- Explore :doc:`../examples` for advanced use cases diff --git a/docs/faq.rst b/docs/faq.rst index ede97032d..505833316 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -38,7 +38,7 @@ Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., s **Q: Can I use my own build system instead of Make/CMake?** -Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`guides/integration` for details. +Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`tutorials/getting_started` for details. **Q: Error: "tusb_config.h: No such file or directory"** diff --git a/docs/guides/index.rst b/docs/guides/index.rst deleted file mode 100644 index cad3dd27f..000000000 --- a/docs/guides/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -********** -How-to Guides -********** - -Problem-solving guides for common TinyUSB development tasks. - -.. toctree:: - :maxdepth: 2 - - integration \ No newline at end of file diff --git a/docs/guides/integration.rst b/docs/guides/integration.rst deleted file mode 100644 index c135c5ec6..000000000 --- a/docs/guides/integration.rst +++ /dev/null @@ -1,494 +0,0 @@ -********************* -Integration Guide -********************* - -This guide covers integrating TinyUSB into production projects with your own build system, custom hardware, and specific requirements. - -Project Integration Methods -============================ - -Method 1: Git Submodule (Recommended) --------------------------------------- - -Best for projects using git version control. - -.. code-block:: bash - - # Add TinyUSB as submodule - git submodule add https://github.com/hathach/tinyusb.git lib/tinyusb - git submodule update --init --recursive - -**Advantages:** -- Pinned to specific TinyUSB version -- Easy to update with ``git submodule update`` -- Version control tracks exact TinyUSB commit - -Method 2: Package Manager Integration -------------------------------------- - -**PlatformIO:** - -.. code-block:: ini - - ; platformio.ini - [env:myboard] - platform = your_platform - board = your_board - framework = arduino ; or other framework - lib_deps = - https://github.com/hathach/tinyusb.git - -**CMake FetchContent:** - -.. code-block:: cmake - - include(FetchContent) - FetchContent_Declare( - tinyusb - GIT_REPOSITORY https://github.com/hathach/tinyusb.git - GIT_TAG master # or specific version tag - ) - FetchContent_MakeAvailable(tinyusb) - -Method 3: Direct Copy ---------------------- - -Copy TinyUSB source files directly into your project. - -.. code-block:: bash - - # Copy only source files - cp -r tinyusb/src/ your_project/lib/tinyusb/ - -**Note:** You'll need to manually update when TinyUSB releases new versions. - -Build System Integration -======================== - -Make/GCC Integration --------------------- - -**Makefile example:** - -.. code-block:: make - - # TinyUSB settings - TUSB_DIR = lib/tinyusb - TUSB_SRC_DIR = $(TUSB_DIR)/src - - # Include paths - CFLAGS += -I$(TUSB_SRC_DIR) - CFLAGS += -I. # For tusb_config.h - - # MCU and OS settings (pass to compiler) - CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_STM32F4 - CFLAGS += -DCFG_TUSB_OS=OPT_OS_NONE - - # TinyUSB source files - SRC_C += $(wildcard $(TUSB_SRC_DIR)/*.c) - SRC_C += $(wildcard $(TUSB_SRC_DIR)/common/*.c) - SRC_C += $(wildcard $(TUSB_SRC_DIR)/device/*.c) - SRC_C += $(wildcard $(TUSB_SRC_DIR)/class/*/*.c) - SRC_C += $(wildcard $(TUSB_SRC_DIR)/portable/$(VENDOR)/$(CHIP_FAMILY)/*.c) - -**Finding the right portable driver:** - -.. code-block:: bash - - # List available drivers - find lib/tinyusb/src/portable -name "*.c" | grep stm32 - # Use: lib/tinyusb/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c - -CMake Integration ------------------ - -**CMakeLists.txt example:** - -.. code-block:: cmake - - # TinyUSB configuration - set(FAMILY_MCUS STM32F4) # Set your MCU family - set(CFG_TUSB_MCU OPT_MCU_STM32F4) - set(CFG_TUSB_OS OPT_OS_FREERTOS) # or OPT_OS_NONE - - # Add TinyUSB - add_subdirectory(lib/tinyusb) - - # Your project - add_executable(your_app - src/main.c - src/usb_descriptors.c - # other sources - ) - - # Link TinyUSB - target_link_libraries(your_app - tinyusb_device # or tinyusb_host - # other libraries - ) - - # Include paths - target_include_directories(your_app PRIVATE - src/ # For tusb_config.h - ) - - # Compile definitions - target_compile_definitions(your_app PRIVATE - CFG_TUSB_MCU=${CFG_TUSB_MCU} - CFG_TUSB_OS=${CFG_TUSB_OS} - ) - -IAR Embedded Workbench ----------------------- - -Use project connection files for easy integration: - -1. Open IAR project -2. Add TinyUSB project connection: ``Tools → Configure Custom Argument Variables`` -3. Create ``TUSB`` group, add ``TUSB_DIR`` variable -4. Import ``tinyusb/tools/iar_template.ipcf`` - -Keil µVision ------------- - -.. code-block:: none - - # Add to project groups: - TinyUSB/Common: src/common/*.c - TinyUSB/Device: src/device/*.c, src/class/*/*.c - TinyUSB/Portable: src/portable/vendor/family/*.c - - # Include paths: - src/ # tusb_config.h location - lib/tinyusb/src/ - - # Preprocessor defines: - CFG_TUSB_MCU=OPT_MCU_STM32F4 - CFG_TUSB_OS=OPT_OS_NONE - -Configuration Setup -=================== - -Create tusb_config.h --------------------- - -This is the most critical file for TinyUSB integration: - -.. code-block:: c - - // tusb_config.h - #ifndef _TUSB_CONFIG_H_ - #define _TUSB_CONFIG_H_ - - // MCU selection - REQUIRED - #ifndef CFG_TUSB_MCU - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #endif - - // OS selection - REQUIRED - #ifndef CFG_TUSB_OS - #define CFG_TUSB_OS OPT_OS_NONE - #endif - - // Debug level - #define CFG_TUSB_DEBUG 0 - - // Device stack - #define CFG_TUD_ENABLED 1 - #define CFG_TUD_ENDPOINT0_SIZE 64 - - // Device classes - #define CFG_TUD_CDC 1 - #define CFG_TUD_HID 0 - #define CFG_TUD_MSC 0 - - // CDC configuration - #define CFG_TUD_CDC_EP_BUFSIZE 512 - #define CFG_TUD_CDC_RX_BUFSIZE 512 - #define CFG_TUD_CDC_TX_BUFSIZE 512 - - #endif - -USB Descriptors ---------------- - -Create or modify ``usb_descriptors.c`` for your device: - -.. code-block:: c - - #include "tusb.h" - - // Device descriptor - tusb_desc_device_t const desc_device = { - .bLength = sizeof(tusb_desc_device_t), - .bDescriptorType = TUSB_DESC_DEVICE, - .bcdUSB = 0x0200, - .bDeviceClass = TUSB_CLASS_MISC, - .bDeviceSubClass = MISC_SUBCLASS_COMMON, - .bDeviceProtocol = MISC_PROTOCOL_IAD, - .bMaxPacketSize0 = CFG_TUD_ENDPOINT0_SIZE, - .idVendor = 0xCafe, // Your VID - .idProduct = 0x4000, // Your PID - .bcdDevice = 0x0100, - .iManufacturer = 0x01, - .iProduct = 0x02, - .iSerialNumber = 0x03, - .bNumConfigurations = 0x01 - }; - - // Get device descriptor - uint8_t const* tud_descriptor_device_cb(void) { - return (uint8_t const*)&desc_device; - } - - // Configuration descriptor - implement based on your needs - uint8_t const* tud_descriptor_configuration_cb(uint8_t index) { - // Return configuration descriptor - } - - // String descriptors - uint16_t const* tud_descriptor_string_cb(uint8_t index, uint16_t langid) { - // Return string descriptors - } - -Application Integration -====================== - -Main Loop Integration --------------------- - -.. code-block:: c - - #include "tusb.h" - - int main(void) { - // Board/MCU initialization - board_init(); // Your board setup - - // USB stack initialization - tusb_init(); - - while (1) { - // USB device task - MUST be called regularly - tud_task(); - - // Your application code - your_app_task(); - } - } - -Interrupt Handler Setup ------------------------ - -**STM32 example:** - -.. code-block:: c - - // USB interrupt handler - void OTG_FS_IRQHandler(void) { - tud_int_handler(0); - } - -**RP2040 example:** - -.. code-block:: c - - void isr_usbctrl(void) { - tud_int_handler(0); - } - -Class Implementation --------------------- - -Implement required callbacks for enabled classes: - -.. code-block:: c - - // CDC class callbacks - void tud_cdc_line_coding_cb(uint8_t itf, cdc_line_coding_t const* p_line_coding) { - // Handle line coding changes - } - - void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { - // Handle DTR/RTS changes - } - -RTOS Integration -=============== - -FreeRTOS Integration -------------------- - -.. code-block:: c - - // USB task - void usb_device_task(void* param) { - while (1) { - tud_task(); - vTaskDelay(1); // 1ms delay - } - } - - // Create USB task - xTaskCreate(usb_device_task, "usbd", - 256, NULL, configMAX_PRIORITIES-1, NULL); - -**Configuration:** - -.. code-block:: c - - // In tusb_config.h - #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUD_TASK_QUEUE_SZ 16 - -RT-Thread Integration --------------------- - -.. code-block:: c - - // In tusb_config.h - #define CFG_TUSB_OS OPT_OS_RTTHREAD - - // USB thread - void usb_thread_entry(void* parameter) { - tusb_init(); - while (1) { - tud_task(); - rt_thread_mdelay(1); - } - } - -Custom Hardware Integration -=========================== - -Clock Configuration -------------------- - -USB requires precise 48MHz clock: - -**STM32 example:** - -.. code-block:: c - - // Configure PLL for 48MHz USB clock - RCC_OscInitStruct.PLL.PLLQ = 7; // Adjust for 48MHz - HAL_RCC_OscConfig(&RCC_OscInitStruct); - -**RP2040 example:** - -.. code-block:: c - - // USB clock is automatically configured by SDK - -Pin Configuration ------------------ - -Configure USB pins correctly: - -**STM32 example:** - -.. code-block:: c - - // USB pins: PA11 (DM), PA12 (DP) - GPIO_InitStruct.Pin = GPIO_PIN_11 | GPIO_PIN_12; - GPIO_InitStruct.Mode = GPIO_MODE_AF_PP; - GPIO_InitStruct.Pull = GPIO_NOPULL; - GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH; - GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS; - HAL_GPIO_Init(GPIOA, &GPIO_InitStruct); - -Power Management ---------------- - -For battery-powered applications: - -.. code-block:: c - - // Implement suspend/resume callbacks - void tud_suspend_cb(bool remote_wakeup_en) { - // Enter low power mode - } - - void tud_resume_cb(void) { - // Exit low power mode - } - -Testing and Validation -====================== - -Build Verification ------------------- - -.. code-block:: bash - - # Test build - make clean && make all - - # Check binary size - arm-none-eabi-size build/firmware.elf - - # Verify no undefined symbols - arm-none-eabi-nm build/firmware.elf | grep " U " - -Runtime Testing ---------------- - -1. **Device Recognition**: Check if device appears in system -2. **Enumeration**: Verify all descriptors are valid -3. **Class Functionality**: Test class-specific features -4. **Performance**: Measure transfer rates and latency -5. **Stress Testing**: Long-running tests with connect/disconnect - -Debugging Integration Issues -============================ - -Common Problems ---------------- - -1. **Device not recognized**: Check descriptors and configuration -2. **Build errors**: Verify include paths and source files -3. **Link errors**: Check library dependencies -4. **Runtime crashes**: Enable debug builds and use debugger -5. **Poor performance**: Profile code and optimize critical paths - -Debug Builds ------------- - -.. code-block:: c - - // In tusb_config.h for debugging - #define CFG_TUSB_DEBUG 2 - #define CFG_TUSB_DEBUG_PRINTF printf - -Enable logging to identify issues quickly. - -Production Considerations -========================= - -Code Size Optimization ----------------------- - -.. code-block:: c - - // Minimal configuration - #define CFG_TUSB_DEBUG 0 - #define CFG_TUD_CDC 1 - #define CFG_TUD_HID 0 - #define CFG_TUD_MSC 0 - // Disable unused classes - -Performance Optimization ------------------------- - -- Use DMA for USB transfers if available -- Optimize descriptor sizes -- Use appropriate endpoint buffer sizes -- Consider high-speed USB for high bandwidth applications - -Compliance and Certification ----------------------------- - -- Validate descriptors against USB specifications -- Test with USB-IF compliance tools -- Consider USB-IF certification for commercial products -- Test with multiple host operating systems \ No newline at end of file diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 56ee49619..561780c53 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -4,6 +4,9 @@ Glossary .. glossary:: + BSP + Board Support Package. A collection of board-specific code that provides hardware abstraction for a particular development board, including pin mappings, clock settings, linker scripts, and hardware initialization routines. Located in ``hw/bsp/FAMILY/boards/BOARD_NAME``. + Bulk Transfer USB transfer type used for large amounts of data that doesn't require guaranteed timing. Used by mass storage devices and CDC class. diff --git a/docs/tutorials/first_device.rst b/docs/tutorials/first_device.rst deleted file mode 100644 index 1b9ed5b0a..000000000 --- a/docs/tutorials/first_device.rst +++ /dev/null @@ -1,151 +0,0 @@ -********************* -Your First USB Device -********************* - -This tutorial walks you through creating a simple USB CDC (serial) device using TinyUSB. By the end, you'll have a working USB device that appears as a serial port on your computer. - -Prerequisites -============= - -* Completed :doc:`getting_started` tutorial -* Development board with USB device capability (e.g., STM32F4 Discovery, Raspberry Pi Pico) -* Basic understanding of C programming - -Understanding USB Device Basics -=============================== - -A USB device needs three key components: - -1. **USB Descriptors**: Tell the host what kind of device this is -2. **Class Implementation**: Handle USB class-specific requests (CDC, HID, etc.) -3. **Application Logic**: Your main application code - -Step 1: Choose Your Starting Point -================================== - -We'll start with the ``cdc_msc`` example as it's the most commonly used and well-tested. - -.. code-block:: bash - - cd examples/device/cdc_msc - -This example implements both CDC (virtual serial port) and MSC (mass storage) classes. - -Step 2: Understand the Code Structure -===================================== - -Key files in the example: - -* ``main.c`` - Main application loop and board initialization -* ``usb_descriptors.c`` - USB device descriptors -* ``tusb_config.h`` - TinyUSB stack configuration - -The main loop follows a simple pattern that combines board initialization, TinyUSB initialization, and continuous task processing: - -.. code-block:: c - - int main(void) { - board_init(); - tusb_init(); - - while (1) { - tud_task(); // TinyUSB device task - cdc_task(); // Application-specific CDC handling - } - } - -The ``tud_task()`` function must be called regularly to handle USB events and maintain the connection with the host. This function processes all queued USB events and triggers appropriate callbacks in your application code. - -Step 3: Build and Test -====================== - -With a clear understanding of the code structure, you're ready to build and test the example. This process involves fetching dependencies, compiling for your target board, and flashing the firmware: - -.. code-block:: bash - - # Fetch dependencies for your board family - python ../../../tools/get_deps.py stm32f4 # Replace with your family - - # Build for your board - make BOARD=stm32f407disco all - - # Flash to device - make BOARD=stm32f407disco flash - -**Expected Result**: After flashing, connect the USB port to your computer. You should see: - -* A new serial port device (e.g., ``/dev/ttyACM0`` on Linux, ``COMx`` on Windows) -* A small mass storage device - -Step 4: Customize for Your Needs -================================= - -Once you have the basic example working, you can customize it for your specific application. The following modifications demonstrate common customization patterns. - -**Simplify to CDC-only**: - -1. In ``tusb_config.h``, disable MSC: - -.. code-block:: c - - #define CFG_TUD_MSC 0 // Disable Mass Storage - -2. Remove MSC-related code from ``main.c`` and ``usb_descriptors.c`` - -**Modify Device Information**: - -In ``usb_descriptors.c``: - -.. code-block:: c - - tusb_desc_device_t const desc_device = { - .idVendor = 0xCafe, // Your vendor ID - .idProduct = 0x4000, // Your product ID - .bcdDevice = 0x0100, // Device version - // ... other fields - }; - -**Add Application Logic**: - -In the CDC task function, add your serial communication logic: - -.. code-block:: c - - void cdc_task(void) { - if (tud_cdc_available()) { - uint8_t buf[64]; - uint32_t count = tud_cdc_read(buf, sizeof(buf)); - - // Echo back what was received - tud_cdc_write(buf, count); - tud_cdc_write_flush(); - } - } - -Common Issues and Solutions -=========================== - -**Device Not Recognized**: - -* Check USB cable (must support data, not just power) -* Verify descriptors are valid using ``LOG=2`` build option -* Ensure ``tud_task()`` is called regularly in main loop - -**Build Errors**: - -* Missing dependencies: Run ``python tools/get_deps.py FAMILY`` -* Wrong board name: Check ``hw/bsp/FAMILY/boards/`` for valid names -* Compiler issues: Install ``gcc-arm-none-eabi`` - -**Runtime Issues**: - -* Hard faults: Check stack size in linker script -* USB not working: Verify clock configuration and USB pin setup -* Serial data corruption: Ensure proper flow control in CDC implementation - -Next Steps -========== - -* Learn about other device classes in :doc:`../reference/usb_classes` -* Understand advanced integration in :doc:`../guides/integration` -* Explore TinyUSB architecture in :doc:`../explanation/architecture` \ No newline at end of file diff --git a/docs/tutorials/first_host.rst b/docs/tutorials/first_host.rst deleted file mode 100644 index 5b406ad34..000000000 --- a/docs/tutorials/first_host.rst +++ /dev/null @@ -1,160 +0,0 @@ -****************** -Your First USB Host -****************** - -This tutorial guides you through creating a simple USB host application that can connect to and communicate with USB devices. - -Prerequisites -============= - -* Completed :doc:`getting_started` and :doc:`first_device` tutorials -* Development board with USB host capability (e.g., STM32F4 Discovery with USB-A connector) -* USB device to test with (USB drive, mouse, keyboard, or CDC device) - -Understanding USB Host Basics -============================= - -A USB host application needs: - -1. **Device Enumeration**: Detect and configure connected devices -2. **Class Drivers**: Handle communication with specific device types -3. **Application Logic**: Process data from/to the connected devices - -Step 1: Start with an Example -============================= - -Use the ``cdc_msc_hid`` host example: - -.. code-block:: bash - - cd examples/host/cdc_msc_hid - -This example can communicate with CDC (serial), MSC (storage), and HID (keyboard/mouse) devices. - -Step 2: Understand the Code Structure -===================================== - -Key components: - -* ``main.c`` - Main loop and device event handling -* Host callbacks - Functions called when devices connect/disconnect -* Class-specific handlers - Process data from different device types - -**Main Loop Pattern**: - -.. code-block:: c - - int main(void) { - board_init(); - tusb_init(); - - while (1) { - tuh_task(); // TinyUSB host task - // Handle connected devices - } - } - -**Connection Events**: TinyUSB calls your callbacks when devices connect: - -.. code-block:: c - - void tuh_mount_cb(uint8_t dev_addr) { - printf("Device connected, address = %d\\n", dev_addr); - } - - void tuh_umount_cb(uint8_t dev_addr) { - printf("Device disconnected, address = %d\\n", dev_addr); - } - -Step 3: Build and Test -====================== - -.. code-block:: bash - - # Fetch dependencies - python ../../../tools/get_deps.py stm32f4 - - # Build - make BOARD=stm32f407disco all - - # Flash - make BOARD=stm32f407disco flash - -**Testing**: Connect different USB devices and observe the output via serial console. - -Step 4: Handle Specific Device Types -==================================== - -**Mass Storage (USB Drive)**: - -.. code-block:: c - - void tuh_msc_mount_cb(uint8_t dev_addr) { - printf("USB Drive mounted\\n"); - // Read/write files - } - -**HID Devices (Keyboard/Mouse)**: - -.. code-block:: c - - void tuh_hid_mount_cb(uint8_t dev_addr, uint8_t instance, - uint8_t const* desc_report, uint16_t desc_len) { - uint8_t const itf_protocol = tuh_hid_interface_protocol(dev_addr, instance); - if (itf_protocol == HID_ITF_PROTOCOL_KEYBOARD) { - printf("Keyboard connected\\n"); - } - } - -**CDC Devices (Serial)**: - -.. code-block:: c - - void tuh_cdc_mount_cb(uint8_t idx) { - printf("CDC device mounted\\n"); - // Configure serial settings - tuh_cdc_set_baudrate(idx, 115200, NULL, 0); - } - -Common Issues and Solutions -=========================== - -**No Device Detection**: - -* Check power supply - host mode requires more power than device mode -* Verify USB connector wiring and type (USB-A for host vs USB micro/C for device) -* Enable logging with ``LOG=2`` to see enumeration process - -**Enumeration Failures**: - -* Some devices need more time - increase timeouts -* Check USB hub support if using a hub -* Verify device is USB 2.0 compatible (USB 3.0 devices should work in USB 2.0 mode) - -**Class Driver Issues**: - -* Not all devices follow standards perfectly - may need custom handling -* Check device descriptors with USB analyzer tools -* Some composite devices may not be fully supported - -Hardware Considerations -======================= - -**Power Requirements**: - -* Host mode typically requires external power or powered USB hub -* Check board documentation for power limitations -* Some boards need jumper changes to enable host power - -**Pin Configuration**: - -* Host and device modes often use different USB connectors/pins -* Verify board supports host mode on your chosen port -* Check if OTG (On-The-Go) configuration is needed - -Next Steps -========== - -* Learn about supported USB classes in :doc:`../reference/usb_classes` -* Understand advanced integration in :doc:`../guides/integration` -* Explore TinyUSB architecture in :doc:`../explanation/architecture` \ No newline at end of file diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst index 432b0b682..35a9aa9bf 100644 --- a/docs/tutorials/getting_started.rst +++ b/docs/tutorials/getting_started.rst @@ -2,22 +2,22 @@ Getting Started *************** -This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example. +This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. Add TinyUSB to your project --------------------------- To incorporate TinyUSB into your project: -* Copy or ``git submodule`` this repository into your project in a subfolder. Let's say it is ``your_project/tinyusb`` +* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` * Add all the ``.c`` files in the ``tinyusb/src`` folder to your project -* Add ``your_project/tinyusb/src`` to your include path. Also make sure your current include path contains the configuration file ``tusb_config.h``. -* Make sure all required macros are defined properly in ``tusb_config.h`` (the configuration file in demo applications is sufficient, but you need to add a few more such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS`` since they are passed by make/cmake to maintain a unique configuration for all boards). -* If you use the device stack, make sure you have created/modified USB descriptors for your own needs. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. +* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. +* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. +* If you're using the device stack, ensure you have created or modified USB descriptors to meet your specific requirements. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. * Add a ``tusb_init(rhport, role)`` call to your reset initialization code. -* Call ``tusb_int_handler(rhport, in_isr)`` in your USB IRQ handler +* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler * Implement all enabled classes' callbacks. -* If you don't use any RTOS at all, you need to continuously and/or periodically call the ``tud_task()``/``tuh_task()`` functions. All of the callbacks and functionality are handled and invoked within the call of that task runner. +* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions continuously or periodically. These task functions handle all callbacks and core functionality. .. note:: TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. @@ -62,14 +62,16 @@ For your convenience, TinyUSB contains a handful of examples for both host and d $ git clone https://github.com/hathach/tinyusb tinyusb $ cd tinyusb -Some ports will also require a port-specific SDK (e.g. RP2040) or binary (e.g. Sony Spresense) to build examples. They are out of scope for TinyUSB, you should download/install them first according to the manufacturer's guide. +Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. Dependencies ^^^^^^^^^^^^ -The hardware code is located in the ``hw/bsp`` folder, and is organized by family/boards. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. Before building, we first need to download dependencies such as: MCU low-level peripheral drivers and external libraries like FreeRTOS (required by some examples). We can do this in either of two ways: +TinyUSB separates example applications from board-specific hardware configurations. Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while Board Support Package (BSP) configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. -1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a family as follows. Note: For TinyUSB developers to download all dependencies, use FAMILY=all. +Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: + +1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. .. code-block:: bash @@ -87,7 +89,7 @@ You only need to do this once per family. Check out :doc:`complete list of depen Build Examples ^^^^^^^^^^^^^^ -Examples support make and cmake build systems for most MCUs, however some MCU families such as Espressif or RP2040 only support cmake. First change directory to an example folder. +Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. .. code-block:: bash @@ -111,7 +113,7 @@ To list all available targets with cmake $ cmake --build . --target help -Note: some examples especially those that uses Vendor class (e.g webUSB) may requires udev permission on Linux (and/or macOS) to access usb device. It depends on your OS distro, typically copy ``99-tinyusb.rules`` and reload your udev is good to go +Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient .. code-block:: bash @@ -132,7 +134,7 @@ If a board has several ports, one port is chosen by default in the individual bo Port Speed ~~~~~~~~~~ -A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force F723 operate at full instead of default high speed +An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: .. code-block:: bash @@ -149,8 +151,36 @@ First install `linkermap tool `_ then ``li $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap -Debug -^^^^^ +Flashing the Device +^^^^^^^^^^^^^^^^^^^ + +The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash + $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash + +Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash-jlink + $ make BOARD=feather_nrf52840_express flash-openocd + + $ cmake --build . --target cdc_msc-jlink + $ cmake --build . --target cdc_msc-openocd + +Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express all uf2 + + $ cmake --build . --target cdc_msc-uf2 + +Debugging +^^^^^^^^^ To compile for debugging add ``DEBUG=1``\ , for example @@ -160,10 +190,10 @@ To compile for debugging add ``DEBUG=1``\ , for example $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. -Log -~~~ +Enable Logging +~~~~~~~~~~~~~~ -Should you have an issue running example and/or submitting an bug report. You could enable TinyUSB built-in debug logging with optional ``LOG=``. ``LOG=1`` will only print out error message, ``LOG=2`` print more information with on-going events. ``LOG=3`` or higher is not used yet. +If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. .. code-block:: bash @@ -171,10 +201,10 @@ Should you have an issue running example and/or submitting an bug report. You co $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. -Logger -~~~~~~ +Logging Performance Impact +~~~~~~~~~~~~~~~~~~~~~~~~~~ -By default log message is printed via on-board UART which is slow and take lots of CPU time comparing to USB speed. If your board support on-board/external debugger, it would be more efficient to use it for logging. There are 2 protocols: +By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: * `LOGGER=rtt`: use `Segger RTT protocol `_ @@ -183,9 +213,9 @@ By default log message is printed via on-board UART which is slow and take lots * Pros: work with most if not all MCUs * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. -* ``LOGGER=swo`` : Use dedicated SWO pin of ARM Cortex SWD debug header. +* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. - * Cons: only work with ARM Cortex MCUs minus M0 + * Cons: Only works with ARM Cortex MCUs except M0 * Pros: should be compatible with more debugger that support SWO. * Software viewer should be provided along with your debugger driver. @@ -197,49 +227,23 @@ By default log message is printed via on-board UART which is slow and take lots $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. -Flash -^^^^^ - -``flash`` target will use the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary, please install those support software in advance. Some board use bootloader/DFU via serial which is required to pass to make command - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash - $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash - -Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash-jlink - $ make BOARD=feather_nrf52840_express flash-openocd - - $ cmake --build . --target cdc_msc-jlink - $ cmake --build . --target cdc_msc-openocd - -Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can be generated with ``uf2`` target - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express all uf2 - - $ cmake --build . --target cdc_msc-uf2 - IAR Support ^^^^^^^^^^^ +IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. + Use project connection ~~~~~~~~~~~~~~~~~~~~~~ IAR Project Connection files are provided to import TinyUSB stack into your project. -* A buildable project of your MCU need to be created in advance. +* A buildable project for your MCU needs to be created in advance. * Take example of STM32F0: - - You need ``stm32l0xx.h``, ``startup_stm32f0xx.s``, ``system_stm32f0xx.c``. + - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. - - ``STM32L0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. + - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. * Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, @@ -279,7 +283,7 @@ Common Issues and Solutions **Build Errors** * **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` -* **"Board 'X' not found"**: Check available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` +* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` * **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board **Runtime Issues** @@ -288,9 +292,65 @@ Common Issues and Solutions * **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors * **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation +Quick Start Examples +-------------------- + +Now that you have TinyUSB set up, you can try these examples to see it in action. + +Simple Device Example +^^^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. + +**What it does:** +* Appears as a serial port that echoes back any text you send +* Appears as a small USB drive with a README.TXT file +* Blinks an LED to show activity + +**Build and run:** + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tud_task()`` loop +* ``src/usb_descriptors.c`` - USB device descriptors +* ``src/msc_disk.c`` - Mass storage implementation + +**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. + +Simple Host Example +^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. + +**What it does:** +* Detects and enumerates connected USB devices +* Communicates with CDC devices (like USB-to-serial adapters) +* Reads from MSC devices (like USB drives) +* Receives input from HID devices (like keyboards and mice) + +**Build and run:** + +.. code-block:: bash + + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tuh_task()`` loop +* ``src/cdc_app.c`` - CDC host functionality +* ``src/msc_app.c`` - Mass storage host functionality +* ``src/hid_app.c`` - HID host functionality + +**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. + Next Steps ----------- +^^^^^^^^^^ -* Try the :doc:`first_device` tutorial to implement a simple USB device -* Read about :doc:`../guides/integration` for production projects * Check :doc:`../reference/boards` for board-specific information +* Explore more :doc:`../examples` for advanced use cases diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst index 6cf8f6ded..dc362d717 100644 --- a/docs/tutorials/index.rst +++ b/docs/tutorials/index.rst @@ -7,6 +7,4 @@ Step-by-step learning guides for TinyUSB development. .. toctree:: :maxdepth: 2 - getting_started - first_device - first_host \ No newline at end of file + getting_started \ No newline at end of file -- cgit v1.3.1 From 82aa46d8ea9370944440cc40b87738ebeabb9593 Mon Sep 17 00:00:00 2001 From: c1570 Date: Sat, 27 Sep 2025 00:30:24 +0200 Subject: more consolidation --- docs/explanation/architecture.rst | 296 ------------------------- docs/explanation/index.rst | 11 - docs/explanation/usb_concepts.rst | 425 ------------------------------------ docs/faq.rst | 2 +- docs/getting_started.rst | 357 +++++++++++++++++++++++++++++++ docs/index.rst | 12 +- docs/reference/architecture.rst | 291 +++++++++++++++++++++++++ docs/reference/configuration.rst | 307 -------------------------- docs/reference/index.rst | 5 +- docs/reference/usb_classes.rst | 287 ------------------------- docs/reference/usb_concepts.rst | 428 +++++++++++++++++++++++++++++++++++++ docs/tutorials/getting_started.rst | 356 ------------------------------ docs/tutorials/index.rst | 10 - 13 files changed, 1083 insertions(+), 1704 deletions(-) delete mode 100644 docs/explanation/architecture.rst delete mode 100644 docs/explanation/index.rst delete mode 100644 docs/explanation/usb_concepts.rst create mode 100644 docs/getting_started.rst create mode 100644 docs/reference/architecture.rst delete mode 100644 docs/reference/configuration.rst delete mode 100644 docs/reference/usb_classes.rst create mode 100644 docs/reference/usb_concepts.rst delete mode 100644 docs/tutorials/getting_started.rst delete mode 100644 docs/tutorials/index.rst (limited to 'docs') diff --git a/docs/explanation/architecture.rst b/docs/explanation/architecture.rst deleted file mode 100644 index aa0c76128..000000000 --- a/docs/explanation/architecture.rst +++ /dev/null @@ -1,296 +0,0 @@ -************ -Architecture -************ - -This document explains TinyUSB's internal architecture, design principles, and how different components work together. - -Design Principles -================= - -Memory Safety -------------- - -TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: - -TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. - -Thread Safety -------------- - -TinyUSB achieves thread safety through a deferred interrupt model: - -- **ISR deferral**: USB interrupts are captured and deferred to task context -- **Single-threaded processing**: All USB protocol handling occurs in task context -- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` -- **RTOS integration**: Proper semaphore/mutex usage for shared resources - -Portability ------------ - -The stack is designed to work across diverse microcontroller families: - -- **Hardware abstraction**: MCU-specific code isolated in portable drivers -- **OS abstraction**: RTOS dependencies isolated in OSAL layer -- **Modular design**: Features can be enabled/disabled at compile time -- **Standard compliance**: Strict adherence to USB specifications - -Core Architecture -================= - -Layer Structure ---------------- - -TinyUSB follows a layered architecture from hardware to application: - -.. code-block:: none - - ┌─────────────────────────────────────────┐ - │ Application Layer │ ← Your code - ├─────────────────────────────────────────┤ - │ USB Class Drivers │ ← CDC, HID, MSC, etc. - ├─────────────────────────────────────────┤ - │ Device/Host Stack Core │ ← USB protocol handling - ├─────────────────────────────────────────┤ - │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers - ├─────────────────────────────────────────┤ - │ OS Abstraction (OSAL) │ ← RTOS integration - ├─────────────────────────────────────────┤ - │ Common Utilities & FIFO │ ← Shared components - └─────────────────────────────────────────┘ - -Component Overview ------------------- - -**Application Layer**: Your main application code that uses TinyUSB APIs. - -**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. - -**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. - -**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. - -**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. - -**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. - -Device Stack Architecture -========================= - -This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). - -Core Components ---------------- - -**Device Controller Driver (DCD)**: -- MCU-specific USB device peripheral driver -- Handles endpoint configuration and data transfers -- Abstracts hardware differences between MCU families -- Located in ``src/portable/VENDOR/FAMILY/`` - -**USB Device Core (USBD)**: -- Implements USB device state machine -- Handles standard USB requests (Chapter 9) -- Manages device configuration and enumeration -- Located in ``src/device/`` - -**Class Drivers**: -- Implement USB class specifications -- Handle class-specific requests and data transfer -- Provide application APIs -- Located in ``src/class/*/`` - -Data Flow ---------- - -**Control Transfers (Setup Requests)**: - -.. code-block:: none - - USB Bus → DCD → USBD Core → Class Driver → Application - ↓ - Standard requests handled in core - ↓ - Class-specific requests → Class Driver - -**Data Transfers**: - -.. code-block:: none - - Application → Class Driver → USBD Core → DCD → USB Bus - USB Bus → DCD → USBD Core → Class Driver → Application - -Event Processing ----------------- - -TinyUSB uses a deferred interrupt model for thread safety: - -1. **Interrupt Occurs**: USB hardware generates interrupt -2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing -3. **Event Queuing**: Events queued for later processing -4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events -5. **Callback Execution**: Application callbacks executed in task context - -.. code-block:: none - - USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application - -Host Stack Architecture -======================= - -This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. - -Core Components ---------------- - -**Host Controller Driver (HCD)**: -- MCU-specific USB host peripheral driver -- Manages USB pipes and data transfers -- Handles host controller hardware -- Located in ``src/portable/VENDOR/FAMILY/`` - -**USB Host Core (USBH)**: -- Implements USB host functionality -- Manages device enumeration and configuration -- Handles pipe management and scheduling -- Located in ``src/host/`` - -**Hub Driver**: -- Manages USB hub devices -- Handles port management and device detection -- Supports multi-level hub topologies -- Located in ``src/host/`` - -Device Enumeration ------------------- - -The host stack follows USB enumeration process: - -1. **Device Detection**: Hub or root hub detects device connection -2. **Reset and Address**: Reset device, assign unique address -3. **Descriptor Retrieval**: Get device, configuration, and class descriptors -4. **Driver Matching**: Find appropriate class driver for device -5. **Configuration**: Configure device and start communication -6. **Class Operation**: Normal class-specific communication - -.. code-block:: none - - Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate - -Class Architecture -================== - -Common Class Structure ----------------------- - -All USB classes follow a similar architecture: - -**Device Classes**: -- ``*_device.c``: Device-side implementation -- ``*_device.h``: Device API definitions -- Implement class-specific descriptors -- Handle class requests and data transfer - -**Host Classes**: -- ``*_host.c``: Host-side implementation -- ``*_host.h``: Host API definitions -- Manage connected devices of this class -- Provide application interface - -Class Driver Interface ----------------------- - -**Required Functions**: -- ``init()``: Initialize class driver -- ``reset()``: Reset class state -- ``open()``: Configure class endpoints -- ``control_xfer_cb()``: Handle control requests -- ``xfer_cb()``: Handle data transfer completion - -**Optional Functions**: -- ``close()``: Clean up class resources -- ``sof_cb()``: Start-of-frame processing - -Descriptor Management ---------------------- - -Each class is responsible for: -- **Interface Descriptors**: Define class type and endpoints -- **Class-Specific Descriptors**: Additional class requirements -- **Endpoint Descriptors**: Define data transfer characteristics - -Memory Management -================= - -Static Allocation Model ------------------------ - -TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. - -Buffer Management ------------------ - -**Endpoint Buffers**: -- Allocated per endpoint at compile time -- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros -- Used for USB data transfers - -**FIFO Buffers**: -- Ring buffers for streaming data -- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros -- Separate read/write pointers - -**DMA Considerations**: -- Buffers must be DMA-accessible on some MCUs -- Alignment requirements vary by hardware -- Cache coherency handled in portable drivers - -Threading Model -=============== - -Task-Based Design ------------------ - -TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. - -RTOS Integration ----------------- - -**Bare Metal**: -- Application calls ``tud_task()`` in main loop -- No threading primitives needed -- Simplest integration method - -**FreeRTOS**: -- USB task runs at high priority -- Semaphores used for synchronization -- Queue for inter-task communication - -**Other RTOS**: -- Similar patterns with RTOS-specific primitives -- OSAL layer abstracts RTOS differences - -Interrupt Handling ------------------- - -**Interrupt Service Routine**: -- Minimal processing in ISR -- Event capture and queuing only -- Quick return to avoid blocking - -**Deferred Processing**: -- All complex processing in task context -- Thread-safe access to data structures -- Application callbacks in known context - -Memory Usage Patterns ---------------------- - -**Flash Memory**: -- Core stack: 8-15KB depending on features -- Each class: 1-4KB additional -- Portable driver: 2-8KB depending on MCU - -**RAM Usage**: -- Core stack: 1-2KB -- Endpoint buffers: User configurable -- Class buffers: Depends on configuration diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst deleted file mode 100644 index 695efd9e0..000000000 --- a/docs/explanation/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -*********** -Explanation -*********** - -Deep understanding of TinyUSB's design, architecture, and concepts. - -.. toctree:: - :maxdepth: 2 - - architecture - usb_concepts \ No newline at end of file diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst deleted file mode 100644 index e3d400921..000000000 --- a/docs/explanation/usb_concepts.rst +++ /dev/null @@ -1,425 +0,0 @@ -************ -USB Concepts -************ - -This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. - -TinyUSB API Naming Conventions -=============================== - -TinyUSB uses consistent function prefixes to organize its API: - -* **tusb_**: Core stack functions (initialization, interrupt handling) -* **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) -* **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) -* **tu_**: Internal utility functions (generally not used by applications) - -This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. - -USB Protocol Basics -==================== - -Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. - -Host and Device Roles ----------------------- - -**USB Host**: The controlling side of a USB connection (typically a computer). The host: -- Initiates all communication -- Provides power to devices -- Manages the USB bus -- Enumerates and configures devices - -**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. - -**USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: -- Respond to host requests -- Cannot initiate communication -- Receive power from the host -- Must be enumerated by the host before use - -**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. - -**OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. - -USB Transfers -============= - -Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. -Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. - -USB defines four transfer types, each intended for different use cases: - -Control Transfers ------------------ - -Used for device configuration and control commands. - -**Characteristics**: -- Bidirectional (uses both IN and OUT) -- Guaranteed delivery with error detection -- Limited data size (8-64 bytes per packet) -- All devices must support control transfers on endpoint 0 - -**Usage**: Device enumeration, configuration changes, class-specific commands - -**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). - -Bulk Transfers --------------- - -Used for large amounts of data that don't require guaranteed timing. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- Guaranteed delivery with error detection -- Large packet sizes (up to 512 bytes for High Speed) -- Uses available bandwidth when no other transfers are active - -**Usage**: File transfers, large data communication, CDC serial data - -**TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. - -Interrupt Transfers -------------------- - -Used for small, time-sensitive data with guaranteed maximum latency. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- Guaranteed delivery with error detection -- Small packet sizes (up to 64 bytes for Full Speed) -- Regular polling interval (1ms to 255ms) - -**Usage**: Keyboard/mouse input, sensor data, status updates - -**TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. - -Isochronous Transfers ---------------------- - -Used for time-critical streaming data. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- No error correction (speed over reliability) -- Guaranteed bandwidth -- Real-time delivery - -**Usage**: Audio, video streaming - -**TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. - -Endpoints and Addressing -========================= - -Endpoint Basics ---------------- - -**Endpoint**: A communication channel between host and device. - -- Each endpoint has a number (0-15) and direction -- Endpoint 0 is reserved for control transfers -- Other endpoints are assigned by device class requirements - -**TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. - -**Direction**: -- **OUT**: Host to device (host sends data out) -- **IN**: Device to host (host reads data in) -- Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). - -**Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) - -Endpoint Configuration ----------------------- - -Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. - -**TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. - -Error Handling and Flow Control -------------------------------- - -**Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. - -**Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. - -**TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. - -USB Device States -================= - -A USB device progresses through several states: - -1. **Attached**: Device is physically connected -2. **Powered**: Device receives power from host -3. **Default**: Device responds to address 0 -4. **Address**: Device has been assigned a unique address -5. **Configured**: Device is ready for normal operation -6. **Suspended**: Device is in low-power state - -**TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. - -Device Enumeration Process -========================== - -When a device is connected, the host follows this process: - -1. **Detection**: Host detects device connection -2. **Reset**: Host resets the device -3. **Descriptor Requests**: Host requests device descriptors -4. **Address Assignment**: Host assigns unique address to device -5. **Configuration**: Host selects and configures device -6. **Class Loading**: Host loads appropriate drivers -7. **Normal Operation**: Device is ready for use - -**TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. - -USB Descriptors -=============== - -Descriptors are data structures that describe device capabilities: - -Device Descriptor ------------------ -Describes the device (VID, PID, USB version, etc.) - -Configuration Descriptor ------------------------- -Describes device configuration (power requirements, interfaces, etc.) - -Interface Descriptor --------------------- -Describes a functional interface (class, endpoints, etc.) - -Endpoint Descriptor -------------------- -Describes endpoint characteristics (type, direction, size, etc.) - -String Descriptors ------------------- -Human-readable strings (manufacturer, product name, etc.) - -**TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: -- ``tud_descriptor_device_cb()`` - Device descriptor -- ``tud_descriptor_configuration_cb()`` - Configuration descriptor -- ``tud_descriptor_string_cb()`` - String descriptors - -The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. - -USB Classes -=========== - -USB classes define standardized protocols for device types: - -**Class Code**: Identifies the device type in descriptors -**Class Driver**: Software that implements the class protocol -**Class Requests**: Standardized commands for the class - -**Common TinyUSB-Supported Classes**: -- **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` -- **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` -- **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` -- **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` -- **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` -- **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` -- **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` - -See :doc:`../reference/usb_classes` for detailed class information and :doc:`../reference/configuration` for configuration options. - -USB Speeds -========== - -USB supports multiple speed modes: - -**Low Speed (1.5 Mbps)**: -- Simple devices (mice, keyboards) -- Limited endpoint types and sizes - -**Full Speed (12 Mbps)**: -- Most common for embedded devices -- All transfer types supported -- Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) - -**High Speed (480 Mbps)**: -- High-performance devices -- Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) -- Requires more complex hardware - -**Super Speed (5 Gbps)**: -- USB 3.0 and later -- Not supported by TinyUSB - -**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. - -USB Controller Abstraction -=========================== - -USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. - -Controller Fundamentals ------------------------ - -**What Controllers Do**: -- Handle USB signaling and protocol timing -- Manage endpoint buffers and data transfers -- Generate interrupts for USB events -- Implement USB electrical specifications - -**Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. - -Controller Architecture Types ------------------------------ - -Different MCU vendors implement USB controllers with varying architectures. -To list a few common patterns: - -**FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): -- Shared or dedicated FIFOs for endpoint data -- Software manages FIFO allocation and data flow -- Common in higher-end MCUs with flexible configurations - -**Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): -- Fixed packet memory areas for each endpoint -- Hardware automatically handles packet placement -- Simpler programming model, common in smaller MCUs - -**Descriptor-Based Controllers** (e.g., NXP EHCI-style): -- Use descriptor chains to describe transfers -- Hardware processes transfer descriptors independently -- More complex but can handle larger transfers autonomously - -TinyUSB Controller Abstraction ------------------------------- - -TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. -These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. - -**Portable Interface** (``src/device/usbd.h``): -- Standardized function signatures for all controllers -- Common endpoint and transfer management APIs -- Unified interrupt and event handling - -**Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): -- Implement the DCD interface for specific hardware -- Handle vendor-specific register layouts and behaviors -- Manage controller-specific quirks and workarounds - -**Common DCD Functions**: -- ``dcd_init()`` - Initialize controller hardware -- ``dcd_edpt_open()`` - Configure endpoint with type and size -- ``dcd_edpt_xfer()`` - Start data transfer on endpoint -- ``dcd_int_handler()`` - Process USB interrupts -- ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection - -Host Controller Driver (HCD) ------------------------------ - -TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. - -**Portable Interface** (``src/host/usbh.h``): -- Standardized interface for all host controllers -- Common device enumeration and pipe management -- Unified transfer scheduling and completion handling - -**Common HCD Functions**: -- ``hcd_init()`` - Initialize host controller hardware -- ``hcd_port_connect_status()`` - Check device connection status -- ``hcd_port_reset()`` - Reset connected device -- ``hcd_edpt_open()`` - Open communication pipe to device endpoint -- ``hcd_edpt_xfer()`` - Transfer data to/from connected device - -**Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. - -TinyUSB Event System & Thread Safety -==================================== - -Deferred Interrupt Processing ------------------------------ - -**Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. - -**Event Flow**: - -1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) -2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue -3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events -4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks - -**Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. - -Controller Event Flow ---------------------- - -**Typical USB Event Processing**: - -1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) -2. **Interrupt Generation**: Controller generates interrupt to CPU -3. **ISR Processing**: ``dcd_int_handler()`` reads controller status -4. **Event Queuing**: Events are queued for later processing (thread safety) -5. **Task Processing**: ``tud_task()`` processes queued events -6. **Class Notification**: Appropriate class drivers handle the event -7. **Application Callback**: User code responds to the event - -USB Class Driver Architecture -============================== - -TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. - -Class Driver Pattern ---------------------- - -**Standardized Entry Points**: Each class driver implements these core functions: - -- ``*_init()`` - Initialize class driver state and buffers -- ``*_reset()`` - Reset to initial state on USB bus reset -- ``*_open()`` - Parse and configure interfaces during enumeration -- ``*_control_xfer_cb()`` - Handle class-specific control requests -- ``*_xfer_cb()`` - Handle transfer completion callbacks - -**Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: - -.. code-block:: c - - // Single instance (default instance 0) - tud_cdc_write(data, len); - - // Multiple instances - tud_cdc_n_write(0, data, len); // Instance 0 - tud_cdc_n_write(1, data, len); // Instance 1 - -**Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. - -Class Driver Types -------------------- - -TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. - -Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. - -The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. - -**Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. - -Power Management -================ - -USB provides power to devices: - -**Bus-Powered**: Device draws power from USB bus (up to 500mA) -**Self-Powered**: Device has its own power source -**Suspend/Resume**: Devices must enter low-power mode when bus is idle - -**TinyUSB Power Management**: -- Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management -- Configure power requirements in device descriptor (``bMaxPower`` field) -- Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) -- Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` - -Next Steps -========== - -- Start with :doc:`../tutorials/getting_started` for basic setup -- Review :doc:`../reference/configuration` for configuration options -- Explore :doc:`../examples` for advanced use cases diff --git a/docs/faq.rst b/docs/faq.rst index 505833316..ade51a379 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -38,7 +38,7 @@ Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., s **Q: Can I use my own build system instead of Make/CMake?** -Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`tutorials/getting_started` for details. +Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`getting_started` for details. **Q: Error: "tusb_config.h: No such file or directory"** diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 000000000..5e8ebd040 --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,357 @@ +*************** +Getting Started +*************** + +This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. + +Add TinyUSB to your project +--------------------------- + +To incorporate TinyUSB into your project: + +* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` +* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project +* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. +* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. +* If you're using the **device stack**, you need to implement all **tud descriptor** callbacks for the stack to work. +* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. +* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler +* Implement all enabled classes' callbacks. +* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions periodically. These task functions handle all callbacks and core functionality. + +.. note:: + TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. + +.. code-block:: c + + int main(void) { + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_AUTO + }; + // tud descriptor omitted here + tusb_init(0, &dev_init); // initialize device stack on roothub port 0 + + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_HOST, + .speed = TUSB_SPEED_AUTO + }; + tusb_init(1, &host_init); // initialize host stack on roothub port 1 + + while(1) { // the mainloop + your_application_code(); + tud_task(); // device task + tuh_task(); // host task + } + } + + void USB0_IRQHandler(void) { + tusb_int_handler(0, true); + } + + void USB1_IRQHandler(void) { + tusb_int_handler(1, true); + } + +Examples +-------- + +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already + +.. code-block:: bash + + $ git clone https://github.com/hathach/tinyusb tinyusb + $ cd tinyusb + +Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. + +Dependencies +^^^^^^^^^^^^ + +TinyUSB separates example applications from board-specific hardware configurations (Board Support Packages, BSP). Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while BSP configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. + +Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: + +1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. + +.. code-block:: bash + + $ python tools/get_deps.py rp2040 + +2. Or run the ``get-deps`` target in one of the example folders as follows. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=feather_nrf52840_express get-deps + +You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` + +Build Examples +^^^^^^^^^^^^^^ + +Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + +Then compile with make or cmake + +.. code-block:: bash + + $ # make + $ make BOARD=feather_nrf52840_express all + + $ # cmake + $ mkdir build && cd build + $ cmake -DBOARD=raspberry_pi_pico .. + $ make + +To list all available targets with cmake + +.. code-block:: bash + + $ cmake --build . --target help + +Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient + +.. code-block:: bash + + $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ + $ sudo udevadm control --reload-rules && sudo udevadm trigger + +RootHub Port Selection +~~~~~~~~~~~~~~~~~~~~~~ + +If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. + +Port Speed +~~~~~~~~~~ + +An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. + +Size Analysis +~~~~~~~~~~~~~ + +First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap + +Flashing the Device +^^^^^^^^^^^^^^^^^^^ + +The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash + $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash + +Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash-jlink + $ make BOARD=feather_nrf52840_express flash-openocd + + $ cmake --build . --target cdc_msc-jlink + $ cmake --build . --target cdc_msc-openocd + +Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express all uf2 + + $ cmake --build . --target cdc_msc-uf2 + +Debugging +^^^^^^^^^ + +To compile for debugging add ``DEBUG=1``\ , for example + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express DEBUG=1 all + + $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. + +Enable Logging +~~~~~~~~~~~~~~ + +If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. + +Logging Performance Impact +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: + + +* `LOGGER=rtt`: use `Segger RTT protocol `_ + + * Cons: requires jlink as the debugger. + * Pros: work with most if not all MCUs + * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. + +* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. + + * Cons: Only works with ARM Cortex MCUs except M0 + * Pros: should be compatible with more debugger that support SWO. + * Software viewer should be provided along with your debugger driver. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. + +IAR Support +^^^^^^^^^^^ + +IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. + +Use project connection +~~~~~~~~~~~~~~~~~~~~~~ + +IAR Project Connection files are provided to import TinyUSB stack into your project. + +* A buildable project for your MCU needs to be created in advance. + + * Take example of STM32F0: + + - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. + + - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. + +* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) + Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, + for example ``C:\\tinyusb`` + +**Import stack only** + +Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. + +**Run examples** + +1. Run ``iar_gen.py`` to generate .ipcf files of examples: + + .. code-block:: + + > cd C:\tinyusb\tools + > python iar_gen.py + +2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. + For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` + +Native CMake support +~~~~~~~~~~~~~~~~~~~~ + +With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. + +Following these steps: + +1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. +2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. +3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. +4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. + +Common Issues and Solutions +--------------------------- + +**Build Errors** + +* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` +* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` +* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board + +**Runtime Issues** + +* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings +* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors +* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation + +Quick Start Examples +-------------------- + +Now that you have TinyUSB set up, you can try these examples to see it in action. + +Simple Device Example +^^^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. + +**What it does:** +* Appears as a serial port that echoes back any text you send +* Appears as a small USB drive with a README.TXT file +* Blinks an LED to show activity + +**Build and run:** + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tud_task()`` loop +* ``src/usb_descriptors.c`` - USB device descriptors +* ``src/msc_disk.c`` - Mass storage implementation + +**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. + +Simple Host Example +^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. + +**What it does:** +* Detects and enumerates connected USB devices +* Communicates with CDC devices (like USB-to-serial adapters) +* Reads from MSC devices (like USB drives) +* Receives input from HID devices (like keyboards and mice) + +**Build and run:** + +.. code-block:: bash + + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tuh_task()`` loop +* ``src/cdc_app.c`` - CDC host functionality +* ``src/msc_app.c`` - Mass storage host functionality +* ``src/hid_app.c`` - HID host functionality + +**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. + +Next Steps +^^^^^^^^^^ + +* Check :doc:`reference/boards` for board-specific information +* Explore more examples in ``examples/device/`` and ``examples/host/`` directories diff --git a/docs/index.rst b/docs/index.rst index 3a70f2471..ac10dbfd7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,10 +18,8 @@ TinyUSB provides a complete USB stack implementation supporting both device and **Quick Navigation:** -* New to TinyUSB? Start with :doc:`tutorials/getting_started` -* Need to solve a specific problem? Check :doc:`guides/index` -* Looking for API details? See :doc:`reference/index` -* Want to understand the design? Read :doc:`explanation/architecture` +* New to TinyUSB? Start with :doc:`getting_started` and :doc:`reference/glossary` +* Want to understand the design? Read :doc:`reference/architecture` and :doc:`reference/usb_concepts` * Having issues? Check :doc:`faq` and :doc:`troubleshooting` Documentation Structure @@ -31,12 +29,10 @@ Documentation Structure :maxdepth: 2 :caption: Information - explanation/index - tutorials/index - guides/index - reference/index + getting_started faq troubleshooting + reference/index .. toctree:: :maxdepth: 1 diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst new file mode 100644 index 000000000..ab451a91a --- /dev/null +++ b/docs/reference/architecture.rst @@ -0,0 +1,291 @@ +************ +Architecture +************ + +This document explains TinyUSB's internal architecture, design principles, and how different components work together. + +Design Principles +================= + +Memory Safety +------------- + +TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: + +TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. + +Thread Safety +------------- + +TinyUSB achieves thread safety through a deferred interrupt model: + +- **ISR deferral**: USB interrupts are captured and deferred to task context +- **Single-threaded processing**: All USB protocol handling occurs in task context +- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` +- **RTOS integration**: Proper semaphore/mutex usage for shared resources + +Portability +----------- + +The stack is designed to work across diverse microcontroller families: + +- **Hardware abstraction**: MCU-specific code isolated in portable drivers +- **OS abstraction**: RTOS dependencies isolated in OSAL layer +- **Modular design**: Features can be enabled/disabled at compile time +- **Standard compliance**: Strict adherence to USB specifications + +Core Architecture +================= + +Layer Structure +--------------- + +TinyUSB follows a layered architecture from hardware to application: + +.. code-block:: none + + ┌─────────────────────────────────────────┐ + │ Application Layer │ ← Your code + ├─────────────────────────────────────────┤ + │ USB Class Drivers │ ← CDC, HID, MSC, etc. + ├─────────────────────────────────────────┤ + │ Device/Host Stack Core │ ← USB protocol handling + ├─────────────────────────────────────────┤ + │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers + ├─────────────────────────────────────────┤ + │ OS Abstraction (OSAL) │ ← RTOS integration + ├─────────────────────────────────────────┤ + │ Common Utilities & FIFO │ ← Shared components + └─────────────────────────────────────────┘ + +Component Overview +------------------ + +**Application Layer**: Your main application code that uses TinyUSB APIs. + +**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. + +**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. + +**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. + +**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. + +**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. + +Device Stack Architecture +========================= + +This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). + +Core Components +--------------- + +**Device Controller Driver (DCD)**: +- MCU-specific USB device peripheral driver +- Handles endpoint configuration and data transfers +- Abstracts hardware differences between MCU families +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Device Core (USBD)**: +- Implements USB device state machine +- Handles standard USB requests (Chapter 9) +- Manages device configuration and enumeration +- Located in ``src/device/`` + +**Class Drivers**: +- Implement USB class specifications +- Handle class-specific requests and data transfer +- Provide application APIs +- Located in ``src/class/*/`` + +Data Flow +--------- + +**Control Transfers (Setup Requests)**: + +.. code-block:: none + + USB Bus → DCD → USBD Core → Class Driver → Application + ↓ + Standard requests handled in core + ↓ + Class-specific requests → Class Driver + +**Data Transfers**: + +.. code-block:: none + + Application → Class Driver → USBD Core → DCD → USB Bus + USB Bus → DCD → USBD Core → Class Driver → Application + +Event Processing +---------------- + +TinyUSB uses a deferred interrupt model for thread safety: + +1. **Interrupt Occurs**: USB hardware generates interrupt +2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing +3. **Event Queuing**: Events queued for later processing +4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events +5. **Callback Execution**: Application callbacks executed in task context + +.. code-block:: none + + USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application + +Host Stack Architecture +======================= + +This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. + +Core Components +--------------- + +**Host Controller Driver (HCD)**: +- MCU-specific USB host peripheral driver +- Manages USB pipes and data transfers +- Handles host controller hardware +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Host Core (USBH)**: +- Implements USB host functionality +- Manages device enumeration and configuration +- Handles pipe management and scheduling +- Located in ``src/host/`` + +**Hub Driver**: +- Manages USB hub devices +- Handles port management and device detection +- Supports multi-level hub topologies +- Located in ``src/host/`` + +Device Enumeration +------------------ + +The host stack follows USB enumeration process: + +1. **Device Detection**: Hub or root hub detects device connection +2. **Reset and Address**: Reset device, assign unique address +3. **Descriptor Retrieval**: Get device, configuration, and class descriptors +4. **Driver Matching**: Find appropriate class driver for device +5. **Configuration**: Configure device and start communication +6. **Class Operation**: Normal class-specific communication + +.. code-block:: none + + Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate + +Class Architecture +================== + +Common Class Structure +---------------------- + +All USB classes follow a similar architecture: + +**Device Classes**: +- ``*_device.c``: Device-side implementation +- ``*_device.h``: Device API definitions +- Implement class-specific descriptors +- Handle class requests and data transfer + +**Host Classes**: +- ``*_host.c``: Host-side implementation +- ``*_host.h``: Host API definitions +- Manage connected devices of this class +- Provide application interface + +Class Driver Interface +---------------------- + +**Required Functions**: +- ``init()``: Initialize class driver +- ``reset()``: Reset class state +- ``open()``: Configure class endpoints +- ``control_xfer_cb()``: Handle control requests +- ``xfer_cb()``: Handle data transfer completion + +**Optional Functions**: +- ``close()``: Clean up class resources +- ``sof_cb()``: Start-of-frame processing + +Descriptor Management +--------------------- + +Each class is responsible for: +- **Interface Descriptors**: Define class type and endpoints +- **Class-Specific Descriptors**: Additional class requirements +- **Endpoint Descriptors**: Define data transfer characteristics + +Memory Management +================= + +Static Allocation Model +----------------------- + +TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. + +Buffer Management +----------------- + +**Endpoint Buffers**: +- Allocated per endpoint at compile time +- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros +- Used for USB data transfers + +**FIFO Buffers**: +- Ring buffers for streaming data +- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros +- Separate read/write pointers + +Threading Model +=============== + +Task-Based Design +----------------- + +TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. + +RTOS Integration +---------------- + +**Bare Metal**: +- Application calls ``tud_task()`` in main loop +- No threading primitives needed +- Simplest integration method + +**FreeRTOS**: +- USB task runs at high priority +- Semaphores used for synchronization +- Queue for inter-task communication + +**Other RTOS**: +- Similar patterns with RTOS-specific primitives +- OSAL layer abstracts RTOS differences + +Interrupt Handling +------------------ + +**Interrupt Service Routine**: +- Minimal processing in ISR +- Event capture and queuing only +- Quick return to avoid blocking + +**Deferred Processing**: +- All complex processing in task context +- Thread-safe access to data structures +- Application callbacks in known context + +Memory Usage Patterns +--------------------- + +**Flash Memory**: +- Core stack: 8-15KB depending on features +- Each class: 1-4KB additional +- Portable driver: 2-8KB depending on MCU + +**RAM Usage**: +- Core stack: 1-2KB +- Endpoint buffers: User configurable +- Class buffers: Depends on configuration diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst deleted file mode 100644 index fa0a874f5..000000000 --- a/docs/reference/configuration.rst +++ /dev/null @@ -1,307 +0,0 @@ -************* -Configuration -************* - -TinyUSB behavior is controlled through compile-time configuration in ``tusb_config.h``. This reference covers all available configuration options. - -Basic Configuration -=================== - -Required Settings ------------------ - -.. code-block:: c - - // Target MCU family - REQUIRED - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - - // OS abstraction layer - REQUIRED - #define CFG_TUSB_OS OPT_OS_NONE - - // Enable device or host stack - #define CFG_TUD_ENABLED 1 // Device stack - #define CFG_TUH_ENABLED 1 // Host stack - -Debug and Logging ------------------ - -.. code-block:: c - - // Debug level (0=off, 1=error, 2=warning, 3=info) - #define CFG_TUSB_DEBUG 2 - - // Memory alignment for buffers (usually 4) - #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) - -Device Stack Configuration -========================== - -Endpoint Configuration ----------------------- - -.. code-block:: c - - // Control endpoint buffer size - #define CFG_TUD_ENDPOINT0_SIZE 64 - - // Number of endpoints (excluding EP0) - #define CFG_TUD_ENDPOINT_MAX 16 - -Device Classes --------------- - -**CDC (Communication Device Class)**: - -.. code-block:: c - - #define CFG_TUD_CDC 1 // Number of CDC interfaces - #define CFG_TUD_CDC_EP_BUFSIZE 512 // CDC endpoint buffer size - #define CFG_TUD_CDC_RX_BUFSIZE 256 // CDC RX FIFO size - #define CFG_TUD_CDC_TX_BUFSIZE 256 // CDC TX FIFO size - -**HID (Human Interface Device)**: - -.. code-block:: c - - #define CFG_TUD_HID 1 // Number of HID interfaces - #define CFG_TUD_HID_EP_BUFSIZE 16 // HID endpoint buffer size - -**MSC (Mass Storage Class)**: - -.. code-block:: c - - #define CFG_TUD_MSC 1 // Number of MSC interfaces - #define CFG_TUD_MSC_EP_BUFSIZE 512 // MSC endpoint buffer size - -**Audio Class**: - -.. code-block:: c - - #define CFG_TUD_AUDIO 1 // Number of audio interfaces - #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN 220 - #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 - #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 - #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 - #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 2 - -**MIDI**: - -.. code-block:: c - - #define CFG_TUD_MIDI 1 // Number of MIDI interfaces - #define CFG_TUD_MIDI_RX_BUFSIZE 128 // MIDI RX buffer size - #define CFG_TUD_MIDI_TX_BUFSIZE 128 // MIDI TX buffer size - -**DFU (Device Firmware Update)**: - -.. code-block:: c - - #define CFG_TUD_DFU 1 // Enable DFU mode - #define CFG_TUD_DFU_XFER_BUFSIZE 512 // DFU transfer buffer size - -**Vendor Class**: - -.. code-block:: c - - #define CFG_TUD_VENDOR 1 // Number of vendor interfaces - #define CFG_TUD_VENDOR_EPSIZE 64 // Vendor endpoint size - #define CFG_TUD_VENDOR_RX_BUFSIZE 64 // RX buffer size (0 = no buffering) - #define CFG_TUD_VENDOR_TX_BUFSIZE 64 // TX buffer size (0 = no buffering) - -.. note:: - Unlike other classes, vendor class supports setting buffer sizes to 0 to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. - -Host Stack Configuration -======================== - -Port and Hub Configuration --------------------------- - -.. code-block:: c - - // Number of host root hub ports - #define CFG_TUH_HUB 1 - - // Number of connected devices (including hub) - #define CFG_TUH_DEVICE_MAX 5 - - // Control transfer buffer size - #define CFG_TUH_ENUMERATION_BUFSIZE 512 - -Host Classes ------------- - -**CDC Host**: - -.. code-block:: c - - #define CFG_TUH_CDC 2 // Number of CDC host instances - #define CFG_TUH_CDC_FTDI 1 // FTDI serial support - #define CFG_TUH_CDC_CP210X 1 // CP210x serial support - #define CFG_TUH_CDC_CH34X 1 // CH34x serial support - -**HID Host**: - -.. code-block:: c - - #define CFG_TUH_HID 4 // Number of HID instances - #define CFG_TUH_HID_EPIN_BUFSIZE 64 // HID endpoint buffer size - #define CFG_TUH_HID_EPOUT_BUFSIZE 64 - -**MSC Host**: - -.. code-block:: c - - #define CFG_TUH_MSC 1 // Number of MSC instances - #define CFG_TUH_MSC_MAXLUN 4 // Max LUNs per device - -Advanced Configuration -====================== - -Memory Management ------------------ - -.. code-block:: c - - // Enable stack protection - #define CFG_TUSB_DEBUG_PRINTF printf - - // Custom memory allocation (if needed) - #define CFG_TUSB_MEM_SECTION __attribute__((section(".usb_ram"))) - -RTOS Configuration ------------------- - -TinyUSB supports multiple operating systems through its OSAL (Operating System Abstraction Layer). Choose the appropriate configuration based on your target environment. - -**FreeRTOS Integration**: - -When using FreeRTOS, configure the task queue sizes to handle USB events efficiently: - -.. code-block:: c - - #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUD_TASK_QUEUE_SZ 16 // Device task queue size - #define CFG_TUH_TASK_QUEUE_SZ 16 // Host task queue size - -**RT-Thread Integration**: - -RT-Thread requires only the OS selection, as it uses the RTOS's built-in primitives: - -.. code-block:: c - - #define CFG_TUSB_OS OPT_OS_RTTHREAD - -Low Power Configuration ------------------------ - -.. code-block:: c - - // Enable remote wakeup - #define CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP 1 - - // Suspend/resume callbacks - // Implement tud_suspend_cb() and tud_resume_cb() - -MCU-Specific Options -==================== - -The ``CFG_TUSB_MCU`` option selects the target microcontroller family: - -.. code-block:: c - - // STM32 families - #define CFG_TUSB_MCU OPT_MCU_STM32F0 - #define CFG_TUSB_MCU OPT_MCU_STM32F1 - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_MCU OPT_MCU_STM32F7 - #define CFG_TUSB_MCU OPT_MCU_STM32H7 - - // NXP families - #define CFG_TUSB_MCU OPT_MCU_LPC18XX - #define CFG_TUSB_MCU OPT_MCU_LPC40XX - #define CFG_TUSB_MCU OPT_MCU_LPC43XX - #define CFG_TUSB_MCU OPT_MCU_KINETIS_KL - #define CFG_TUSB_MCU OPT_MCU_IMXRT - - // Other vendors - #define CFG_TUSB_MCU OPT_MCU_RP2040 - #define CFG_TUSB_MCU OPT_MCU_ESP32S2 - #define CFG_TUSB_MCU OPT_MCU_ESP32S3 - #define CFG_TUSB_MCU OPT_MCU_SAMD21 - #define CFG_TUSB_MCU OPT_MCU_SAMD51 - #define CFG_TUSB_MCU OPT_MCU_NRF5X - -Configuration Examples -====================== - -Minimal Device (CDC only) --------------------------- - -.. code-block:: c - - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_OS OPT_OS_NONE - #define CFG_TUSB_DEBUG 0 - - #define CFG_TUD_ENABLED 1 - #define CFG_TUD_ENDPOINT0_SIZE 64 - - #define CFG_TUD_CDC 1 - #define CFG_TUD_CDC_EP_BUFSIZE 512 - #define CFG_TUD_CDC_RX_BUFSIZE 512 - #define CFG_TUD_CDC_TX_BUFSIZE 512 - - // Disable other classes - #define CFG_TUD_HID 0 - #define CFG_TUD_MSC 0 - #define CFG_TUD_MIDI 0 - #define CFG_TUD_AUDIO 0 - #define CFG_TUD_VENDOR 0 - -Full-Featured Host ------------------- - -.. code-block:: c - - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUSB_DEBUG 2 - - #define CFG_TUH_ENABLED 1 - #define CFG_TUH_HUB 1 - #define CFG_TUH_DEVICE_MAX 8 - #define CFG_TUH_ENUMERATION_BUFSIZE 512 - - #define CFG_TUH_CDC 2 - #define CFG_TUH_HID 4 - #define CFG_TUH_MSC 2 - #define CFG_TUH_VENDOR 2 - -Validation -========== - -Use these checks to validate your configuration: - -.. code-block:: c - - // In your main.c, add compile-time checks - #if !defined(CFG_TUSB_MCU) || (CFG_TUSB_MCU == OPT_MCU_NONE) - #error "CFG_TUSB_MCU must be defined" - #endif - - #if CFG_TUD_ENABLED && !defined(CFG_TUD_ENDPOINT0_SIZE) - #error "CFG_TUD_ENDPOINT0_SIZE must be defined for device stack" - #endif - -Common Configuration Issues -=========================== - -1. **Endpoint buffer size too small**: Causes transfer failures -2. **Missing CFG_TUSB_MCU**: Build will fail -3. **Incorrect OS setting**: RTOS functions won't work properly -4. **Insufficient endpoint count**: Device enumeration will fail -5. **Buffer size mismatches**: Data corruption or transfer failures - -For configuration examples specific to your board, check ``examples/device/*/tusb_config.h``. \ No newline at end of file diff --git a/docs/reference/index.rst b/docs/reference/index.rst index cb35dd1b9..d3c96eeee 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -7,9 +7,8 @@ Complete reference documentation for TinyUSB APIs, configuration, and supported .. toctree:: :maxdepth: 2 - api/index - configuration - usb_classes + architecture + usb_concepts boards dependencies concurrency diff --git a/docs/reference/usb_classes.rst b/docs/reference/usb_classes.rst deleted file mode 100644 index 387587b48..000000000 --- a/docs/reference/usb_classes.rst +++ /dev/null @@ -1,287 +0,0 @@ -*********** -USB Classes -*********** - -TinyUSB supports multiple USB device and host classes. This reference describes the features, capabilities, and requirements for each class. - -Device Classes -============== - -CDC (Communication Device Class) --------------------------------- - -Implements USB CDC specification for serial communication. - -**Supported Features:** -- CDC-ACM (Abstract Control Model) for virtual serial ports -- Data terminal ready (DTR) and request to send (RTS) control lines -- Line coding configuration (baud rate, parity, stop bits) -- Break signal support - -**Configuration:** -- ``CFG_TUD_CDC``: Number of CDC interfaces (1-4) -- ``CFG_TUD_CDC_EP_BUFSIZE``: Endpoint buffer size (typically 512) -- ``CFG_TUD_CDC_RX_BUFSIZE``: Receive FIFO size -- ``CFG_TUD_CDC_TX_BUFSIZE``: Transmit FIFO size - -**Key Functions:** -- ``tud_cdc_available()``: Check bytes available to read -- ``tud_cdc_read()``: Read data from host -- ``tud_cdc_write()``: Write data to host -- ``tud_cdc_write_flush()``: Flush transmit buffer - -**Callbacks:** -- ``tud_cdc_line_coding_cb()``: Line coding changed -- ``tud_cdc_line_state_cb()``: DTR/RTS state changed - -HID (Human Interface Device) ----------------------------- - -Implements USB HID specification for input devices. - -**Supported Features:** -- Boot protocol (keyboard/mouse) -- Report protocol with custom descriptors -- Input, output, and feature reports -- Multiple HID interfaces - -**Configuration:** -- ``CFG_TUD_HID``: Number of HID interfaces -- ``CFG_TUD_HID_EP_BUFSIZE``: Endpoint buffer size - -**Key Functions:** -- ``tud_hid_ready()``: Check if ready to send report -- ``tud_hid_report()``: Send HID report -- ``tud_hid_keyboard_report()``: Send keyboard report -- ``tud_hid_mouse_report()``: Send mouse report - -**Callbacks:** -- ``tud_hid_descriptor_report_cb()``: Provide report descriptor -- ``tud_hid_get_report_cb()``: Handle get report request -- ``tud_hid_set_report_cb()``: Handle set report request - -MSC (Mass Storage Class) ------------------------- - -Implements USB mass storage for file systems. - -**Supported Features:** -- SCSI transparent command set -- Multiple logical units (LUNs) -- Read/write operations -- Inquiry and capacity commands - -**Configuration:** -- ``CFG_TUD_MSC``: Number of MSC interfaces -- ``CFG_TUD_MSC_EP_BUFSIZE``: Endpoint buffer size - -**Key Functions:** -- Storage operations handled via callbacks - -**Required Callbacks:** -- ``tud_msc_inquiry_cb()``: Device inquiry information -- ``tud_msc_test_unit_ready_cb()``: Test if LUN is ready -- ``tud_msc_capacity_cb()``: Get LUN capacity -- ``tud_msc_start_stop_cb()``: Start/stop LUN -- ``tud_msc_read10_cb()``: Read data from LUN -- ``tud_msc_write10_cb()``: Write data to LUN - -Audio Class ------------ - -Implements USB Audio Class 2.0 specification. - -**Supported Features:** -- Audio streaming (input/output) -- Multiple sampling rates -- Volume and mute controls -- Feedback endpoints for asynchronous mode - -**Configuration:** -- ``CFG_TUD_AUDIO``: Number of audio functions -- Multiple configuration options for channels, sample rates, bit depth - -**Key Functions:** -- ``tud_audio_read()``: Read audio data -- ``tud_audio_write()``: Write audio data -- ``tud_audio_clear_ep_out_ff()``: Clear output FIFO - -MIDI ----- - -Implements USB MIDI specification. - -**Supported Features:** -- MIDI 1.0 message format -- Multiple virtual MIDI cables -- Standard MIDI messages - -**Configuration:** -- ``CFG_TUD_MIDI``: Number of MIDI interfaces -- ``CFG_TUD_MIDI_RX_BUFSIZE``: Receive buffer size -- ``CFG_TUD_MIDI_TX_BUFSIZE``: Transmit buffer size - -**Key Functions:** -- ``tud_midi_available()``: Check available MIDI messages -- ``tud_midi_read()``: Read MIDI packet -- ``tud_midi_write()``: Send MIDI packet - -DFU (Device Firmware Update) ----------------------------- - -Implements USB DFU specification for firmware updates. - -**Supported Modes:** -- DFU Mode: Device enters DFU for firmware update -- DFU Runtime: Request transition to DFU mode - -**Configuration:** -- ``CFG_TUD_DFU``: Enable DFU mode -- ``CFG_TUD_DFU_RUNTIME``: Enable DFU runtime - -**Key Functions:** -- Firmware update operations handled via callbacks - -**Required Callbacks:** -- ``tud_dfu_download_cb()``: Receive firmware data -- ``tud_dfu_manifest_cb()``: Complete firmware update - -Vendor Class ------------- - -Custom vendor-specific USB class implementation. - -**Features:** -- Configurable endpoints -- Custom protocol implementation -- WebUSB support -- Microsoft OS descriptors - -**Configuration:** -- ``CFG_TUD_VENDOR``: Number of vendor interfaces -- ``CFG_TUD_VENDOR_EPSIZE``: Endpoint size - -**Key Functions:** -- ``tud_vendor_available()``: Check available data -- ``tud_vendor_read()``: Read vendor data -- ``tud_vendor_write()``: Write vendor data - -Host Classes -============ - -CDC Host --------- - -Connect to CDC devices (virtual serial ports). - -**Supported Devices:** -- CDC-ACM devices -- FTDI USB-to-serial converters -- CP210x USB-to-serial converters -- CH34x USB-to-serial converters - -**Configuration:** -- ``CFG_TUH_CDC``: Number of CDC host instances -- ``CFG_TUH_CDC_FTDI``: Enable FTDI support -- ``CFG_TUH_CDC_CP210X``: Enable CP210x support - -**Key Functions:** -- ``tuh_cdc_available()``: Check available data -- ``tuh_cdc_read()``: Read from CDC device -- ``tuh_cdc_write()``: Write to CDC device -- ``tuh_cdc_set_baudrate()``: Configure serial settings - -HID Host --------- - -Connect to HID devices (keyboards, mice, etc.). - -**Supported Devices:** -- Boot keyboards and mice -- Generic HID devices with report descriptors -- Composite HID devices - -**Configuration:** -- ``CFG_TUH_HID``: Number of HID host instances -- ``CFG_TUH_HID_EPIN_BUFSIZE``: Input endpoint buffer size - -**Key Functions:** -- ``tuh_hid_receive_report()``: Start receiving reports -- ``tuh_hid_send_report()``: Send report to device -- ``tuh_hid_parse_report_descriptor()``: Parse HID descriptors - -MSC Host --------- - -Connect to mass storage devices (USB drives). - -**Supported Features:** -- SCSI transparent command set -- FAT file system support (with FatFS integration) -- Multiple LUNs per device - -**Configuration:** -- ``CFG_TUH_MSC``: Number of MSC host instances -- ``CFG_TUH_MSC_MAXLUN``: Maximum LUNs per device - -**Key Functions:** -- ``tuh_msc_ready()``: Check if device is ready -- ``tuh_msc_read10()``: Read sectors from device -- ``tuh_msc_write10()``: Write sectors to device - -Hub ---- - -Support for USB hubs to connect multiple devices. - -**Features:** -- Multi-level hub support -- Port power management -- Device connect/disconnect detection - -**Configuration:** -- ``CFG_TUH_HUB``: Number of hub instances -- ``CFG_TUH_DEVICE_MAX``: Total connected devices - -Class Implementation Guidelines -=============================== - -Descriptor Requirements ------------------------ - -Each USB class requires specific descriptors: - -1. **Interface Descriptor**: Defines the class type -2. **Endpoint Descriptors**: Define communication endpoints -3. **Class-Specific Descriptors**: Additional class requirements -4. **String Descriptors**: Human-readable device information - -Callback Implementation ------------------------ - -Most classes require callback functions: - -- **Mandatory callbacks**: Must be implemented for class to function -- **Optional callbacks**: Provide additional functionality -- **Event callbacks**: Called when specific events occur - -Performance Considerations --------------------------- - -When implementing USB classes, match **buffer sizes** to expected data rates to avoid bottlenecks. Choose appropriate **transfer types** based on your application's requirements. Keep **callback processing** lightweight for optimal performance. Avoid **memory allocations in critical paths** where possible to maintain consistent performance. - -Testing and Validation ----------------------- - -- **USB-IF Compliance**: Ensure descriptors meet USB standards -- **Host Compatibility**: Test with multiple operating systems -- **Performance Testing**: Verify transfer rates and latency -- **Error Handling**: Test disconnect/reconnect scenarios - -Class-Specific Resources -======================== - -- **USB-IF Specifications**: Official USB class specifications -- **Example Code**: Reference implementations in ``examples/`` directory -- **Test Applications**: Host-side test applications for validation -- **Debugging Tools**: USB protocol analyzers and debugging utilities \ No newline at end of file diff --git a/docs/reference/usb_concepts.rst b/docs/reference/usb_concepts.rst new file mode 100644 index 000000000..86ae97007 --- /dev/null +++ b/docs/reference/usb_concepts.rst @@ -0,0 +1,428 @@ +************ +USB Concepts +************ + +This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. + +TinyUSB API Naming Conventions +=============================== + +TinyUSB uses consistent function prefixes to organize its API: + +* **tusb_**: Core stack functions (initialization, interrupt handling) +* **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) +* **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) +* **tu_**: Internal utility functions (generally not used by applications) + +This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. + +USB Protocol Basics +==================== + +Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. + +Host and Device Roles +---------------------- + +**USB Host**: The controlling side of a USB connection (typically a computer). The host: +- Initiates all communication +- Provides power to devices +- Manages the USB bus +- Enumerates and configures devices + +**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. + +**USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: +- Respond to host requests +- Cannot initiate communication +- Receive power from the host +- Must be enumerated by the host before use + +**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. + +**OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. + +USB Transfers +============= + +Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. +Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. + +USB defines four transfer types, each intended for different use cases: + +Control Transfers +----------------- + +Used for device configuration and control commands. + +**Characteristics**: +- Bidirectional (uses both IN and OUT) +- Guaranteed delivery with error detection +- Limited data size (8-64 bytes per packet) +- All devices must support control transfers on endpoint 0 + +**Usage**: Device enumeration, configuration changes, class-specific commands + +**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). + +Bulk Transfers +-------------- + +Used for large amounts of data that don't require guaranteed timing. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Large packet sizes (up to 512 bytes for High Speed) +- Uses available bandwidth when no other transfers are active + +**Usage**: File transfers, large data communication, CDC serial data + +**TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. + +Interrupt Transfers +------------------- + +Used for small, time-sensitive data with guaranteed maximum latency. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Small packet sizes (up to 64 bytes for Full Speed) +- Regular polling interval (1ms to 255ms) + +**Usage**: Keyboard/mouse input, sensor data, status updates + +**TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. + +Isochronous Transfers +--------------------- + +Used for time-critical streaming data. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- No error correction (speed over reliability) +- Guaranteed bandwidth +- Real-time delivery + +**Usage**: Audio, video streaming + +**TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. + +Endpoints and Addressing +========================= + +Endpoint Basics +--------------- + +**Endpoint**: A communication channel between host and device. + +- Each endpoint has a number (0-15) and direction +- Endpoint 0 is reserved for control transfers +- Other endpoints are assigned by device class requirements + +**TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. + +**Direction**: +- **OUT**: Host to device (host sends data out) +- **IN**: Device to host (host reads data in) +- Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). + +**Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) + +Endpoint Configuration +---------------------- + +Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. + +**TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. + +Error Handling and Flow Control +------------------------------- + +**Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. + +**Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. + +**TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. + +USB Device States +================= + +A USB device progresses through several states: + +1. **Attached**: Device is physically connected +2. **Powered**: Device receives power from host +3. **Default**: Device responds to address 0 +4. **Address**: Device has been assigned a unique address +5. **Configured**: Device is ready for normal operation +6. **Suspended**: Device is in low-power state + +**TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. + +Device Enumeration Process +========================== + +When a device is connected, the host follows this process: + +1. **Detection**: Host detects device connection +2. **Reset**: Host resets the device +3. **Descriptor Requests**: Host requests device descriptors +4. **Address Assignment**: Host assigns unique address to device +5. **Configuration**: Host selects and configures device +6. **Class Loading**: Host loads appropriate drivers +7. **Normal Operation**: Device is ready for use + +**TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. + +USB Descriptors +=============== + +Descriptors are data structures that describe device capabilities: + +Device Descriptor +----------------- +Describes the device (VID, PID, USB version, etc.) + +Configuration Descriptor +------------------------ +Describes device configuration (power requirements, interfaces, etc.) + +Interface Descriptor +-------------------- +Describes a functional interface (class, endpoints, etc.) + +Endpoint Descriptor +------------------- +Describes endpoint characteristics (type, direction, size, etc.) + +String Descriptors +------------------ +Human-readable strings (manufacturer, product name, etc.) + +**TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: +- ``tud_descriptor_device_cb()`` - Device descriptor +- ``tud_descriptor_configuration_cb()`` - Configuration descriptor +- ``tud_descriptor_string_cb()`` - String descriptors + +The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. + +USB Classes +=========== + +USB classes define standardized protocols for device types: + +**Class Code**: Identifies the device type in descriptors +**Class Driver**: Software that implements the class protocol +**Class Requests**: Standardized commands for the class + +**Common TinyUSB-Supported Classes**: +- **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` +- **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` +- **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` +- **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` +- **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` +- **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` +- **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` + +.. note:: + **Vendor Class Buffer Configuration**: Unlike other USB classes, the vendor class supports setting buffer sizes to 0 in ``tusb_config.h`` (``CFG_TUD_VENDOR_RX_BUFSIZE = 0``) to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. + +See ``examples/device/*/tusb_config.h`` for configuration examples. + +USB Speeds +========== + +USB supports multiple speed modes: + +**Low Speed (1.5 Mbps)**: +- Simple devices (mice, keyboards) +- Limited endpoint types and sizes + +**Full Speed (12 Mbps)**: +- Most common for embedded devices +- All transfer types supported +- Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) + +**High Speed (480 Mbps)**: +- High-performance devices +- Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) +- Requires more complex hardware + +**Super Speed (5 Gbps)**: +- USB 3.0 and later +- Not supported by TinyUSB + +**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. + +USB Controller Abstraction +=========================== + +USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. + +Controller Fundamentals +----------------------- + +**What Controllers Do**: +- Handle USB signaling and protocol timing +- Manage endpoint buffers and data transfers +- Generate interrupts for USB events +- Implement USB electrical specifications + +**Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. + +Controller Architecture Types +----------------------------- + +Different MCU vendors implement USB controllers with varying architectures. +To list a few common patterns: + +**FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): +- Shared or dedicated FIFOs for endpoint data +- Software manages FIFO allocation and data flow +- Common in higher-end MCUs with flexible configurations + +**Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): +- Fixed packet memory areas for each endpoint +- Hardware automatically handles packet placement +- Simpler programming model, common in smaller MCUs + +**Descriptor-Based Controllers** (e.g., NXP EHCI-style): +- Use descriptor chains to describe transfers +- Hardware processes transfer descriptors independently +- More complex but can handle larger transfers autonomously + +TinyUSB Controller Abstraction +------------------------------ + +TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. +These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. + +**Portable Interface** (``src/device/usbd.h``): +- Standardized function signatures for all controllers +- Common endpoint and transfer management APIs +- Unified interrupt and event handling + +**Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): +- Implement the DCD interface for specific hardware +- Handle vendor-specific register layouts and behaviors +- Manage controller-specific quirks and workarounds + +**Common DCD Functions**: +- ``dcd_init()`` - Initialize controller hardware +- ``dcd_edpt_open()`` - Configure endpoint with type and size +- ``dcd_edpt_xfer()`` - Start data transfer on endpoint +- ``dcd_int_handler()`` - Process USB interrupts +- ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection + +Host Controller Driver (HCD) +----------------------------- + +TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. + +**Portable Interface** (``src/host/usbh.h``): +- Standardized interface for all host controllers +- Common device enumeration and pipe management +- Unified transfer scheduling and completion handling + +**Common HCD Functions**: +- ``hcd_init()`` - Initialize host controller hardware +- ``hcd_port_connect_status()`` - Check device connection status +- ``hcd_port_reset()`` - Reset connected device +- ``hcd_edpt_open()`` - Open communication pipe to device endpoint +- ``hcd_edpt_xfer()`` - Transfer data to/from connected device + +**Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. + +TinyUSB Event System & Thread Safety +==================================== + +Deferred Interrupt Processing +----------------------------- + +**Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. + +**Event Flow**: + +1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) +2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue +3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events +4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks + +**Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. + +Controller Event Flow +--------------------- + +**Typical USB Event Processing**: + +1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) +2. **Interrupt Generation**: Controller generates interrupt to CPU +3. **ISR Processing**: ``dcd_int_handler()`` reads controller status +4. **Event Queuing**: Events are queued for later processing (thread safety) +5. **Task Processing**: ``tud_task()`` processes queued events +6. **Class Notification**: Appropriate class drivers handle the event +7. **Application Callback**: User code responds to the event + +USB Class Driver Architecture +============================== + +TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. + +Class Driver Pattern +--------------------- + +**Standardized Entry Points**: Each class driver implements these core functions: + +- ``*_init()`` - Initialize class driver state and buffers +- ``*_reset()`` - Reset to initial state on USB bus reset +- ``*_open()`` - Parse and configure interfaces during enumeration +- ``*_control_xfer_cb()`` - Handle class-specific control requests +- ``*_xfer_cb()`` - Handle transfer completion callbacks + +**Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: + +.. code-block:: c + + // Single instance (default instance 0) + tud_cdc_write(data, len); + + // Multiple instances + tud_cdc_n_write(0, data, len); // Instance 0 + tud_cdc_n_write(1, data, len); // Instance 1 + +**Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. + +Class Driver Types +------------------- + +TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. + +Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. + +The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. + +**Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. + +Power Management +================ + +USB provides power to devices: + +**Bus-Powered**: Device draws power from USB bus (up to 500mA) +**Self-Powered**: Device has its own power source +**Suspend/Resume**: Devices must enter low-power mode when bus is idle + +**TinyUSB Power Management**: +- Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management +- Configure power requirements in device descriptor (``bMaxPower`` field) +- Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) +- Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` + +Next Steps +========== + +- Start with :doc:`../getting_started` for basic setup +- Review ``examples/device/*/tusb_config.h`` for configuration examples +- Explore examples in ``examples/device/`` and ``examples/host/`` directories diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst deleted file mode 100644 index 35a9aa9bf..000000000 --- a/docs/tutorials/getting_started.rst +++ /dev/null @@ -1,356 +0,0 @@ -*************** -Getting Started -*************** - -This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. - -Add TinyUSB to your project ---------------------------- - -To incorporate TinyUSB into your project: - -* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` -* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project -* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. -* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. -* If you're using the device stack, ensure you have created or modified USB descriptors to meet your specific requirements. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. -* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. -* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler -* Implement all enabled classes' callbacks. -* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions continuously or periodically. These task functions handle all callbacks and core functionality. - -.. note:: - TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. - -.. code-block:: c - - int main(void) { - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(0, &dev_init); // initialize device stack on roothub port 0 - - tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_HOST, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(1, &host_init); // initialize host stack on roothub port 1 - - while(1) { // the mainloop - your_application_code(); - tud_task(); // device task - tuh_task(); // host task - } - } - - void USB0_IRQHandler(void) { - tusb_int_handler(0, true); - } - - void USB1_IRQHandler(void) { - tusb_int_handler(1, true); - } - -Examples --------- - -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already - -.. code-block:: bash - - $ git clone https://github.com/hathach/tinyusb tinyusb - $ cd tinyusb - -Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. - -Dependencies -^^^^^^^^^^^^ - -TinyUSB separates example applications from board-specific hardware configurations. Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while Board Support Package (BSP) configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. - -Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: - -1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. - -.. code-block:: bash - - $ python tools/get_deps.py rp2040 - -2. Or run the ``get-deps`` target in one of the example folders as follows. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=feather_nrf52840_express get-deps - -You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` - -Build Examples -^^^^^^^^^^^^^^ - -Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - -Then compile with make or cmake - -.. code-block:: bash - - $ # make - $ make BOARD=feather_nrf52840_express all - - $ # cmake - $ mkdir build && cd build - $ cmake -DBOARD=raspberry_pi_pico .. - $ make - -To list all available targets with cmake - -.. code-block:: bash - - $ cmake --build . --target help - -Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient - -.. code-block:: bash - - $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ - $ sudo udevadm control --reload-rules && sudo udevadm trigger - -RootHub Port Selection -~~~~~~~~~~~~~~~~~~~~~~ - -If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. - -Port Speed -~~~~~~~~~~ - -An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. - -Size Analysis -~~~~~~~~~~~~~ - -First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap - -Flashing the Device -^^^^^^^^^^^^^^^^^^^ - -The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash - $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash - -Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash-jlink - $ make BOARD=feather_nrf52840_express flash-openocd - - $ cmake --build . --target cdc_msc-jlink - $ cmake --build . --target cdc_msc-openocd - -Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express all uf2 - - $ cmake --build . --target cdc_msc-uf2 - -Debugging -^^^^^^^^^ - -To compile for debugging add ``DEBUG=1``\ , for example - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express DEBUG=1 all - - $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. - -Enable Logging -~~~~~~~~~~~~~~ - -If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. - -Logging Performance Impact -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: - - -* `LOGGER=rtt`: use `Segger RTT protocol `_ - - * Cons: requires jlink as the debugger. - * Pros: work with most if not all MCUs - * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. - -* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. - - * Cons: Only works with ARM Cortex MCUs except M0 - * Pros: should be compatible with more debugger that support SWO. - * Software viewer should be provided along with your debugger driver. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. - -IAR Support -^^^^^^^^^^^ - -IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. - -Use project connection -~~~~~~~~~~~~~~~~~~~~~~ - -IAR Project Connection files are provided to import TinyUSB stack into your project. - -* A buildable project for your MCU needs to be created in advance. - - * Take example of STM32F0: - - - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. - - - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. - -* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) - Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, - for example ``C:\\tinyusb`` - -**Import stack only** - -Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. - -**Run examples** - -1. Run ``iar_gen.py`` to generate .ipcf files of examples: - - .. code-block:: - - > cd C:\tinyusb\tools - > python iar_gen.py - -2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. - For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` - -Native CMake support -~~~~~~~~~~~~~~~~~~~~ - -With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. - -Following these steps: - -1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. -2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. -3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. -4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. - -Common Issues and Solutions ---------------------------- - -**Build Errors** - -* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` -* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` -* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board - -**Runtime Issues** - -* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings -* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors -* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation - -Quick Start Examples --------------------- - -Now that you have TinyUSB set up, you can try these examples to see it in action. - -Simple Device Example -^^^^^^^^^^^^^^^^^^^^^ - -The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. - -**What it does:** -* Appears as a serial port that echoes back any text you send -* Appears as a small USB drive with a README.TXT file -* Blinks an LED to show activity - -**Build and run:** - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tud_task()`` loop -* ``src/usb_descriptors.c`` - USB device descriptors -* ``src/msc_disk.c`` - Mass storage implementation - -**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. - -Simple Host Example -^^^^^^^^^^^^^^^^^^^ - -The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. - -**What it does:** -* Detects and enumerates connected USB devices -* Communicates with CDC devices (like USB-to-serial adapters) -* Reads from MSC devices (like USB drives) -* Receives input from HID devices (like keyboards and mice) - -**Build and run:** - -.. code-block:: bash - - $ cd examples/host/cdc_msc_hid - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tuh_task()`` loop -* ``src/cdc_app.c`` - CDC host functionality -* ``src/msc_app.c`` - Mass storage host functionality -* ``src/hid_app.c`` - HID host functionality - -**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. - -Next Steps -^^^^^^^^^^ - -* Check :doc:`../reference/boards` for board-specific information -* Explore more :doc:`../examples` for advanced use cases diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst deleted file mode 100644 index dc362d717..000000000 --- a/docs/tutorials/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -********* -Tutorials -********* - -Step-by-step learning guides for TinyUSB development. - -.. toctree:: - :maxdepth: 2 - - getting_started \ No newline at end of file -- cgit v1.3.1 From 1f908d88ce4ba76d15d5b961a293327961deb7f9 Mon Sep 17 00:00:00 2001 From: c1570 Date: Sat, 27 Sep 2025 00:39:29 +0200 Subject: getting_started structure --- docs/getting_started.rst | 7 ++++--- 1 file changed, 4 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 5e8ebd040..85f1f8a04 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -63,13 +63,14 @@ For your convenience, TinyUSB contains a handful of examples for both host and d $ git clone https://github.com/hathach/tinyusb tinyusb $ cd tinyusb -Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. +TinyUSB separates example applications from board-specific hardware configurations (Board Support Packages, BSP). The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. + +* Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories. +* BSP configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. Dependencies ^^^^^^^^^^^^ -TinyUSB separates example applications from board-specific hardware configurations (Board Support Packages, BSP). Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while BSP configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. - Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: 1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. -- cgit v1.3.1 From fa599e3ff4c41c471cd6db92fd924f95485942cd Mon Sep 17 00:00:00 2001 From: c1570 Date: Sun, 28 Sep 2025 00:40:29 +0200 Subject: streamlined getting_started --- docs/getting_started.rst | 365 ++++++++++++----------------------------------- 1 file changed, 95 insertions(+), 270 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 85f1f8a04..84663e486 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -2,285 +2,157 @@ Getting Started *************** -This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. +This guide will get you up and running with TinyUSB quickly. We'll start with working examples, then show you how to integrate TinyUSB into your own projects. -Add TinyUSB to your project ---------------------------- - -To incorporate TinyUSB into your project: - -* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` -* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project -* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. -* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. -* If you're using the **device stack**, you need to implement all **tud descriptor** callbacks for the stack to work. -* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. -* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler -* Implement all enabled classes' callbacks. -* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions periodically. These task functions handle all callbacks and core functionality. - -.. note:: - TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. - -.. code-block:: c - - int main(void) { - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - // tud descriptor omitted here - tusb_init(0, &dev_init); // initialize device stack on roothub port 0 +Quick Start Examples +==================== - tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_HOST, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(1, &host_init); // initialize host stack on roothub port 1 +The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. We'll assume you are using the stm32f407disco board. - while(1) { // the mainloop - your_application_code(); - tud_task(); // device task - tuh_task(); // host task - } - } +Simple Device Example +--------------------- - void USB0_IRQHandler(void) { - tusb_int_handler(0, true); - } +The `cdc_msc `_ example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). - void USB1_IRQHandler(void) { - tusb_int_handler(1, true); - } - -Examples --------- +**What it does:** +* Appears as a serial port that echoes back any text you send +* Appears as a small USB drive with a README.TXT file +* Blinks an LED to show activity -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already +**Build and run:** .. code-block:: bash $ git clone https://github.com/hathach/tinyusb tinyusb $ cd tinyusb - -TinyUSB separates example applications from board-specific hardware configurations (Board Support Packages, BSP). The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. - -* Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories. -* BSP configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. - -Dependencies -^^^^^^^^^^^^ - -Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: - -1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. - -.. code-block:: bash - - $ python tools/get_deps.py rp2040 - -2. Or run the ``get-deps`` target in one of the example folders as follows. - -.. code-block:: bash - + $ python tools/get_deps.py stm32f4 # Download dependencies $ cd examples/device/cdc_msc - $ make BOARD=feather_nrf52840_express get-deps - -You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` - -Build Examples -^^^^^^^^^^^^^^ + $ make BOARD=stm32f407disco all flash -Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. - -.. code-block:: bash +Connect to your computer and you'll see both a new serial port and a small USB drive appear. - $ cd examples/device/cdc_msc - -Then compile with make or cmake - -.. code-block:: bash - - $ # make - $ make BOARD=feather_nrf52840_express all - - $ # cmake - $ mkdir build && cd build - $ cmake -DBOARD=raspberry_pi_pico .. - $ make - -To list all available targets with cmake +Simple Host Example +------------------- -.. code-block:: bash +The `cdc_msc_hid `_ example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. - $ cmake --build . --target help +**What it does:** +* Detects and enumerates connected USB devices +* Communicates with CDC devices (like USB-to-serial adapters) +* Reads from MSC devices (like USB drives) +* Receives input from HID devices (like keyboards and mice) -Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient +**Build and run:** .. code-block:: bash - $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ - $ sudo udevadm control --reload-rules && sudo udevadm trigger + $ python tools/get_deps.py stm32f4 # If not done already + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32f407disco all flash -RootHub Port Selection -~~~~~~~~~~~~~~~~~~~~~~ +Connect USB devices to see enumeration messages and device-specific interactions in the serial output. -If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: +Project Structure +----------------- -.. code-block:: bash +TinyUSB separates example applications from board-specific hardware configurations: - $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all +* **Example applications**: Located in `examples/device/ `_, `examples/host/ `_, and `examples/dual/ `_ directories +* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. +For example, raspberry_pi_pico is located in `hw/bsp/rp2040/boards/raspberry_pi_pico `_ where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build with ``BOARD=raspberry_pi_pico``, the build system automatically finds the corresponding BSP using the FAMILY. -Port Speed -~~~~~~~~~~ +Add TinyUSB to Your Project +============================ -An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: +Once you've seen TinyUSB working, here's how to integrate it into your own project: -.. code-block:: bash +Integration Steps +----------------- - $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all +1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb`` - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. +2. **Add source files**: Add all ``.c`` files from ``tinyusb/src/`` to your project -Size Analysis -~~~~~~~~~~~~~ +3. **Configure include paths**: Add ``your_project/tinyusb/src`` to your include path. Ensure your include path contains ``tusb_config.h`` -First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. +4. **Configure TinyUSB**: Create ``tusb_config.h`` with required macros like ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. Copy from ``examples/device/*/tusb_config.h`` as a starting point -.. code-block:: bash +5. **Implement USB descriptors**: For device stack, implement all ``tud_descriptor_*_cb()`` callbacks - $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap +6. **Initialize TinyUSB**: Add ``tusb_init()`` to your initialization code -Flashing the Device -^^^^^^^^^^^^^^^^^^^ +7. **Handle interrupts**: Call ``tusb_int_handler()`` from your USB IRQ handler -The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command +8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) periodically in your main loop -.. code-block:: bash +9. **Implement class callbacks**: Implement callbacks for enabled USB classes - $ make BOARD=feather_nrf52840_express flash - $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash +Simple Integration Example +-------------------------- -Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. +.. code-block:: c -.. code-block:: bash + #include "tusb.h" - $ make BOARD=feather_nrf52840_express flash-jlink - $ make BOARD=feather_nrf52840_express flash-openocd + int main(void) { + board_init(); // Your board initialization - $ cmake --build . --target cdc_msc-jlink - $ cmake --build . --target cdc_msc-openocd + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_AUTO + }; + // tud_descriptor_* callbacks omitted here + tusb_init(0, &dev_init); -Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target + while(1) { + tud_task(); // TinyUSB device task + your_application(); // Your application code + } + } -.. code-block:: bash + void USB_IRQHandler(void) { + tusb_int_handler(0, true); + } - $ make BOARD=feather_nrf52840_express all uf2 +.. note:: + Unlike many libraries, TinyUSB callbacks don't need to be explicitly registered. The stack automatically calls functions with specific names (e.g., ``tud_cdc_rx_cb()``) when events occur. Simply implement the callbacks you need. - $ cmake --build . --target cdc_msc-uf2 +.. note:: + TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`reference/glossary` for more details. -Debugging -^^^^^^^^^ +Development Tips +================ -To compile for debugging add ``DEBUG=1``\ , for example +**Debug builds and logging:** .. code-block:: bash - $ make BOARD=feather_nrf52840_express DEBUG=1 all - - $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. + $ make BOARD=stm32f407disco DEBUG=1 all # Debug build + $ make BOARD=stm32f407disco LOG=2 all # Enable detailed logging -Enable Logging -~~~~~~~~~~~~~~ - -If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. +**CMake build system:** .. code-block:: bash - $ make BOARD=feather_nrf52840_express LOG=2 all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. - -Logging Performance Impact -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: - - -* `LOGGER=rtt`: use `Segger RTT protocol `_ - - * Cons: requires jlink as the debugger. - * Pros: work with most if not all MCUs - * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. - -* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. + $ mkdir build && cd build + $ cmake -DBOARD=stm32f407disco .. + $ make - * Cons: Only works with ARM Cortex MCUs except M0 - * Pros: should be compatible with more debugger that support SWO. - * Software viewer should be provided along with your debugger driver. +**Alternative flash methods:** .. code-block:: bash - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. - -IAR Support -^^^^^^^^^^^ - -IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. - -Use project connection -~~~~~~~~~~~~~~~~~~~~~~ - -IAR Project Connection files are provided to import TinyUSB stack into your project. - -* A buildable project for your MCU needs to be created in advance. - - * Take example of STM32F0: - - - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. - - - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. - -* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) - Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, - for example ``C:\\tinyusb`` - -**Import stack only** - -Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. - -**Run examples** - -1. Run ``iar_gen.py`` to generate .ipcf files of examples: - - .. code-block:: - - > cd C:\tinyusb\tools - > python iar_gen.py - -2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. - For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` + $ make BOARD=stm32f407disco flash-jlink # Use J-Link + $ make BOARD=stm32f407disco flash-openocd # Use OpenOCD + $ make BOARD=stm32f407disco all uf2 # Generate UF2 for drag-and-drop -Native CMake support -~~~~~~~~~~~~~~~~~~~~ +**IAR Embedded Workbench:** -With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. - -Following these steps: - -1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. -2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. -3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. -4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. +For IAR users, project connection files are available. Import `tools/iar_template.ipcf `_ or use native CMake support (IAR 9.50.1+). See `tools/iar_gen.py `_ for automated project generation. Common Issues and Solutions ---------------------------- +=========================== **Build Errors** @@ -294,65 +166,18 @@ Common Issues and Solutions * **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors * **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation -Quick Start Examples --------------------- - -Now that you have TinyUSB set up, you can try these examples to see it in action. - -Simple Device Example -^^^^^^^^^^^^^^^^^^^^^ - -The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. - -**What it does:** -* Appears as a serial port that echoes back any text you send -* Appears as a small USB drive with a README.TXT file -* Blinks an LED to show activity - -**Build and run:** - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tud_task()`` loop -* ``src/usb_descriptors.c`` - USB device descriptors -* ``src/msc_disk.c`` - Mass storage implementation - -**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. - -Simple Host Example -^^^^^^^^^^^^^^^^^^^ +**Linux Permissions** -The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. - -**What it does:** -* Detects and enumerates connected USB devices -* Communicates with CDC devices (like USB-to-serial adapters) -* Reads from MSC devices (like USB drives) -* Receives input from HID devices (like keyboards and mice) - -**Build and run:** +Some examples require udev permissions to access USB devices: .. code-block:: bash - $ cd examples/host/cdc_msc_hid - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tuh_task()`` loop -* ``src/cdc_app.c`` - CDC host functionality -* ``src/msc_app.c`` - Mass storage host functionality -* ``src/hid_app.c`` - HID host functionality - -**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. + $ cp `examples/device/99-tinyusb.rules `_ /etc/udev/rules.d/ + $ sudo udevadm control --reload-rules && sudo udevadm trigger Next Steps -^^^^^^^^^^ +========== * Check :doc:`reference/boards` for board-specific information -* Explore more examples in ``examples/device/`` and ``examples/host/`` directories +* Explore more examples in `examples/device/ `_ and `examples/host/ `_ directories +* Read :doc:`reference/usb_concepts` to understand USB fundamentals -- cgit v1.3.1 From 9dd67b19e207edd17917296a5c7c185c86507fa8 Mon Sep 17 00:00:00 2001 From: c1570 Date: Mon, 20 Oct 2025 20:19:40 +0200 Subject: revert unnecessary Sphinx config changes --- docs/conf.py | 20 -------------------- 1 file changed, 20 deletions(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index be9aeaaf9..4249d41f7 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -24,29 +24,9 @@ extensions = [ 'sphinx.ext.autodoc', 'sphinx.ext.intersphinx', 'sphinx.ext.todo', - 'sphinx.ext.viewcode', - 'sphinx.ext.napoleon', 'sphinx_autodoc_typehints', ] -# Autodoc configuration -autodoc_default_options = { - 'members': True, - 'undoc-members': True, - 'show-inheritance': True, -} - -# Napoleon configuration for Google/NumPy style docstrings -napoleon_google_docstring = True -napoleon_numpy_docstring = True -napoleon_include_init_with_doc = False -napoleon_include_private_with_doc = False - -# Intersphinx mapping for cross-references -intersphinx_mapping = { - 'python': ('https://docs.python.org/3', None), -} - templates_path = ['_templates'] exclude_patterns = ['_build'] -- cgit v1.3.1 From 418239a2165551201ace6ddb49ce327c825e2607 Mon Sep 17 00:00:00 2001 From: c1570 Date: Mon, 20 Oct 2025 20:38:05 +0200 Subject: add missing class driver callbacks --- docs/reference/architecture.rst | 6 +++++- 1 file changed, 5 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst index ab451a91a..8e4c6890e 100644 --- a/docs/reference/architecture.rst +++ b/docs/reference/architecture.rst @@ -199,6 +199,8 @@ All USB classes follow a similar architecture: Class Driver Interface ---------------------- +See ``usbd.c``. + **Required Functions**: - ``init()``: Initialize class driver - ``reset()``: Reset class state @@ -208,7 +210,9 @@ Class Driver Interface **Optional Functions**: - ``close()``: Clean up class resources -- ``sof_cb()``: Start-of-frame processing +- ``deinit()``: Deinitialize class driver +- ``sof()``: Start-of-frame processing +- ``xfer_isr()``: Called from USB ISR context on transfer completion. Data will get queued for ``xfer_cb()`` only if this returns ``false``. Descriptor Management --------------------- -- cgit v1.3.1 From 3cb248f2e59dade48e724946883a6f67de3680e4 Mon Sep 17 00:00:00 2001 From: c1570 Date: Mon, 20 Oct 2025 20:56:29 +0200 Subject: add note about CMake --- docs/getting_started.rst | 10 +++++++--- 1 file changed, 7 insertions(+), 3 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 84663e486..a3d36a55c 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -7,7 +7,9 @@ This guide will get you up and running with TinyUSB quickly. We'll start with wo Quick Start Examples ==================== -The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. We'll assume you are using the stm32f407disco board. +The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. + +We'll assume you are using the stm32f407disco board. For other boards, see ``Board Support Packages`` below. Simple Device Example --------------------- @@ -27,7 +29,7 @@ The `cdc_msc Date: Tue, 21 Oct 2025 14:09:00 +0200 Subject: use CMake in getting_started examples --- docs/getting_started.rst | 34 +++++++++------------------------- 1 file changed, 9 insertions(+), 25 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index a3d36a55c..32c80b91c 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -27,11 +27,12 @@ The `cdc_msc Date: Tue, 11 Nov 2025 10:27:47 +0700 Subject: update doc --- .github/workflows/static_analysis.yml | 9 +- README.rst | 56 ++++++-- docs/_static/custom.css | 3 + docs/conf.py | 8 +- docs/contributing/code_of_conduct.rst | 1 - docs/contributing/index.rst | 22 --- docs/contributing/porting.rst | 243 ---------------------------------- docs/faq.rst | 32 +---- docs/getting_started.rst | 159 ++++++++++++---------- docs/index.rst | 37 +----- docs/info/changelog.rst | 48 +++++++ docs/info/code_of_conduct.rst | 1 + docs/info/index.rst | 1 + docs/integration.rst | 93 +++++++++++++ docs/porting.rst | 243 ++++++++++++++++++++++++++++++++++ docs/reference/architecture.rst | 39 ++---- docs/reference/boards.rst | 31 +++-- docs/reference/dependencies.rst | 12 +- docs/reference/glossary.rst | 2 +- docs/troubleshooting.rst | 43 ++++-- hw/bsp/family_support.cmake | 49 +++++-- tools/gen_doc.py | 2 +- 22 files changed, 640 insertions(+), 494 deletions(-) create mode 100644 docs/_static/custom.css delete mode 100644 docs/contributing/code_of_conduct.rst delete mode 100644 docs/contributing/index.rst delete mode 100644 docs/contributing/porting.rst create mode 100644 docs/info/code_of_conduct.rst create mode 100644 docs/integration.rst create mode 100644 docs/porting.rst (limited to 'docs') diff --git a/.github/workflows/static_analysis.yml b/.github/workflows/static_analysis.yml index a89cdc279..4db267517 100644 --- a/.github/workflows/static_analysis.yml +++ b/.github/workflows/static_analysis.yml @@ -90,7 +90,8 @@ jobs: path: ${{ steps.analyze.outputs.sarif-output }} PVS-Studio: - if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest strategy: fail-fast: false @@ -141,7 +142,8 @@ jobs: path: pvs-studio-${{ matrix.board }}.sarif SonarQube: - if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false runs-on: ubuntu-latest env: BUILD_WRAPPER_OUT_DIR: build_wrapper_output_directory @@ -184,7 +186,8 @@ jobs: --define sonar.cfamily.compile-commands=${{ env.BUILD_WRAPPER_OUT_DIR }}/compile_commands.json IAR-CStat: - #if: github.repository_owner == 'hathach' + # Only run on non-forked PR since secrets token is required + #if: github.repository_owner == 'hathach' && github.event.pull_request.head.repo.fork == false if: false runs-on: ubuntu-latest strategy: diff --git a/README.rst b/README.rst index 2d84a2f6c..d0586f55a 100644 --- a/README.rst +++ b/README.rst @@ -1,26 +1,55 @@ +TinyUSB +======= + |Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |License| Sponsors -======== +-------- TinyUSB is funded by: Adafruit. Purchasing products from them helps to support this project. .. figure:: docs/assets/adafruit_logo.svg :alt: Adafruit Logo + :align: left :target: https://www.adafruit.com -TinyUSB Project -=============== +.. raw:: html + +
+ +Overview +-------- .. figure:: docs/assets/logo.svg :alt: TinyUSB + :align: left + +.. raw:: html + +
+ +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems. It’s designed for memory safety +(no dynamic allocation) and thread safety (all interrupts deferred to non-ISR task functions). The stack emphasizes portability, +small footprint, and real-time performance across 50+ MCU families. -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function. Check out the online `documentation `__ for more details. +Key Features +------------ + +* **Thread-safe:** USB interrupts deferred to task context +* **Memory-safe:** No dynamic allocation, all buffers static +* **Portable:** Supports 50+ MCU families +* **Comprehensive:** Includes CDC, HID, MSC, Audio, and Host support +* **RTOS-friendly:** Works with bare metal, FreeRTOS, RT-Thread, and Mynewt .. figure:: docs/assets/stack.svg :width: 500px + :align: left :alt: stackup +.. raw:: html + +
+ :: . @@ -36,7 +65,7 @@ TinyUSB is an open-source cross-platform USB Host/Device stack for embedded syst Getting started -=============== +--------------- See the `online documentation `_ for information about using TinyUSB and how it is implemented. @@ -49,7 +78,7 @@ For bugs and feature requests, please `raise an issue `_ Host Stack -========== +---------- - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) @@ -81,14 +110,14 @@ Host Stack Similar to the Device Stack, if you have a special requirement, ``usbh_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack. Power Delivery Stack -==================== +-------------------- - Power Delivery 3.0 (PD3.0) with USB Type-C support (WIP) - Super early stage, only for testing purpose - Only support STM32 G4 OS Abstraction layer -==================== +-------------------- TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) events into a central queue, then processing them later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as Communication Device Class (CDC) FIFO. Therefore the stack needs to use some of the OS's basic APIs. Following OSes are already supported out of the box. @@ -98,7 +127,7 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) - **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo `_ Supported CPUs -============== +-------------- +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ | Manufacturer | Family | Device | Host | Highspeed | Driver | Note | @@ -234,7 +263,7 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ Table Legend ------------- +^^^^^^^^^^^^ ========= ========================= ✔ Supported @@ -244,7 +273,7 @@ Table Legend ========= ========================= Development Tools -================= +----------------- The following tools are provided freely to support the development of the TinyUSB project: @@ -273,6 +302,5 @@ The following tools are provided freely to support the development of the TinyUS .. _Supported Boards: docs/reference/boards.rst .. _Dependencies: docs/reference/dependencies.rst .. _Concurrency: docs/reference/concurrency.rst -.. _Contributing: docs/contributing/index.rst .. _Code of Conduct: CODE_OF_CONDUCT.rst -.. _Porting: docs/contributing/porting.rst +.. _Porting: docs/porting.rst diff --git a/docs/_static/custom.css b/docs/_static/custom.css new file mode 100644 index 000000000..d64d26047 --- /dev/null +++ b/docs/_static/custom.css @@ -0,0 +1,3 @@ +.clear-both { + clear: both; +} diff --git a/docs/conf.py b/docs/conf.py index 4249d41f7..cd0338413 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -14,7 +14,7 @@ from pathlib import Path # -- Project information ----------------------------------------------------- project = 'TinyUSB' -copyright = '2024, Ha Thach' +copyright = '2025, Ha Thach' author = 'Ha Thach' @@ -41,6 +41,8 @@ html_favicon = 'assets/logo.svg' html_theme_options = { 'sidebar_hide_name': True, } +html_static_path = ['_static'] +html_css_files = ['custom.css'] todo_include_todos = True @@ -52,7 +54,9 @@ def preprocess_readme(): if src.exists(): content = src.read_text() content = re.sub(r"docs/", r"", content) - content = re.sub(r".rst", r".html", content) + content = re.sub(r"\.rst\b", r".html", content) + if not content.endswith("\n"): + content += "\n" tgt.write_text(content) preprocess_readme() diff --git a/docs/contributing/code_of_conduct.rst b/docs/contributing/code_of_conduct.rst deleted file mode 100644 index fb1859c75..000000000 --- a/docs/contributing/code_of_conduct.rst +++ /dev/null @@ -1 +0,0 @@ -.. include:: ../../CODE_OF_CONDUCT.rst \ No newline at end of file diff --git a/docs/contributing/index.rst b/docs/contributing/index.rst deleted file mode 100644 index 78933a3ca..000000000 --- a/docs/contributing/index.rst +++ /dev/null @@ -1,22 +0,0 @@ -************ -Contributing -************ - -Contributing can be highly rewarding, but it can also be frustrating at times. -It takes time to review patches, and as this is an open source project, that -sometimes can take a while. The reviewing process depends on the availability -of the maintainers, who may not be always available. Please try to be -understanding through the process. - -There a few guidelines you need to keep in mind when contributing. Please have -a look at them as that will make the contribution process easier for all -parties. - -Index -===== - -.. toctree:: - :maxdepth: 2 - - code_of_conduct - porting diff --git a/docs/contributing/porting.rst b/docs/contributing/porting.rst deleted file mode 100644 index c3076354c..000000000 --- a/docs/contributing/porting.rst +++ /dev/null @@ -1,243 +0,0 @@ - -******* -Porting -******* - -TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It -handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for -data transactions on different endpoints. Porting is the process of adding low-level support for -the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support -for the microcontroller to other projects, especially those already using TinyUSB such as CircuitPython. - -Below are instructions on how to get the cdc_msc device example running on a new microcontroller. Doing so includes adding the common code necessary for other uses while minimizing other extra code. Whenever you see a phrase or word in ``<>`` it should be replaced. - -Register defs -------------- - -The first step to adding support is including the register definitions and startup code for the -microcontroller in TinyUSB. We write the TinyUSB implementation against these structs instead of higher level functions to keep the code small and to prevent function name collisions in linking of larger projects. For ARM microcontrollers this is the CMSIS definitions. They should be -placed in the ``hw/mcu//`` directory. - -Once this is done, create a directory in ``hw/bsp/`` for the specific board you are using to test the code (duplicating an existing board's directory is the best way to get started). The board should be a readily available development board so that others can also test. - -Build ------ - -Now that those directories are in place, we can start our iteration process to get the example building successfully. To build, run from the root of TinyUSB: - -.. code-block:: bash - - make -C examples/device/cdc_msc BOARD= - -Unless you've read ahead, this will fail miserably. Now, lets get it to fail less by updating the files in the board directory. The code in the board's directory is responsible for setting up the microcontroller's clocks and pins so that USB works. TinyUSB itself only operates on the USB peripheral. The board directory also includes information what files are needed to build the example. - -One of the first things to change is the ``-DCFG_TUSB_MCU`` C flag in the ``board.mk`` file. This is used to tell TinyUSB what platform is being built. So, add an entry to ``src/tusb_option.h`` and update the ``CFLAGS`` to match. - -Update ``board.mk``'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from ``src/portable`` into ``src/portable//`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. - -Implementation --------------- - -At this point you should get an error due to an implementation issue and hopefully the build is setup for the new MCU. You will still need to modify the ``board.mk`` to include specific ``CFLAGS``, the linker script, linker flags, source files, include directories. All file paths are relative to the top of the TinyUSB repo. - -Board Support (BSP) -^^^^^^^^^^^^^^^^^^^ - -The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. Its responsible for getting the MCU started and the USB peripheral clocked. It also optionally provides LED definitions that are used to blink an LED to show that the code is running. - -It is located in ``hw/bsp//board_.c``. - -``board_init()`` -~~~~~~~~~~~~~~~~ - -``board_init()`` is responsible for starting the MCU, setting up the USB clock and USB pins. It is also responsible for initializing LED pins. - -One useful clock debugging technique is to set up a PWM output at a known value such as 500hz based on the USB clock so that you can verify it is correct with a logic probe or oscilloscope. - -Setup your USB in a crystal-less mode when available. That makes the code easier to port across boards. - -``board_led_write()`` -~~~~~~~~~~~~~~~~~~~~~ - -Feel free to skip this until you want to verify your demo code is running. To implement, set the pin corresponding to the led to output a value that lights the LED when ``state`` is true. - -OS Abstraction Layer (OSAL) -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -The OS Abstraction Layer is responsible for providing basic data structures for TinyUSB that may allow for concurrency when used with an RTOS. Without an RTOS it simply handles concurrency issues between the main code and interrupts. The code is almost entirely agnostic of MCU and lives in ``src/osal``. - -In RTOS configurations, ``tud_task()``/``tuh_task()`` blocks behind a synchronization structure when the event queue is empty, so that the scheduler may give the CPU to a different task. To take advantage of the library's capability to yield the CPU when there are no actionable USB device events, ensure that the ``CFG_TUSB_OS`` symbol is defined, e.g ``OPT_OS_FREERTOS`` enables the FreeRTOS scheduler to schedule other threads than that which calls ``tud_task()``/``tuh_task()``. - -Device API -^^^^^^^^^^ - -After the USB device is setup, the USB device code works by processing events on the main thread (by calling ``tud_task()``). These events are queued by the USB interrupt handler. So, there are three parts to the device low-level API: device setup, endpoint setup and interrupt processing. - -All of the code for the low-level device API is in ``src/portable///dcd_.c``. - -Device Setup -~~~~~~~~~~~~ - -``dcd_init()`` -"""""""""""""" - -Initializes the USB peripheral for device mode and enables it. -This function should enable internal D+/D- pull-up for enumeration. - -``dcd_int_enable()`` / ``dcd_int_disable()`` -"""""""""""""""""""""""""""""""""""""""""""" - -Enables or disables the USB device interrupt(s). May be used to prevent concurrency issues when mutating data structures shared between main code and the interrupt handler. - -``dcd_int_handler()`` -""""""""""""""""""""" - -Processes all the hardware generated events e.g Bus reset, new data packet from host etc ... It will be called by application in the MCU USB interrupt handler. - -``dcd_set_address()`` -""""""""""""""""""""" - -Called when the device is given a new bus address. - -If your peripheral automatically changes address during enumeration (like the nrf52) you may leave this empty and also no queue an event for the corresponding SETUP packet. - -``dcd_remote_wakeup()`` -""""""""""""""""""""""" - -Called to remote wake up host when suspended (e.g hid keyboard) - -``dcd_connect()`` / ``dcd_disconnect()`` -"""""""""""""""""""""""""""""""""""""""" - -Connect or disconnect the data-line pull-up resistor. Define only if MCU has an internal pull-up. (BSP may define for MCU without internal pull-up.) - -Special events -~~~~~~~~~~~~~~ - -You must let TinyUSB know when certain events occur so that it can continue its work. There are a few methods you can call to queue events for TinyUSB to process. - -``dcd_event_bus_signal()`` -"""""""""""""""""""""""""" - -There are a number of events that your peripheral may communicate about the state of the bus. Here is an overview of what they are. Events in **BOLD** must be provided for TinyUSB to work. - - -* **DCD_EVENT_RESET** - Triggered when the host resets the bus causing the peripheral to reset. Do any other internal reset you need from the interrupt handler such as resetting the control endpoint. -* DCD_EVENT_SOF - Signals the start of a new USB frame. - -Calls to this look like: - -.. code-block:: c - - dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); - - -The first ``0`` is the USB peripheral number. Statically saying ``0`` is common for single USB device MCUs. - -The ``true`` indicates the call is from an interrupt handler and will always be the case when porting in this way. - -``dcd_setup_received()`` -"""""""""""""""""""""""" - -SETUP packets are a special type of transaction that can occur at any time on the control endpoint, numbered ``0``. Since they are unique, most peripherals have special handling for them. Their data is always 8 bytes in length as well. - -Calls to this look like: - -.. code-block:: c - - dcd_event_setup_received(0, setup, true); - - -As before with ``dcd_event_bus_signal()`` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. - -Endpoints -~~~~~~~~~ - -Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below. - -Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides ``tu_edpt_number()`` and ``tu_edpt_dir()`` to unpack this data from the address. Here is a snippet that does it. - -.. code-block:: c - - uint8_t epnum = tu_edpt_number(ep_addr); - uint8_t dir = tu_edpt_dir(ep_addr); - - -``dcd_edpt_open()`` -""""""""""""""""""" - -Opening an endpoint is done for all non-control endpoints once the host picks a configuration that the device should use. At this point, the endpoint should be enabled in the peripheral and configured to match the endpoint descriptor. Pay special attention to the direction of the endpoint you can get from the helper methods above. It will likely change what registers you are setting. - -Also make sure to enable endpoint specific interrupts. - -``dcd_edpt_close()`` -"""""""""""""""""""" - -Close an endpoint. his function is used for implementing alternate settings. - -After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. - -Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. - -``dcd_edpt_xfer()`` -""""""""""""""""""" - -``dcd_edpt_xfer()`` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. - -Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint -number and direction which usually determines where to write the buffer info. The buffer and its length are usually -written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a -register or setting a counter register to 0 for OUT or length for IN.) - -The transmit buffer alignment is determined by ``CFG_TUSB_MEM_ALIGN``. - -One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB -packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). -Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track -some state for yourself and queue up an intermediate USB packet from the interrupt handler. - -Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. -During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete()`` function is called. - -The ``dcd_edpt_xfer()`` function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, -then it must be explicitly sent by the stack calling ``dcd_edpt_xfer()``, by calling ``dcd_edpt_xfer()`` a second time with len=0. -For control transfers, this is automatically done in ``usbd_control.c``. - -At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new ``dcd_edpt_xfer()`` will not -be called again on the same endpoint address until the driver calls ``dcd_xfer_complete()`` (except in cases of USB resets). - -``dcd_xfer_complete()`` -""""""""""""""""""""""" - -Once a transfer completes you must call ``dcd_xfer_complete()`` from the USB interrupt handler to let TinyUSB know that a transaction has completed. Here is a sample call: - -.. code-block:: c - - dcd_event_xfer_complete(0, ep_addr, xfer->actual_len, XFER_RESULT_SUCCESS, true); - - -The arguments are: - - -* the USB peripheral number -* the endpoint address -* the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer()``) -* the result of the transfer. Failure isn't handled yet. -* ``true`` to note the call is from an interrupt handler. - -``dcd_edpt_stall()`` / ``dcd_edpt_clear_stall()`` -""""""""""""""""""""""""""""""""""""""""""""""""" - -Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints. - -Woohoo! -------- - -At this point you should have everything working! 🙂 Of course, you may not write perfect code. Here are some tips and tricks for debugging. - -Use `WireShark `_ or `a Beagle `_ to sniff the USB traffic. When things aren't working its likely very early in the USB enumeration process. Figuring out where can help clue in where the issue is. For example: - - -* If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly. -* If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? 🙂) -* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task()`` may not be called.) If that's OK, the ``dcd_xfer_complete()`` may not be setting up the next transaction correctly. diff --git a/docs/faq.rst b/docs/faq.rst index ade51a379..a5fe09495 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -7,7 +7,7 @@ General Questions **Q: What microcontrollers does TinyUSB support?** -TinyUSB supports 30+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. +TinyUSB supports 50+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list. **Q: Can I use TinyUSB in commercial projects?** @@ -178,33 +178,3 @@ ESP32-S3 has specific USB implementation challenges: - Check power supply requirements for host mode - Some features may be limited compared to other MCUs - Use ESP32-S3 specific examples and documentation - -STM32CubeIDE Integration -======================== - -**Q: How do I integrate TinyUSB with STM32CubeIDE?** - -1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode -2. Enable the USB global interrupt in NVIC Settings -3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c -4. Call ``tud_task()`` in your main loop -5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` -6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files - -**Q: STM32CubeIDE generated code conflicts with TinyUSB** - -Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. - -**Q: STM32 USB interrupt handler setup** - -Replace the generated USB interrupt handler with a call to TinyUSB: - -.. code-block:: c - - void OTG_FS_IRQHandler(void) { - tud_int_handler(0); - } - -**Q: Which STM32 families work best with TinyUSB?** - -STM32F4, F7, and H7 families have the most mature TinyUSB support. STM32F0, F1, F3, L4 families are also supported but may have more limitations. Check the supported boards list for your specific variant. \ No newline at end of file diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 32c80b91c..0c3fcec80 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -2,14 +2,39 @@ Getting Started *************** -This guide will get you up and running with TinyUSB quickly. We'll start with working examples, then show you how to integrate TinyUSB into your own projects. +This guide will get you up and running with TinyUSB quickly with working examples. + +Project Structure +==================== + +TinyUSB separates example applications from board-specific hardware configurations: + +* **Example applications**: Located in `examples/ `_ directories +* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts +* **Build system**: Located in `examples/build_system/ `_ which supports both Make and CMake. Though some MCU families such as espressif or rp2040 only support cmake + +For example, stm32h743eval is located in `hw/bsp/stm32h7/boards/stm32h743eval `_ where ``FAMILY=stm32h7`` and ``BOARD=stm32h743eval``. When you build with ``BOARD=stm32h743eval``, the build system automatically finds the corresponding BSP using the FAMILY. + +For guidance on integrating TinyUSB into your own firmware (configuration, descriptors, initialization, and callback workflow), see :doc:`integration`. Quick Start Examples ==================== The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately. -We'll assume you are using the stm32f407disco board. For other boards, see ``Board Support Packages`` below. +We'll assume you are using the **STM32H743 Eval board** (BOARD=stm32h743eval) under the **stm32h7** family. For other boards, see ``Board Support Packages`` below. + +Get the Code +------------ + +.. code-block:: bash + + $ git clone https://github.com/hathach/tinyusb tinyusb + $ cd tinyusb + $ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7 + +.. note:: + For rp2040 `pico-sdk `_ or `esp-idf `_ for Espressif targets are required; install them per vendor instructions. Simple Device Example --------------------- @@ -17,20 +42,33 @@ Simple Device Example The `cdc_msc `_ example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). **What it does:** + * Appears as a serial port that echoes back any text you send * Appears as a small USB drive with a README.TXT file * Blinks an LED to show activity -**Build and run:** +**Build and run with CMake:** + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ cmake -DBOARD=stm32h743eval -B build # add "-G Ninja" to use Ninja build + $ cmake --build build + # cmake --build build --target cdc_msc-jlink + +.. tip:: + Flashed/Debugger can be selected with --target ``-jlink``, ``-stlink`` or ``-openocd`` depending on your board. Use ``--target help`` to list all supported targets. + +**Build and run with Make:** .. code-block:: bash - $ git clone https://github.com/hathach/tinyusb tinyusb - $ cd tinyusb - $ python tools/get_deps.py stm32f4 # download dependencies, note ESP and RP2 need their SDKs, too $ cd examples/device/cdc_msc - $ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows - $ cmake --build build # add "--target cdc_msc-jlink" for flashing using J-Link, "--target help" to list targets + $ make BOARD=stm32h743eval all + $ make BOARD=stm32h743eval flash-jlink + +.. tip:: + Flashed/Debugger can be selected with target ``flash-jlink``, ``flash-stlink`` or ``flash-openocd`` depending on your board. Connect the device to your computer and you'll see both a new serial port and a small USB drive appear. @@ -40,113 +78,91 @@ Simple Host Example The `cdc_msc_hid `_ example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. **What it does:** + * Detects and enumerates connected USB devices * Communicates with CDC devices (like USB-to-serial adapters) * Reads from MSC devices (like USB drives) * Receives input from HID devices (like keyboards and mice) -**Build and run:** +**Build and run with CMake:** .. code-block:: bash - $ # initial setup see previous example $ cd examples/host/cdc_msc_hid - $ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows - $ cmake --build build # add "--target cdc_msc_hid-jlink" for flashing using J-Link, "--target help" to list targets - -Connect USB devices to see enumeration messages and device-specific interactions in the serial output. - -Project Structure ------------------ - -TinyUSB separates example applications from board-specific hardware configurations: - -* **Example applications**: Located in `examples/device/ `_, `examples/host/ `_, and `examples/dual/ `_ directories -* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts - -For example, raspberry_pi_pico is located in `hw/bsp/rp2040/boards/raspberry_pi_pico `_ where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build with ``BOARD=raspberry_pi_pico``, the build system automatically finds the corresponding BSP using the FAMILY. - -Add TinyUSB to Your Project -============================ + $ cmake -DBOARD=stm32h743eval -B build + $ cmake --build build -Once you've seen TinyUSB working, here's how to integrate it into your own project: +**Build and run with Make:** -Integration Steps ------------------ +.. code-block:: bash -1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb`` + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32h743eval all + $ make BOARD=stm32h743eval flash-jlink -2. **Add source files**: Add all ``.c`` files from ``tinyusb/src/`` to your project +Connect USB devices to see enumeration messages and device-specific interactions in the serial output. -3. **Configure include paths**: Add ``your_project/tinyusb/src`` to your include path. Ensure your include path contains ``tusb_config.h`` +Additional Build Options +------------------------ -4. **Configure TinyUSB**: Create ``tusb_config.h`` with required macros like ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. Copy from ``examples/device/*/tusb_config.h`` as a starting point +Debug and Logging +^^^^^^^^^^^^^^^^^ -5. **Implement USB descriptors**: For device stack, implement all ``tud_descriptor_*_cb()`` callbacks +TinyUSB built-in logging can be enabled by setting `CFG_TUSB_DEBUG` which is done by passing ``LOG=level``. The higher the level, the more verbose the logging. -6. **Initialize TinyUSB**: Add ``tusb_init()`` to your initialization code +In addition to traditional hw uart as default, logging with debugger such as `Segger RTT `_ (10x faster) is also supported with `LOGGER=rtt` option. -7. **Handle interrupts**: Call ``tusb_int_handler()`` from your USB IRQ handler +.. code-block:: bash -8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) periodically in your main loop + $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 # logging level 2 with uart + $ cmake -B build -DBOARD=stm32h743eval -DLOG=2 -DLOGGER=rtt # logging level 2 with RTT -9. **Implement class callbacks**: Implement callbacks for enabled USB classes +.. code-block:: bash -Simple Integration Example --------------------------- + $ make BOARD=stm32h743eval LOG=2 all # logging level 2 with uart + $ make BOARD=stm32h743eval LOG=2 LOGGER=rtt all # logging level 2 with RTT -.. code-block:: c +RootHub Port Selection +^^^^^^^^^^^^^^^^^^^^^^ - #include "tusb.h" +Some boards support multiple usb controllers (roothub ports), by default one rh port is used as device, another as host in ``board.mk/board.cmake``. This can be overridden with option ``RHPORT_DEVICE=n`` or ``RHPORT_HOST=n`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: - int main(void) { - board_init(); // Your board initialization +.. code-block:: bash - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - // tud_descriptor_* callbacks omitted here - tusb_init(0, &dev_init); + $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE=1 # select roothub port 1 as device - while(1) { - tud_task(); // TinyUSB device task - your_application(); // Your application code - } - } +.. code-block:: bash - void USB_IRQHandler(void) { - tusb_int_handler(0, true); - } + $ make BOARD=stm32h743eval RHPORT_DEVICE=1 all # select roothub port 1 as device -.. note:: - Unlike many libraries, TinyUSB callbacks don't need to be explicitly registered. The stack automatically calls functions with specific names (e.g., ``tud_cdc_rx_cb()``) when events occur. Simply implement the callbacks you need. +RootHub Port Speed +^^^^^^^^^^^^^^^^^^ -.. note:: - TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`reference/glossary` for more details. +A MCU can support multiple operational speed. By default, the example build system will use the fastest supported on the board. Use option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL/HIGH_SPEED/`` e.g To force operating speed -Development Tips -================ +.. code-block:: bash -**Debug builds and logging:** + $ cmake -B build -DBOARD=stm32h743eval -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. code-block:: bash - $ cmake -DBOARD=stm32f407disco -DDEBUG=1 ... # Debug build - $ cmake -DBOARD=stm32f407disco -DLOG=2 ... # Enable detailed logging + $ make BOARD=stm32h743eval RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all + -**IAR Embedded Workbench:** +IAR Embedded Workbench +---------------------- For IAR users, project connection files are available. Import `tools/iar_template.ipcf `_ or use native CMake support (IAR 9.50.1+). See `tools/iar_gen.py `_ for automated project generation. + Common Issues and Solutions -=========================== +--------------------------- **Build Errors** * **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` * **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` -* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board +* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board or ``python tools/get_deps.py -b BOARD`` **Runtime Issues** @@ -166,6 +182,7 @@ Some examples require udev permissions to access USB devices: Next Steps ========== +* Check :doc:`integration` for integrating TinyUSB into your own firmware * Check :doc:`reference/boards` for board-specific information * Explore more examples in `examples/device/ `_ and `examples/host/ `_ directories * Read :doc:`reference/usb_concepts` to understand USB fundamentals diff --git a/docs/index.rst b/docs/index.rst index ac10dbfd7..39d30a038 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -1,45 +1,21 @@ -TinyUSB Documentation -===================== - -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events deferred to non-ISR task functions. - -For Developers --------------- - -TinyUSB provides a complete USB stack implementation supporting both device and host modes across a wide range of microcontrollers. The stack is designed for resource-constrained embedded systems with emphasis on code size, memory efficiency, and real-time performance. - -**Key Features:** - -* **Thread-safe design**: All USB interrupts are deferred to task context -* **Memory-safe**: No dynamic allocation, all buffers are statically allocated -* **Portable**: Supports 30+ MCU families from major vendors -* **Comprehensive**: Device classes (CDC, HID, MSC, Audio, etc.) and Host stack -* **RTOS support**: Works with bare metal, FreeRTOS, RT-Thread, and Mynewt - -**Quick Navigation:** - -* New to TinyUSB? Start with :doc:`getting_started` and :doc:`reference/glossary` -* Want to understand the design? Read :doc:`reference/architecture` and :doc:`reference/usb_concepts` -* Having issues? Check :doc:`faq` and :doc:`troubleshooting` - -Documentation Structure ------------------------ +.. include:: ../README_processed.rst .. toctree:: :maxdepth: 2 :caption: Information getting_started + integration + porting + reference/index faq troubleshooting - reference/index .. toctree:: :maxdepth: 1 :caption: Project Info info/index - contributing/index .. toctree:: :caption: External Links @@ -48,8 +24,3 @@ Documentation Structure Source Code Issue Tracker Discussions - -GitHub Project Main README -========================== - -.. include:: ../README_processed.rst diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index b4423f81e..d6bf846ed 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -20,6 +20,7 @@ API Changes ----------- - Core APIs + - Add weak callbacks with new syntax for better compiler compatibility - Add ``tusb_deinit()`` to cleanup stack - Add time functions: ``tusb_time_millis_api()`` and ``tusb_time_delay_ms_api()`` @@ -27,6 +28,7 @@ API Changes - Introduce ``xfer_isr()`` callback for ISO transfer optimization in device classes - Device APIs + - CDC: Add notification support ``tud_cdc_configure()``, ``tud_cdc_n_notify_uart_state()``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - MSC: Add ``tud_msc_inquiry2_cb()`` with bufsize parameter, update ``tud_msc_async_io_done()`` @@ -36,6 +38,7 @@ API Changes ``tud_mtp_response_send()``, ``tud_mtp_event_send()`` - Host APIs + - Core: Add ``tuh_edpt_close()``, ``tuh_address_set()``, ``tuh_descriptor_get_device_local()``, ``tuh_descriptor_get_string_langid()``, ``tuh_connected()``, ``tuh_bus_info_get()`` - Add enumeration callbacks: ``tuh_enum_descriptor_device_cb()``, @@ -50,6 +53,7 @@ Controller Driver (DCD & HCD) ----------------------------- - DWC2 + - Support DWC2 v4.30a with improved reset procedure - Fix core reset: wait for AHB idle before reset - Add STM32 DWC2 data cache support with proper alignment @@ -64,6 +68,7 @@ Controller Driver (DCD & HCD) - Refactor bitfields for better code generation - FSDEV (STM32) + - Fix AT32 compile issues after single-buffered endpoint changes - Add configurable single-buffered isochronous endpoints - Fix STM32H7 recurrent suspend ISR @@ -72,35 +77,42 @@ Controller Driver (DCD & HCD) - Improve PMA size handling for STM32U0 - EHCI + - Fix removed QHD getting reused - Fix NXP USBPHY disconnection detection - Chipidea/NXP + - Fix race condition with spinlock - Improve iMXRT support: fix build, disable BOARD_ConfigMPU, fix attach debouncing on port1 highspeed - Fix iMXRT1064 and add to HIL test pool - MAX3421E + - Use spinlock for thread safety instead of atomic flag - Implement ``hcd_edpt_close()`` - RP2040 + - Fix audio ISO transfer: reset state before notifying stack - Fix CMake RTOS cache variable - Abort transfer if active in ``iso_activate()`` - SAMD + - Add host controller driver support Device Stack ------------ - USBD Core + - Introduce ``xfer_isr()`` callback for interrupt-time transfer handling - Add ``usbd_edpt_xfer_fifo()`` stub - Revert endpoint busy/claim status if ``xfer_isr()`` defers to ``xfer_cb()`` - Audio + - Major simplification of UAC driver and alt settings management - Move ISO transfers into ``xfer_isr()`` for better performance - Remove FIFO mutex (single producer/consumer optimization) @@ -109,25 +121,30 @@ Device Stack - Update buffer macros with cache line size alignment - CDC + - Add notification support: ``CFG_TUD_CDC_NOTIFY``, ``tud_cdc_n_notify_conn_speed_change()``, ``tud_cdc_notify_complete_cb()`` - Reduce default bInterval from 16ms to 1ms for better responsiveness - Rename ``tud_cdc_configure_fifo()`` to ``tud_cdc_configure()`` and add ``tx_overwritable_if_not_connected`` option - Fix web serial robustness with major overhaul and logic cleanup - HID + - Add Usage Page and Table for Power Devices (0x84 - 0x85) - Fix HID descriptor parser variable size and 4-byte item handling - Add consumer page configurations - MIDI + - Fix MIDI interface descriptor handling after audio streaming interface - Skip RX data with all zeroes - MSC + - Add async I/O support for MSC using ``tud_msc_async_io_done()`` - Add ``tud_msc_inquiry2_cb()`` with bufsize for full inquiry response - MTP + - Add new Media Transfer Protocol (MTP) device class driver - Support MTP operations: GetDeviceInfo, SendObjectInfo, SendObject - Add MTP event support with ``tud_mtp_event_send()`` @@ -135,13 +152,16 @@ Device Stack - Add hardware-in-the-loop testing support - NCM + - Add USB NCM link state control support - Fix DHCP offer/ACK destination - USBTMC + - Add vendor-specific message support - Vendor + - Fix vendor device reset and open issues - Fix descriptor parsing for ``CFG_TUD_VENDOR > 1`` - Fix vendor FIFO argument calculation @@ -150,6 +170,7 @@ Host Stack ---------- - USBH Core + - Major enumeration improvements: - Fix enumeration racing conditions - Add proper attach debouncing with hub/rootport handling (200ms delay) @@ -173,6 +194,7 @@ Host Stack - Force removed devices in same bus info before setting address - CDC Serial Host + - Major refactor to generalize CDC serial drivers (FTDI, CP210x, CH34x, PL2303, ACM) - Add explicit ``sync()`` API with ``TU_API_SYNC()`` returning ``tusb_xfer_result_t`` - Rename ``tuh_cdc_get_local_line_coding()`` to ``tuh_cdc_get_line_coding_local()`` @@ -180,6 +202,7 @@ Host Stack - Implement ``tuh_cdc_get/set_dtr/rts()`` as inline functions - MIDI Host + - Major API changes: - Rename ``tuh_midi_stream_flush()`` to ``tuh_midi_write_flush()`` - Add ``tuh_midi_packet_read_n()`` and ``tuh_midi_packet_write_n()`` @@ -189,9 +212,11 @@ Host Stack - Add ``tuh_midi_descriptor_cb()`` and ``tuh_midi_itf_get_info()`` - MSC Host + - Continue async I/O improvements - HID Host + - Fix version string to actually show version 0.18.0 @@ -226,6 +251,7 @@ Controller Driver (DCD & HCD) ----------------------------- - DWC2 + - Add DMA support for both device and host controller - Add host driver support including: full/high speed, control/bulk/interrupt (CBI) transfer, split CBI i.e FS/LS attached via highspeed hub, hub support @@ -695,6 +721,7 @@ Controller Driver (DCD & HCD) ----------------------------- - [DWC2] Generalize synopsys dwc2 with synopsys/dwc2 which support both FS and HS phy (UTMI and ULPI) for various MCUs. + - Broadcom 28/27xx on raspberrypi SBC - Silicon Labs EFM32 - Espressif ESP32 Sx @@ -916,6 +943,7 @@ HID - Add more hid keys constant from 0x6B to 0xA4 - [Breaking] rename API + - ``HID_PROTOCOL_NONE/KEYBOARD/MOUSE`` to ``HID_ITF_PROTOCOL_NONE/KEYBOARD/MOUSE`` - ``tud_hid_boot_mode()`` to ``tud_hid_get_protocol()`` - ``tud_hid_boot_mode_cb()`` to ``tud_hid_set_protocol_cb()`` @@ -925,6 +953,7 @@ MIDI - Fix MIDI buffer overflow issue - [Breaking] rename API + - Rename ``tud_midi_read()`` to ``tud_midi_stream_read()`` - Rename ``tud_midi_write()`` to ``tud_midi_stream_write()`` - Rename ``tud_midi_receive()`` to ``tud_midi_packet_read()`` @@ -1075,15 +1104,19 @@ Device Controller Driver - Use ``dcd_event_bus_reset()`` with link speed to replace bus_signal - ESP32-S2: + - Add bus suspend and wakeup support - SAMD21: + - Fix (walkaround) samd21 setup_packet overflow by USB DMA - STM32 Synopsys: + - Rework USB FIFO allocation scheme and allow RX FIFO size reduction - Sony CXD56 + - Update Update Spresense SDK to 2.0.2 - Fix dcd issues with setup packets - Correct EP number for cdc_msc example @@ -1100,19 +1133,24 @@ USB Device **Class Driver** - CDC + - Allow to transmit data, even if the host does not support control line states i.e set DTR - HID + - change default ``CFG_TUD_HID_EP_BUFSIZE`` from 16 to 64 - MIDI + - Fix midi sysex sending bug - MSC + - Invoke only scsi complete callback after status transaction is complete. - Fix ``scsi_mode_sense6_t`` padding, which cause IAR compiler internal error. - USBTMC + - Change interrupt endpoint example size to 8 instead of 2 for better compatibility with mcu **Example** @@ -1154,6 +1192,7 @@ Device Controller Driver - Enhance STM32 Synopsys - Support bus events disconnection/suspend/resume/wakeup + - Improve transfer performance with optimizing xfer and fifo size - Support Highspeed port (OTG_HS) with both internal and external PHY - Support multiple usb ports with rhport=1 is highspeed on selected MCUs e.g H743, F23. It is possible to have OTG_HS to run on Fullspeed PHY (e.g lacking external PHY) @@ -1163,6 +1202,7 @@ Device Controller Driver - Support F105, F107 - Enhance STM32 fsdev + - Improve dcd fifo allocation - Fix ISTR race condition - Support remap USB IRQ on supported MCUs @@ -1171,6 +1211,7 @@ Device Controller Driver - Enhance NUC 505: enhance set configure behavior - Enhance SAMD + - Fix race condition with setup packet - Add SAMD11 option ``OPT_MCU_SAMD11`` - Add SAME5x option ``OPT_MCU_SAME5X`` @@ -1178,6 +1219,7 @@ Device Controller Driver - Fix SAMG control data toggle and stall race condition - Enhance nRF + - Fix hanged when ``tud_task()`` is called within critical section (disabled interrupt) - Fix disconnect bus event not submitted - Implement ISO transfer and ``dcd_edpt_close()`` @@ -1203,6 +1245,7 @@ USB Device - Improve USB Highspeed support with actual link speed detection with ``dcd_event_bus_reset()`` - Enhance class driver management + - ``usbd_driver_open()`` add max length argument, and return length of interface (0 for not supported). Return value is used for finding appropriate driver - Add application implemented class driver via ``usbd_app_driver_get_cb()`` - IAD is handled to assign driver id @@ -1219,11 +1262,13 @@ USB Device - USBTMC: fix descriptors when INT EP is disabled - CDC: + - Send zero length packet for end of data when needed - Add ``tud_cdc_tx_complete_cb()`` callback - Change ``tud_cdc_n_write_flush()`` return number of bytes forced to transfer, and flush when writing enough data to fifo - MIDI: + - Add packet interface - Add multiple jack descriptors - Fix MIDI driver for sysex @@ -1231,12 +1276,14 @@ USB Device - DFU Runtime: fix response to SET_INTERFACE and DFU_GETSTATUS request - Rename some configure macro to make it clear that those are used directly for endpoint transfer + - ``CFG_TUD_HID_BUFSIZE`` to ``CFG_TUD_HID_EP_BUFSIZE`` - ``CFG_TUD_CDC_EPSIZE`` to ``CFG_TUD_CDC_EP_BUFSIZE`` - ``CFG_TUD_MSC_BUFSIZE`` to ``CFG_TUD_MSC_EP_BUFSIZE`` - ``CFG_TUD_MIDI_EPSIZE`` to ``CFG_TUD_MIDI_EP_BUFSIZE`` - HID: + - Fix gamepad template descriptor - Add multiple HID interface API - Add extra comma to HID_REPORT_ID @@ -1258,6 +1305,7 @@ Examples - Add new ``hid_multiple_interface`` - Enhance ``net_lwip_webserver`` example + - Add multiple configuration: RNDIS for Windows, CDC-ECM for macOS (Linux will work with both) - Update lwip to STABLE-2_1_2_RELEASE for ``net_lwip_webserver`` diff --git a/docs/info/code_of_conduct.rst b/docs/info/code_of_conduct.rst new file mode 100644 index 000000000..2d70708d4 --- /dev/null +++ b/docs/info/code_of_conduct.rst @@ -0,0 +1 @@ +.. include:: ../../CODE_OF_CONDUCT.rst diff --git a/docs/info/index.rst b/docs/info/index.rst index a636f37dc..b6d30b432 100644 --- a/docs/info/index.rst +++ b/docs/info/index.rst @@ -10,3 +10,4 @@ Index changelog contributors + code_of_conduct diff --git a/docs/integration.rst b/docs/integration.rst new file mode 100644 index 000000000..3480746d0 --- /dev/null +++ b/docs/integration.rst @@ -0,0 +1,93 @@ +******************* +Integrating TinyUSB +******************* + +Once you've seen TinyUSB working in the examples, use this guide to wire the stack into your own firmware. + +Integration Steps +================= + +1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb``. +2. **Add source files**: Add every ``.c`` file from ``tinyusb/src/`` to your project build system. + +.. note:: + Only supported dcd/hcd drivers for your CPU sources under ``tinyusb/src/portable/vendor/usbip/`` are needed. Add + +3. **Configure TinyUSB**: Create ``tusb_config.h`` with macros such as ``CFG_TUSB_MCU``, ``CFG_TUSB_OS``, and class enable flags. Start from any example's ``tusb_config.h`` and tweak. +4. **Configure include paths**: Add ``your_project/tinyusb/src`` (and the folder holding ``tusb_config.h``) to your include paths. +5. **Implement USB descriptors**: For device stack, implement the ``tud_descriptor_*_cb()`` callbacks (device) or host descriptor helpers that match your product. +6. **Initialize TinyUSB**: Call ``tusb_init()`` once the clocks/peripherals are ready. Pass ``tusb_rhport_init_t`` if you need per-port settings. +7. **Handle interrupts**: From the USB ISR call ``tusb_int_handler(rhport, true)`` so the stack can process events. +8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) regularly from the main loop, RTOS task. +9. **Implement class callbacks**: Provide the callbacks for the classes you enabled (e.g., ``tud_cdc_rx_cb()``, ``tuh_msc_mount_cb()``). + +Minimal Example +=============== + +.. code-block:: c + + #include "tusb.h" + + int main(void) { + board_init(); // Your board initialization + + // Init device stack on roothub port 0 for highspeed device + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_HIGH + }; + tusb_init(0, &dev_init); + + // init host stack on roothub port 1 for fullspeed host + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_FULL + }; + tusb_init(1, &host_init); + + while (1) { + tud_task(); // device task + tuh_task(); // host task + + app_task(); // Your application logic + } + } + + void USB0_IRQHandler(void) { + // forward interrupt port 0 to TinyUSB stack + tusb_int_handler(0, true); + } + + void USB1_IRQHandler(void) { + // forward interrupt port 0 to TinyUSB stack + tusb_int_handler(1, true); + } + +.. note:: + Unlike many libraries, TinyUSB callbacks don't need to be registered. Implement functions with the prescribed names (for example ``tud_cdc_rx_cb()``) and the stack will invoke them automatically. + +.. note:: + Naming follows ``tud_*`` for device APIs and ``tuh_*`` for host APIs. Refer to :doc:`reference/glossary` for a summary of the prefixes and callback naming rules. + + +STM32CubeIDE Integration +======================== + +To integrate TinyUSB device stack with STM32CubeIDE + +1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode +2. Enable the USB global interrupt in NVIC Settings +3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c +4. Call ``tud_task()`` in your main loop +5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)`` + +.. code-block:: c + + void OTG_FS_IRQHandler(void) { + tud_int_handler(0); + } + +6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files + +.. tip:: + STM32CubeIDE generated code conflicts with TinyUSB. Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality. diff --git a/docs/porting.rst b/docs/porting.rst new file mode 100644 index 000000000..c3076354c --- /dev/null +++ b/docs/porting.rst @@ -0,0 +1,243 @@ + +******* +Porting +******* + +TinyUSB is designed to be a universal USB protocol stack for microcontrollers. It +handles most of the high level USB protocol and relies on the microcontroller's USB peripheral for +data transactions on different endpoints. Porting is the process of adding low-level support for +the rest of the common stack. Once the low-level is implemented, it is very easy to add USB support +for the microcontroller to other projects, especially those already using TinyUSB such as CircuitPython. + +Below are instructions on how to get the cdc_msc device example running on a new microcontroller. Doing so includes adding the common code necessary for other uses while minimizing other extra code. Whenever you see a phrase or word in ``<>`` it should be replaced. + +Register defs +------------- + +The first step to adding support is including the register definitions and startup code for the +microcontroller in TinyUSB. We write the TinyUSB implementation against these structs instead of higher level functions to keep the code small and to prevent function name collisions in linking of larger projects. For ARM microcontrollers this is the CMSIS definitions. They should be +placed in the ``hw/mcu//`` directory. + +Once this is done, create a directory in ``hw/bsp/`` for the specific board you are using to test the code (duplicating an existing board's directory is the best way to get started). The board should be a readily available development board so that others can also test. + +Build +----- + +Now that those directories are in place, we can start our iteration process to get the example building successfully. To build, run from the root of TinyUSB: + +.. code-block:: bash + + make -C examples/device/cdc_msc BOARD= + +Unless you've read ahead, this will fail miserably. Now, lets get it to fail less by updating the files in the board directory. The code in the board's directory is responsible for setting up the microcontroller's clocks and pins so that USB works. TinyUSB itself only operates on the USB peripheral. The board directory also includes information what files are needed to build the example. + +One of the first things to change is the ``-DCFG_TUSB_MCU`` C flag in the ``board.mk`` file. This is used to tell TinyUSB what platform is being built. So, add an entry to ``src/tusb_option.h`` and update the ``CFLAGS`` to match. + +Update ``board.mk``'s VENDOR and CHIP_FAMILY values when creating the directory for the struct files. Duplicate one of the other sources from ``src/portable`` into ``src/portable//`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling. + +Implementation +-------------- + +At this point you should get an error due to an implementation issue and hopefully the build is setup for the new MCU. You will still need to modify the ``board.mk`` to include specific ``CFLAGS``, the linker script, linker flags, source files, include directories. All file paths are relative to the top of the TinyUSB repo. + +Board Support (BSP) +^^^^^^^^^^^^^^^^^^^ + +The board support code is only used for self-contained examples and testing. It is not used when TinyUSB is part of a larger project. Its responsible for getting the MCU started and the USB peripheral clocked. It also optionally provides LED definitions that are used to blink an LED to show that the code is running. + +It is located in ``hw/bsp//board_.c``. + +``board_init()`` +~~~~~~~~~~~~~~~~ + +``board_init()`` is responsible for starting the MCU, setting up the USB clock and USB pins. It is also responsible for initializing LED pins. + +One useful clock debugging technique is to set up a PWM output at a known value such as 500hz based on the USB clock so that you can verify it is correct with a logic probe or oscilloscope. + +Setup your USB in a crystal-less mode when available. That makes the code easier to port across boards. + +``board_led_write()`` +~~~~~~~~~~~~~~~~~~~~~ + +Feel free to skip this until you want to verify your demo code is running. To implement, set the pin corresponding to the led to output a value that lights the LED when ``state`` is true. + +OS Abstraction Layer (OSAL) +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +The OS Abstraction Layer is responsible for providing basic data structures for TinyUSB that may allow for concurrency when used with an RTOS. Without an RTOS it simply handles concurrency issues between the main code and interrupts. The code is almost entirely agnostic of MCU and lives in ``src/osal``. + +In RTOS configurations, ``tud_task()``/``tuh_task()`` blocks behind a synchronization structure when the event queue is empty, so that the scheduler may give the CPU to a different task. To take advantage of the library's capability to yield the CPU when there are no actionable USB device events, ensure that the ``CFG_TUSB_OS`` symbol is defined, e.g ``OPT_OS_FREERTOS`` enables the FreeRTOS scheduler to schedule other threads than that which calls ``tud_task()``/``tuh_task()``. + +Device API +^^^^^^^^^^ + +After the USB device is setup, the USB device code works by processing events on the main thread (by calling ``tud_task()``). These events are queued by the USB interrupt handler. So, there are three parts to the device low-level API: device setup, endpoint setup and interrupt processing. + +All of the code for the low-level device API is in ``src/portable///dcd_.c``. + +Device Setup +~~~~~~~~~~~~ + +``dcd_init()`` +"""""""""""""" + +Initializes the USB peripheral for device mode and enables it. +This function should enable internal D+/D- pull-up for enumeration. + +``dcd_int_enable()`` / ``dcd_int_disable()`` +"""""""""""""""""""""""""""""""""""""""""""" + +Enables or disables the USB device interrupt(s). May be used to prevent concurrency issues when mutating data structures shared between main code and the interrupt handler. + +``dcd_int_handler()`` +""""""""""""""""""""" + +Processes all the hardware generated events e.g Bus reset, new data packet from host etc ... It will be called by application in the MCU USB interrupt handler. + +``dcd_set_address()`` +""""""""""""""""""""" + +Called when the device is given a new bus address. + +If your peripheral automatically changes address during enumeration (like the nrf52) you may leave this empty and also no queue an event for the corresponding SETUP packet. + +``dcd_remote_wakeup()`` +""""""""""""""""""""""" + +Called to remote wake up host when suspended (e.g hid keyboard) + +``dcd_connect()`` / ``dcd_disconnect()`` +"""""""""""""""""""""""""""""""""""""""" + +Connect or disconnect the data-line pull-up resistor. Define only if MCU has an internal pull-up. (BSP may define for MCU without internal pull-up.) + +Special events +~~~~~~~~~~~~~~ + +You must let TinyUSB know when certain events occur so that it can continue its work. There are a few methods you can call to queue events for TinyUSB to process. + +``dcd_event_bus_signal()`` +"""""""""""""""""""""""""" + +There are a number of events that your peripheral may communicate about the state of the bus. Here is an overview of what they are. Events in **BOLD** must be provided for TinyUSB to work. + + +* **DCD_EVENT_RESET** - Triggered when the host resets the bus causing the peripheral to reset. Do any other internal reset you need from the interrupt handler such as resetting the control endpoint. +* DCD_EVENT_SOF - Signals the start of a new USB frame. + +Calls to this look like: + +.. code-block:: c + + dcd_event_bus_signal(0, DCD_EVENT_BUS_RESET, true); + + +The first ``0`` is the USB peripheral number. Statically saying ``0`` is common for single USB device MCUs. + +The ``true`` indicates the call is from an interrupt handler and will always be the case when porting in this way. + +``dcd_setup_received()`` +"""""""""""""""""""""""" + +SETUP packets are a special type of transaction that can occur at any time on the control endpoint, numbered ``0``. Since they are unique, most peripherals have special handling for them. Their data is always 8 bytes in length as well. + +Calls to this look like: + +.. code-block:: c + + dcd_event_setup_received(0, setup, true); + + +As before with ``dcd_event_bus_signal()`` the first argument is the USB peripheral number and the third is true to signal its being called from an interrupt handler. The middle argument is byte array of length 8 with the contents of the SETUP packet. It can be stack allocated because it is copied into the queue. + +Endpoints +~~~~~~~~~ + +Endpoints are the core of the USB data transfer process. They come in a few forms such as control, isochronous, bulk, and interrupt. We won't cover the details here except with some caveats in open below. In general, data is transferred by setting up a buffer of a given length to be transferred on a given endpoint address and then waiting for an interrupt to signal that the transfer is finished. Further details below. + +Endpoints within USB have an address which encodes both the number and direction of an endpoint. TinyUSB provides ``tu_edpt_number()`` and ``tu_edpt_dir()`` to unpack this data from the address. Here is a snippet that does it. + +.. code-block:: c + + uint8_t epnum = tu_edpt_number(ep_addr); + uint8_t dir = tu_edpt_dir(ep_addr); + + +``dcd_edpt_open()`` +""""""""""""""""""" + +Opening an endpoint is done for all non-control endpoints once the host picks a configuration that the device should use. At this point, the endpoint should be enabled in the peripheral and configured to match the endpoint descriptor. Pay special attention to the direction of the endpoint you can get from the helper methods above. It will likely change what registers you are setting. + +Also make sure to enable endpoint specific interrupts. + +``dcd_edpt_close()`` +"""""""""""""""""""" + +Close an endpoint. his function is used for implementing alternate settings. + +After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. + +Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. + +``dcd_edpt_xfer()`` +""""""""""""""""""" + +``dcd_edpt_xfer()`` is responsible for configuring the peripheral to send or receive data from the host. "xfer" is short for "transfer". **This is one of the core methods you must implement for TinyUSB to work (one other is the interrupt handler).** Data from the host is the OUT direction and data to the host is IN. It is used for all endpoints including the control endpoint 0. Make sure to handle the zero-length packet STATUS packet on endpoint 0 correctly. It may be a special transaction to the peripheral. + +Besides that, all other transactions are relatively straight-forward. The endpoint address provides the endpoint +number and direction which usually determines where to write the buffer info. The buffer and its length are usually +written to a specific location in memory and the peripheral is told the data is valid. (Maybe by writing a 1 to a +register or setting a counter register to 0 for OUT or length for IN.) + +The transmit buffer alignment is determined by ``CFG_TUSB_MEM_ALIGN``. + +One potential pitfall is that the buffer may be longer than the maximum endpoint size of one USB +packet. Some peripherals can handle transmitting multiple USB packets for a provided buffer (like the SAMD21). +Others (like the nRF52) may need each USB packet queued individually. To make this work you'll need to track +some state for yourself and queue up an intermediate USB packet from the interrupt handler. + +Once the transaction is going, the interrupt handler will notify TinyUSB of transfer completion. +During transmission, the IN data buffer is guaranteed to remain unchanged in memory until the ``dcd_xfer_complete()`` function is called. + +The ``dcd_edpt_xfer()`` function must never add zero-length-packets (ZLP) on its own to a transfer. If a ZLP is required, +then it must be explicitly sent by the stack calling ``dcd_edpt_xfer()``, by calling ``dcd_edpt_xfer()`` a second time with len=0. +For control transfers, this is automatically done in ``usbd_control.c``. + +At the moment, only a single buffer can be transmitted at once. There is no provision for double-buffering. new ``dcd_edpt_xfer()`` will not +be called again on the same endpoint address until the driver calls ``dcd_xfer_complete()`` (except in cases of USB resets). + +``dcd_xfer_complete()`` +""""""""""""""""""""""" + +Once a transfer completes you must call ``dcd_xfer_complete()`` from the USB interrupt handler to let TinyUSB know that a transaction has completed. Here is a sample call: + +.. code-block:: c + + dcd_event_xfer_complete(0, ep_addr, xfer->actual_len, XFER_RESULT_SUCCESS, true); + + +The arguments are: + + +* the USB peripheral number +* the endpoint address +* the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer()``) +* the result of the transfer. Failure isn't handled yet. +* ``true`` to note the call is from an interrupt handler. + +``dcd_edpt_stall()`` / ``dcd_edpt_clear_stall()`` +""""""""""""""""""""""""""""""""""""""""""""""""" + +Stalling is one way an endpoint can indicate failure such as when an unsupported command is transmitted. The pair of ``dcd_edpt_stall()``, ``dcd_edpt_clear_stall()`` help manage the stall state of all endpoints. + +Woohoo! +------- + +At this point you should have everything working! 🙂 Of course, you may not write perfect code. Here are some tips and tricks for debugging. + +Use `WireShark `_ or `a Beagle `_ to sniff the USB traffic. When things aren't working its likely very early in the USB enumeration process. Figuring out where can help clue in where the issue is. For example: + + +* If the host sends a SETUP packet and its not ACKed then your USB peripheral probably isn't started correctly. +* If the peripheral is started correctly but it still didn't work, then verify your usb clock is correct. (You did output a PWM based on it right? 🙂) +* If the SETUP packet is ACKed but nothing is sent back then you interrupt handler isn't queueing the setup packet correctly. (Also, if you are using your own code instead of an example ``tud_task()`` may not be called.) If that's OK, the ``dcd_xfer_complete()`` may not be setting up the next transaction correctly. diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst index 8e4c6890e..70ea17ed4 100644 --- a/docs/reference/architecture.rst +++ b/docs/reference/architecture.rst @@ -42,36 +42,23 @@ Layer Structure TinyUSB follows a layered architecture from hardware to application: -.. code-block:: none +.. figure:: ../assets/stack.svg + :width: 500px + :align: left + :alt: stackup + +.. raw:: html - ┌─────────────────────────────────────────┐ - │ Application Layer │ ← Your code - ├─────────────────────────────────────────┤ - │ USB Class Drivers │ ← CDC, HID, MSC, etc. - ├─────────────────────────────────────────┤ - │ Device/Host Stack Core │ ← USB protocol handling - ├─────────────────────────────────────────┤ - │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers - ├─────────────────────────────────────────┤ - │ OS Abstraction (OSAL) │ ← RTOS integration - ├─────────────────────────────────────────┤ - │ Common Utilities & FIFO │ ← Shared components - └─────────────────────────────────────────┘ +
Component Overview ------------------ -**Application Layer**: Your main application code that uses TinyUSB APIs. - -**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. - -**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. - -**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. - -**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. - -**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. +- **Application Layer**: Your main application code that uses TinyUSB APIs. +- **Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. +- **Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. +- **OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. +- **Device/Host Controller Driver**: drivers that interface with MCU USB peripherals. Several MCUs may share a common driver. Device Stack Architecture ========================= @@ -85,7 +72,7 @@ Core Components - MCU-specific USB device peripheral driver - Handles endpoint configuration and data transfers - Abstracts hardware differences between MCU families -- Located in ``src/portable/VENDOR/FAMILY/`` +- Located in ``src/portable/VENDOR/USBIP/`` **USB Device Core (USBD)**: - Implements USB device state machine diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index e668e2693..12da5c90b 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -107,17 +107,20 @@ olimex_emz64 Olimex PIC32-EMZ64 pic32mz http olimex_hmz144 Olimex PIC32-HMZ144 pic32mz https://www.olimex.com/Products/PIC/Development/PIC32-HMZ144/open-source-hardware cynthion_d11 Great Scott Gadgets Cynthion samd11 https://greatscottgadgets.com/cynthion/ samd11_xplained SAMD11 Xplained Pro samd11 https://www.microchip.com/en-us/development-tool/ATSAMD11-XPRO -atsamd21_xpro SAMD21 Xplained Pro samd21 https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMD21-XPRO -circuitplayground_express Adafruit Circuit Playground Express samd21 https://www.adafruit.com/product/3333 -curiosity_nano SAMD21 Curiosty Nano samd21 https://www.microchip.com/en-us/development-tool/dm320119 -cynthion_d21 Great Scott Gadgets Cynthion samd21 https://greatscottgadgets.com/cynthion/ -feather_m0_express Adafruit Feather M0 Express samd21 https://www.adafruit.com/product/3403 -itsybitsy_m0 Adafruit ItsyBitsy M0 samd21 https://www.adafruit.com/product/3727 -metro_m0_express Adafruit Metro M0 Express samd21 https://www.adafruit.com/product/3505 -qtpy Adafruit QT Py samd21 https://www.adafruit.com/product/4600 -seeeduino_xiao Seeeduino XIAO samd21 https://wiki.seeedstudio.com/Seeeduino-XIAO/ -sparkfun_samd21_mini_usb SparkFun SAMD21 Mini samd21 https://www.sparkfun.com/products/13664 -trinket_m0 Adafruit Trinket M0 samd21 https://www.adafruit.com/product/3500 +atsamd21_xpro SAMD21 Xplained Pro samd2x_l2x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMD21-XPRO +atsaml21_xpro SAML21 Xplained Pro samd2x_l2x https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b +circuitplayground_express Adafruit Circuit Playground Express samd2x_l2x https://www.adafruit.com/product/3333 +curiosity_nano SAMD21 Curiosty Nano samd2x_l2x https://www.microchip.com/en-us/development-tool/dm320119 +cynthion_d21 Great Scott Gadgets Cynthion samd2x_l2x https://greatscottgadgets.com/cynthion/ +feather_m0_express Adafruit Feather M0 Express samd2x_l2x https://www.adafruit.com/product/3403 +itsybitsy_m0 Adafruit ItsyBitsy M0 samd2x_l2x https://www.adafruit.com/product/3727 +metro_m0_express Adafruit Metro M0 Express samd2x_l2x https://www.adafruit.com/product/3505 +qtpy Adafruit QT Py samd2x_l2x https://www.adafruit.com/product/4600 +saml22_feather SAML22 Feather samd2x_l2x https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather +seeeduino_xiao Seeeduino XIAO samd2x_l2x https://wiki.seeedstudio.com/Seeeduino-XIAO/ +sensorwatch_m0 SensorWatch samd2x_l2x https://github.com/joeycastillo/Sensor-Watch +sparkfun_samd21_mini_usb SparkFun SAMD21 Mini samd2x_l2x https://www.sparkfun.com/products/13664 +trinket_m0 Adafruit Trinket M0 samd2x_l2x https://www.adafruit.com/product/3500 d5035_01 D5035-01 samd5x_e5x https://github.com/RudolphRiedel/USB_CAN-FD feather_m4_express Adafruit Feather M4 Express samd5x_e5x https://www.adafruit.com/product/3857 itsybitsy_m4 Adafruit ItsyBitsy M4 samd5x_e5x https://www.adafruit.com/product/3800 @@ -125,10 +128,9 @@ metro_m4_express Adafruit Metro M4 Express samd5x_e5x http pybadge Adafruit PyBadge samd5x_e5x https://www.adafruit.com/product/4200 pyportal Adafruit PyPortal samd5x_e5x https://www.adafruit.com/product/4116 same54_xplained SAME54 Xplained Pro samd5x_e5x https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAME54-XPRO +same70_qmtech SAME70 QMTech same7x https://www.aliexpress.com/item/1005003173783268.html +same70_xplained SAME70 Xplained same7x https://www.microchip.com/en-us/development-tool/atsame70-xpld samg55_xplained SAMG55 Xplained Pro samg https://www.microchip.com/DevelopmentTools/ProductDetails/ATSAMG55-XPRO -atsaml21_xpro SAML21 Xplained Pro saml2x https://www.microchip.com/en-us/development-tool/atsaml21-xpro-b -saml22_feather SAML22 Feather saml2x https://github.com/joeycastillo/Feather-Projects/tree/main/SAML22%20Feather -sensorwatch_m0 SensorWatch saml2x https://github.com/joeycastillo/Sensor-Watch ========================= =================================== ========== ================================================================================= ====== MindMotion @@ -295,6 +297,7 @@ stm32l052dap52 STM32 L052 DAP stm32l0 n/a stm32l0538disco STM32 L0538 Discovery stm32l0 https://www.st.com/en/evaluation-tools/32l0538discovery.html stm32l412nucleo STM32 L412 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l412kb.html stm32l476disco STM32 L476 Disco stm32l4 https://www.st.com/en/evaluation-tools/32l476gdiscovery.html +stm32l496nucleo STM32 L496 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l496ZG-P.html stm32l4p5nucleo STM32 L4P5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4p5zg.html stm32l4r5nucleo STM32 L4R5 Nucleo stm32l4 https://www.st.com/en/evaluation-tools/nucleo-l4r5zi.html stm32n6570dk STM32 N6570-DK stm32n6 https://www.st.com/en/evaluation-tools/stm32n6570-dk.html diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index e04cc2c2f..de1603383 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral drivers and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -23,7 +23,7 @@ hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf -hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc +hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 @@ -80,10 +80,10 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32n6 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c -lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git b0bbb0423b278ca632cfe1474eb227961d835fd2 ra +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c +lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 ra stm32n6 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== ====================================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== diff --git a/docs/reference/glossary.rst b/docs/reference/glossary.rst index 561780c53..537769c43 100644 --- a/docs/reference/glossary.rst +++ b/docs/reference/glossary.rst @@ -95,4 +95,4 @@ Glossary Product Identifier. 16-bit number assigned by vendor to identify specific products. USB-IF - USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. \ No newline at end of file + USB Implementers Forum. Organization that maintains USB specifications and assigns VIDs. diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index e30210d01..bb9f15166 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -15,13 +15,14 @@ Toolchain Problems The ARM GCC toolchain is not installed or not in PATH. *Solution*: + .. code-block:: bash # Ubuntu/Debian - sudo apt-get update && sudo apt-get install gcc-arm-none-eabi + $ sudo apt-get update && sudo apt-get install gcc-arm-none-eabi # macOS with Homebrew - brew install --cask gcc-arm-embedded + $ brew install --cask gcc-arm-embedded # Windows: Download from ARM website and add to PATH @@ -30,14 +31,15 @@ The ARM GCC toolchain is not installed or not in PATH. Build tools are missing. *Solution*: + .. code-block:: bash # Ubuntu/Debian - sudo apt-get install build-essential cmake + $ sudo apt-get install build-essential cmake # macOS - xcode-select --install - brew install cmake + $ xcode-select --install + $ brew install cmake Dependency Issues ----------------- @@ -47,10 +49,12 @@ Dependency Issues Dependencies for your MCU family are not downloaded. *Solution*: + .. code-block:: bash - # Download dependencies for specific family - python tools/get_deps.py stm32f4 # Replace with your family + # Download dependencies for specific board or family + $ python tools/get_deps.py -b stm32h743eval # Replace with your board + $ python tools/get_deps.py stm32f4 # Replace with your family # Or from example directory cd examples/device/cdc_msc @@ -61,14 +65,12 @@ Dependencies for your MCU family are not downloaded. Invalid board name in build command. *Diagnosis*: + .. code-block:: bash # List available boards for a family ls hw/bsp/stm32f4/boards/ - # List all supported boards - python tools/build.py -l - *Solution*: Use exact board name from the listing. Runtime Issues @@ -82,6 +84,7 @@ Device Mode Problems The most common issue - host doesn't see your USB device. *Diagnosis steps*: + 1. Check USB cable (must support data, not just power) 2. Enable logging: build with ``LOG=2`` 3. Use different USB ports/hosts @@ -99,17 +102,20 @@ The most common issue - host doesn't see your USB device. Device is detected but configuration fails. *Diagnosis*: + .. code-block:: bash # Build with logging enabled make BOARD=your_board LOG=2 all *Look for*: + - Setup request handling errors - Endpoint configuration problems - String descriptor issues *Solutions*: + - Implement all required descriptors - Check endpoint sizes match descriptors - Ensure control endpoint (EP0) handling is correct @@ -119,11 +125,13 @@ Device is detected but configuration fails. Device enumerates but data doesn't transfer correctly. *Common causes*: + - Buffer overruns in class callbacks - Incorrect endpoint usage (IN vs OUT) - Flow control issues in CDC class *Solutions*: + - Check buffer sizes in callbacks - Verify endpoint directions in descriptors - Implement proper flow control @@ -136,11 +144,13 @@ Host Mode Problems Host application doesn't see connected devices. *Hardware checks*: + - Power supply adequate for host mode - USB-A connector for host (not micro-USB) - Board supports host mode on selected port *Software checks*: + - ``tuh_task()`` called regularly - Host stack enabled in ``tusb_config.h`` - Correct root hub port configuration @@ -150,12 +160,14 @@ Host application doesn't see connected devices. Devices connect but enumeration fails. *Diagnosis*: + .. code-block:: bash # Enable host logging make BOARD=your_board LOG=2 RHPORT_HOST=1 all *Common issues*: + - Power supply insufficient during enumeration - Timing issues with slow devices - USB hub compatibility problems @@ -165,6 +177,7 @@ Devices connect but enumeration fails. Device enumerates but class-specific communication fails. *Troubleshooting*: + - Check device descriptors match expected class - Verify interface/endpoint assignments - Some devices need device-specific handling @@ -185,6 +198,7 @@ High CPU Usage **Symptoms**: MCU spending too much time in USB handling *Solutions*: + - Use efficient logging (RTT/SWO instead of UART) - Reduce log level in production builds - Optimize descriptor parsing @@ -197,11 +211,13 @@ STM32 Issues ------------ **Clock configuration problems**: + - USB requires precise 48MHz clock - HSE crystal must be configured correctly - PLL settings affect USB timing **Pin configuration**: + - USB pins need specific alternate function settings - VBUS sensing configuration - ID pin for OTG applications @@ -210,6 +226,7 @@ RP2040 Issues ------------- **PIO-USB for host mode**: + - Requires specific pin assignments - CPU overclocking may be needed for reliable operation - Timing-sensitive - avoid long interrupt disable periods @@ -218,8 +235,8 @@ ESP32 Issues ------------ **USB peripheral differences**: -- ESP32-S2/S3 have different USB capabilities -- Some variants only support device mode + +- ESP32-S2/S3/P4 have different USB capabilities - DMA configuration varies between models Advanced Debugging @@ -249,6 +266,7 @@ However, especially for diagnosis of crashes, it can still be useful. arm-none-eabi-gdb build/your_app.elf *Useful breakpoints*: + - ``dcd_int_handler()`` - USB interrupt entry - ``tud_task()`` - Main device task - Class-specific callbacks @@ -280,6 +298,7 @@ When reporting issues: 5. **Host environment**: OS version, USB port type **Resources**: + - GitHub Discussions: https://github.com/hathach/tinyusb/discussions - Issue Tracker: https://github.com/hathach/tinyusb/issues - Documentation: https://docs.tinyusb.org diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index ad68957df..23dfb9d80 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -10,6 +10,40 @@ get_filename_component(TOP ${TOP} ABSOLUTE) set(UF2CONV_PY ${TOP}/tools/uf2/utils/uf2conv.py) +function(family_resolve_board BOARD_NAME BOARD_PATH_OUT) + if ("${BOARD_NAME}" STREQUAL "") + message(FATAL_ERROR "You must set BOARD (e.g. metro_m4_express, raspberry_pi_pico). Use -DBOARD=xxx on the cmake command line.") + endif() + + file(GLOB _board_paths + LIST_DIRECTORIES true + RELATIVE ${TOP}/hw/bsp + ${TOP}/hw/bsp/*/boards/* + ) + + set(_hint_names "") + foreach(_board_path ${_board_paths}) + get_filename_component(_board_name ${_board_path} NAME) + if (_board_name STREQUAL "${BOARD_NAME}") + set(${BOARD_PATH_OUT} ${_board_path} PARENT_SCOPE) + return() + endif() + string(FIND "${_board_name}" "${BOARD_NAME}" _pos) + if (_pos EQUAL 0) + list(APPEND _hint_names ${_board_name}) + endif() + endforeach() + + if (_hint_names) + list(REMOVE_DUPLICATES _hint_names) + list(SORT _hint_names) + list(JOIN _hint_names ", " _hint_str) + message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found. Boards with the same prefix:\n${_hint_str}") + else() + message(FATAL_ERROR "BOARD '${BOARD_NAME}' not found under hw/bsp/*/boards") + endif() +endfunction() + #------------------------------------------------------------- # Toolchain # Can be changed via -DTOOLCHAIN=gcc|iar or -DCMAKE_C_COMPILER= or ENV{CC}= @@ -78,21 +112,8 @@ endif () # FAMILY and BOARD #------------------------------------------------------------- if (NOT DEFINED FAMILY) - if (NOT DEFINED BOARD) - message(FATAL_ERROR "You must set a BOARD variable for the build (e.g. metro_m4_express, raspberry_pi_pico). - You can do this via -DBOARD=xxx on the cmake command line") - endif () - - # Find path contains BOARD - file(GLOB BOARD_PATH LIST_DIRECTORIES true - RELATIVE ${TOP}/hw/bsp - ${TOP}/hw/bsp/*/boards/${BOARD} - ) - if (NOT BOARD_PATH) - message(FATAL_ERROR "Could not detect FAMILY from BOARD=${BOARD}") - endif () + family_resolve_board("${BOARD}" BOARD_PATH) - # replace / with ; so that we can get the first element as FAMILY string(REPLACE "/" ";" BOARD_PATH ${BOARD_PATH}) list(GET BOARD_PATH 0 FAMILY) set(FAMILY ${FAMILY} CACHE STRING "Board family") diff --git a/tools/gen_doc.py b/tools/gen_doc.py index ab07bc116..3920531d5 100755 --- a/tools/gen_doc.py +++ b/tools/gen_doc.py @@ -23,7 +23,7 @@ def gen_deps_doc(): Dependencies ************ -MCU low-level peripheral driver and external libraries for building TinyUSB examples +MCU low-level peripheral drivers and external libraries for building TinyUSB examples {tabulate(df, headers="keys", tablefmt='rst')} """ -- cgit v1.3.1 From 6b28a4478c9f8fa3993d593360eb5574bbdeda22 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 15 Nov 2025 19:46:14 +0700 Subject: make TUP_DCD_EDPT_ISO_ALLOC i.e dcd_edpt_iso_alloc()/dcd_edpt_iso_activate() as default driver implementation. dcd_edpt_close() is deprecated and will be removed from all driver in the future. --- docs/porting.rst | 10 + src/common/tusb_mcu.h | 335 ++++++++++++----------- src/device/dcd.h | 11 +- src/portable/bridgetek/ft9xx/dcd_ft9xx.c | 15 +- src/portable/chipidea/ci_fs/dcd_ci_fs.c | 18 +- src/portable/chipidea/ci_hs/dcd_ci_hs.c | 196 +++++++------ src/portable/dialog/da146xx/dcd_da146xx.c | 16 +- src/portable/microchip/pic/dcd_pic.c | 16 +- src/portable/microchip/pic32mz/dcd_pic32mz.c | 13 +- src/portable/microchip/samd/dcd_samd.c | 11 +- src/portable/microchip/samg/dcd_samg.c | 15 +- src/portable/microchip/samx7x/dcd_samx7x.c | 17 +- src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c | 299 ++++++++++---------- src/portable/nordic/nrf5x/dcd_nrf5x.c | 16 +- src/portable/nxp/khci/dcd_khci.c | 16 +- src/portable/nxp/lpc17_40/dcd_lpc17_40.c | 15 +- src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c | 16 +- src/portable/raspberrypi/pio_usb/dcd_pio_usb.c | 14 +- src/portable/renesas/rusb2/dcd_rusb2.c | 16 +- src/portable/sunxi/dcd_sunxi_musb.c | 16 +- src/portable/ti/msp430x5xx/dcd_msp430x5xx.c | 16 +- src/portable/valentyusb/eptri/dcd_eptri.c | 15 +- src/portable/wch/dcd_ch32_usbfs.c | 13 +- src/portable/wch/dcd_ch32_usbhs.c | 27 +- 24 files changed, 702 insertions(+), 450 deletions(-) (limited to 'docs') diff --git a/docs/porting.rst b/docs/porting.rst index c3076354c..9b60ec5a2 100644 --- a/docs/porting.rst +++ b/docs/porting.rst @@ -173,12 +173,22 @@ Also make sure to enable endpoint specific interrupts. ``dcd_edpt_close()`` """""""""""""""""""" +.. warning:: + This function is deprecated, ISO transfer should implement dcd_edpt_iso_alloc() and dcd_edpt_iso_activate() instead. + Close an endpoint. his function is used for implementing alternate settings. After calling this, the device should not respond to any packets directed towards this endpoint. When called, this function must abort any transfers in progress through this endpoint, before returning. Implementation is optional. Must be called from the USB task. Interrupts could be disabled or enabled during the call. +``dcd_edpt_iso_alloc() / dcd_edpt_iso_activate()`` +"""""""""""""""""""""""""""""""""""""""""""""""""" + +dcd_edpt_iso_alloc() is used to allocate largest buffer (for all alternative interfaces) for ISO endpoints when device is enumerated. This allows DCD to allocate necessary resources for ISO endpoints in the future. + +dcd_edpt_iso_activate() is used to activate or deactivate ISO endpoint when alternate setting is set with active max packet size. + ``dcd_edpt_xfer()`` """"""""""""""""""" diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index fd922ee56..05ae6929c 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -37,14 +37,14 @@ #ifdef __ARM_ARCH // ARM Architecture set __ARM_FEATURE_UNALIGNED to 1 for mcu supports unaligned access #if defined(__ARM_FEATURE_UNALIGNED) && __ARM_FEATURE_UNALIGNED == 1 - #define TUP_ARCH_STRICT_ALIGN 0 + #define TUP_ARCH_STRICT_ALIGN 0 #else - #define TUP_ARCH_STRICT_ALIGN 1 + #define TUP_ARCH_STRICT_ALIGN 1 #endif #else // TODO default to strict align for others // Should investigate other architecture such as risv, xtensa, mips for optimal setting - #define TUP_ARCH_STRICT_ALIGN 1 + #define TUP_ARCH_STRICT_ALIGN 1 #endif /* USB Controller Attributes for Device, Host or MCU (both) @@ -57,41 +57,41 @@ //--------------------------------------------------------------------+ // NXP //--------------------------------------------------------------------+ -#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) +#if TU_CHECK_MCU(OPT_MCU_LPC11UXX, OPT_MCU_LPC13XX, OPT_MCU_LPC15XX) #define TUP_USBIP_IP3511 - #define TUP_DCD_ENDPOINT_MAX 5 + #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC175X_6X, OPT_MCU_LPC177X_8X, OPT_MCU_LPC40XX) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP - #define TUP_OHCI_RHPORTS 2 + #define TUP_OHCI_RHPORTS 2 #elif TU_CHECK_MCU(OPT_MCU_LPC51UXX) - #define TUP_USBIP_IP3511 - #define TUP_DCD_ENDPOINT_MAX 5 + #define TUP_USBIP_IP3511 + #define TUP_DCD_ENDPOINT_MAX 5 #elif TU_CHECK_MCU(OPT_MCU_LPC54) // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC55) // TODO USB0 has 5, USB1 has 6 #define TUP_USBIP_IP3511 #define TUP_USBIP_OHCI #define TUP_USBIP_OHCI_NXP - #define TUP_OHCI_RHPORTS 1 // 1 downstream port + #define TUP_OHCI_RHPORTS 1 // 1 downstream port - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_LPC18XX, OPT_MCU_LPC43XX) // USB0 has 6 with HS PHY, USB1 has 4 only FS #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI - #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_MCXN9) // USB0 is chipidea FS @@ -102,15 +102,15 @@ #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_MCXA15) // USB0 is chipidea FS #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_MCX - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_MIMXRT1XXX) #include "fsl_device_registers.h" @@ -118,60 +118,61 @@ #define TUP_USBIP_CHIPIDEA_HS #define TUP_USBIP_EHCI - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 1 #if __CORTEX_M == 7 - #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT 1 - #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT 1 - #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 + #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT 1 + #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT 1 + #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #endif #elif TU_CHECK_MCU(OPT_MCU_KINETIS_KL, OPT_MCU_KINETIS_K32L, OPT_MCU_KINETIS_K) #define TUP_USBIP_CHIPIDEA_FS #define TUP_USBIP_CHIPIDEA_FS_KINETIS - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #elif TU_CHECK_MCU(OPT_MCU_MM32F327X) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // Nordic //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_NRF5X) // 8 CBI + 1 ISO - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_EDPT_CLOSE_API #elif TU_CHECK_MCU(OPT_MCU_NRF54) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_NRF - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 //--------------------------------------------------------------------+ // Microchip //--------------------------------------------------------------------+ -#elif TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML2X, OPT_MCU_SAMD21) || \ - TU_CHECK_MCU(OPT_MCU_SAMD51, OPT_MCU_SAME5X) - #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_SAMD11, OPT_MCU_SAML2X, OPT_MCU_SAMD21) || TU_CHECK_MCU(OPT_MCU_SAMD51, OPT_MCU_SAME5X) + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_SAMG) - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_SAMX7X) - #define TUP_DCD_ENDPOINT_MAX 10 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_PIC32MZ) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY -#elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || \ - TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) - #define TUP_DCD_ENDPOINT_MAX 16 +#elif TU_CHECK_MCU(OPT_MCU_PIC32MX, OPT_MCU_PIC32MM, OPT_MCU_PIC32MK) || TU_CHECK_MCU(OPT_MCU_PIC24, OPT_MCU_DSPIC33) + #define TUP_DCD_ENDPOINT_MAX 16 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY + #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // ST @@ -179,23 +180,23 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F1) // - F102, F103 use fsdev // - F105, F107 use dwc2 - #if defined (STM32F105x8) || defined (STM32F105xB) || defined (STM32F105xC) || \ - defined (STM32F107xB) || defined (STM32F107xC) + #if defined(STM32F105x8) || defined(STM32F105xB) || defined(STM32F105xC) || defined(STM32F107xB) || \ + defined(STM32F107xC) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 - #define TUP_DCD_ENDPOINT_MAX 4 - #elif defined(STM32F102x6) || defined(STM32F102xB) || \ - defined(STM32F103x6) || defined(STM32F103xB) || defined(STM32F103xE) || defined(STM32F103xG) + #define TUP_DCD_ENDPOINT_MAX 4 + #elif defined(STM32F102x6) || defined(STM32F102xB) || defined(STM32F103x6) || defined(STM32F103xB) || \ + defined(STM32F103xE) || defined(STM32F103xG) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #else #error "Unsupported STM32F1 mcu" #endif @@ -205,55 +206,55 @@ #define TUP_USBIP_DWC2_STM32 // FS has 4 ep, HS has 5 ep - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32F4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // For most mcu, FS has 4, HS has 6. TODO 446/469/479 HS has 9 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_STM32F7) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 6, HS has 9 - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 // MCU with on-chip HS Phy #if defined(STM32F723xx) || defined(STM32F730xx) || defined(STM32F733xx) - #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS + #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif // Enable dcache if DMA is enabled - #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE - #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE - #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 + #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE + #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE + #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #elif TU_CHECK_MCU(OPT_MCU_STM32H7) #include "stm32h7xx.h" #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 #if __CORTEX_M == 7 // Enable dcache if DMA is enabled - #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE - #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE - #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 + #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE + #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE + #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 32 #endif #elif TU_CHECK_MCU(OPT_MCU_STM32H5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32G4) // Device controller @@ -262,41 +263,40 @@ // TypeC controller #define TUP_USBIP_TYPEC_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #define TUP_TYPEC_RHPORTS_NUM 1 #elif TU_CHECK_MCU(OPT_MCU_STM32G0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32C0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L0, OPT_MCU_STM32L1) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32L4) // - L4x2, L4x3 use fsdev // - L4x4, L4x6, L4x7, L4x9 use dwc2 - #if defined (STM32L475xx) || defined (STM32L476xx) || \ - defined (STM32L485xx) || defined (STM32L486xx) || defined (STM32L496xx) || \ - defined (STM32L4A6xx) || defined (STM32L4P5xx) || defined (STM32L4Q5xx) || \ - defined (STM32L4R5xx) || defined (STM32L4R7xx) || defined (STM32L4R9xx) || \ - defined (STM32L4S5xx) || defined (STM32L4S7xx) || defined (STM32L4S9xx) + #if defined(STM32L475xx) || defined(STM32L476xx) || defined(STM32L485xx) || defined(STM32L486xx) || \ + defined(STM32L496xx) || defined(STM32L4A6xx) || defined(STM32L4P5xx) || defined(STM32L4Q5xx) || \ + defined(STM32L4R5xx) || defined(STM32L4R7xx) || defined(STM32L4R9xx) || defined(STM32L4S5xx) || \ + defined(STM32L4S7xx) || defined(STM32L4S9xx) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #elif defined(STM32L412xx) || defined(STM32L422xx) || defined(STM32L432xx) || defined(STM32L433xx) || \ - defined(STM32L442xx) || defined(STM32L443xx) || defined(STM32L452xx) || defined(STM32L462xx) + defined(STM32L442xx) || defined(STM32L443xx) || defined(STM32L452xx) || defined(STM32L462xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #else #error "Unsupported STM32L4 mcu" #endif @@ -304,19 +304,19 @@ #elif TU_CHECK_MCU(OPT_MCU_STM32WB) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32WBA) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 - #define TUP_DCD_ENDPOINT_MAX 9 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 #elif TU_CHECK_MCU(OPT_MCU_STM32U5) - #if defined (STM32U535xx) || defined (STM32U545xx) + #if defined(STM32U535xx) || defined(STM32U545xx) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #else #define TUP_USBIP_DWC2 @@ -324,38 +324,38 @@ // U59x/5Ax/5Fx/5Gx are highspeed with built-in HS PHY #if defined(STM32U595xx) || defined(STM32U599xx) || defined(STM32U5A5xx) || defined(STM32U5A9xx) || \ - defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) - #define TUP_DCD_ENDPOINT_MAX 9 - #define TUP_RHPORT_HIGHSPEED 1 + defined(STM32U5F7xx) || defined(STM32U5F9xx) || defined(STM32U5G7xx) || defined(STM32U5G9xx) + #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_RHPORT_HIGHSPEED 1 #else - #define TUP_DCD_ENDPOINT_MAX 6 + #define TUP_DCD_ENDPOINT_MAX 6 #endif #endif #elif TU_CHECK_MCU(OPT_MCU_STM32L5) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32U3) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_STM32H7RS, OPT_MCU_STM32N6) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_STM32 // FS has 6, HS has 9 - #define TUP_DCD_ENDPOINT_MAX 9 + #define TUP_DCD_ENDPOINT_MAX 9 // MCU with on-chip HS Phy - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_RHPORT_HIGHSPEED 1 // Enable dcache if DMA is enabled #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE @@ -366,43 +366,39 @@ // Sony //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_CXD56) - #define TUP_DCD_ENDPOINT_MAX 7 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY - #define TUP_DCD_EDPT_ISO_ALLOC //--------------------------------------------------------------------+ // TI //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_MSP430x5xx) - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_MSP432E4, OPT_MCU_TM4C123, OPT_MCU_TM4C129) #define TUP_USBIP_MUSB #define TUP_USBIP_MUSB_TI - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ // ValentyUSB (Litex) //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_VALENTYUSB_EPTRI) - #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_DCD_ENDPOINT_MAX 16 //--------------------------------------------------------------------+ // Nuvoton //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_NUC121, OPT_MCU_NUC126) - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_DCD_EDPT_ISO_ALLOC + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_NUC120) - #define TUP_DCD_ENDPOINT_MAX 6 - #define TUP_DCD_EDPT_ISO_ALLOC + #define TUP_DCD_ENDPOINT_MAX 6 #elif TU_CHECK_MCU(OPT_MCU_NUC505) - #define TUP_DCD_ENDPOINT_MAX 12 - #define TUP_RHPORT_HIGHSPEED 1 - #define TUP_DCD_EDPT_ISO_ALLOC + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 1 //--------------------------------------------------------------------+ // Espressif @@ -410,114 +406,124 @@ #elif TU_CHECK_MCU(OPT_MCU_ESP32S2, OPT_MCU_ESP32S3, OPT_MCU_ESP32H4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN - #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + #define TUP_DCD_ENDPOINT_MAX 7 // only 5 TX FIFO for endpoint IN + + // clang-format off + #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + // clang-format on #if CFG_TUSB_MCU == OPT_MCU_ESP32S3 #define TUP_MCU_MULTIPLE_CORE 1 #endif // Disable slave if DMA is enabled - #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE - #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE + #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE + #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE #elif TU_CHECK_MCU(OPT_MCU_ESP32P4) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_ESP32 - #define TUP_RHPORT_HIGHSPEED 1 // port0 FS, port1 HS - #define TUP_DCD_ENDPOINT_MAX 16 // FS 7 ep, HS 16 ep + #define TUP_RHPORT_HIGHSPEED 1 // port0 FS, port1 HS + #define TUP_DCD_ENDPOINT_MAX 16 // FS 7 ep, HS 16 ep - #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + // clang-format off + #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + // clang-format on - #define TUP_MCU_MULTIPLE_CORE 1 + #define TUP_MCU_MULTIPLE_CORE 1 // Disable slave if DMA is enabled - #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE - #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE + #define CFG_TUD_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUD_DWC2_DMA_ENABLE + #define CFG_TUH_DWC2_SLAVE_ENABLE_DEFAULT !CFG_TUH_DWC2_DMA_ENABLE // Enable dcache if DMA is enabled - #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE - #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE - #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 64 + #define CFG_TUD_MEM_DCACHE_ENABLE_DEFAULT CFG_TUD_DWC2_DMA_ENABLE + #define CFG_TUH_MEM_DCACHE_ENABLE_DEFAULT CFG_TUH_DWC2_DMA_ENABLE + #define CFG_TUSB_MEM_DCACHE_LINE_SIZE_DEFAULT 64 -#elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C5, OPT_MCU_ESP32C6, OPT_MCU_ESP32C61, OPT_MCU_ESP32H2) +#elif TU_CHECK_MCU(OPT_MCU_ESP32, OPT_MCU_ESP32C2, OPT_MCU_ESP32C3, OPT_MCU_ESP32C5, OPT_MCU_ESP32C6, \ + OPT_MCU_ESP32C61, OPT_MCU_ESP32H2) #if (CFG_TUD_ENABLED || !(defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421)) - #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" + #error "MCUs are only supported with CFG_TUH_MAX3421 enabled" #endif - #define TUP_DCD_ENDPOINT_MAX 0 - #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + #define TUP_DCD_ENDPOINT_MAX 0 + + // clang-format off + #define CFG_TUSB_OS_INC_PATH_DEFAULT freertos/ + // clang-format on + //--------------------------------------------------------------------+ // Dialog //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_DA1469X) - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_EDPT_CLOSE_API //--------------------------------------------------------------------+ // Raspberry Pi //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RP2040) - #define TUP_DCD_EDPT_ISO_ALLOC - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_MCU_MULTIPLE_CORE 1 + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_MCU_MULTIPLE_CORE 1 - #define TU_ATTR_FAST_FUNC __not_in_flash("tinyusb") + #define TU_ATTR_FAST_FUNC __not_in_flash("tinyusb") //--------------------------------------------------------------------+ // Silabs //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_EFM32GG) #define TUP_USBIP_DWC2 - #define TUP_DCD_ENDPOINT_MAX 7 + #define TUP_DCD_ENDPOINT_MAX 7 //--------------------------------------------------------------------+ // Renesas //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_RX63X, OPT_MCU_RX65X, OPT_MCU_RX72N, OPT_MCU_RAXXX) #define TUP_USBIP_RUSB2 - #define TUP_DCD_ENDPOINT_MAX 10 + #define TUP_DCD_ENDPOINT_MAX 10 //--------------------------------------------------------------------+ // GigaDevice //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_GD32VF103) #define TUP_USBIP_DWC2 - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 //--------------------------------------------------------------------+ // Broadcom //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_BCM2711, OPT_MCU_BCM2835, OPT_MCU_BCM2837) #define TUP_USBIP_DWC2 - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 1 //--------------------------------------------------------------------+ // Infineon //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_XMC4000) #define TUP_USBIP_DWC2 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 //--------------------------------------------------------------------+ // BridgeTek //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_FT90X) - #define TUP_DCD_ENDPOINT_MAX 8 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY #elif TU_CHECK_MCU(OPT_MCU_FT93X) - #define TUP_DCD_ENDPOINT_MAX 16 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ // Allwinner //--------------------------------------------------------------------+ #elif TU_CHECK_MCU(OPT_MCU_F1C100S) - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 //--------------------------------------------------------------------+ // WCH @@ -527,31 +533,31 @@ #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) - #define CFG_TUD_WCH_USBIP_USBFS 0 + #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_USBHS) - #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif - #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) #elif TU_CHECK_MCU(OPT_MCU_CH32V103) #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) - #define CFG_TUD_WCH_USBIP_USBFS 1 + #define CFG_TUD_WCH_USBIP_USBFS 1 #endif - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_CH32V20X) // v20x support both port0 FSDEV (USBD) and port1 USBFS #define TUP_USBIP_WCH_USBFS #ifndef CFG_TUH_WCH_USBIP_USBFS - #define CFG_TUH_WCH_USBIP_USBFS 1 + #define CFG_TUH_WCH_USBIP_USBFS 1 #endif #define TUP_USBIP_FSDEV @@ -559,14 +565,14 @@ // default to FSDEV for device #if !defined(CFG_TUD_WCH_USBIP_USBFS) - #define CFG_TUD_WCH_USBIP_USBFS 0 + #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_FSDEV) - #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #define CFG_TUD_WCH_USBIP_FSDEV (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_CH32V307) // v307 support both FS and HS, default to HS @@ -574,15 +580,15 @@ #define TUP_USBIP_WCH_USBFS #if !defined(CFG_TUD_WCH_USBIP_USBFS) - #define CFG_TUD_WCH_USBIP_USBFS 0 + #define CFG_TUD_WCH_USBIP_USBFS 0 #endif #if !defined(CFG_TUD_WCH_USBIP_USBHS) - #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) + #define CFG_TUD_WCH_USBIP_USBHS (CFG_TUD_WCH_USBIP_USBFS ? 0 : 1) #endif - #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS - #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) + #define TUP_RHPORT_HIGHSPEED CFG_TUD_WCH_USBIP_USBHS + #define TUP_DCD_ENDPOINT_MAX (CFG_TUD_WCH_USBIP_USBHS ? 16 : 8) //--------------------------------------------------------------------+ // Analog Devices @@ -590,8 +596,8 @@ #elif TU_CHECK_MCU(OPT_MCU_MAX32650, OPT_MCU_MAX32666, OPT_MCU_MAX32690, OPT_MCU_MAX78002) #define TUP_USBIP_MUSB #define TUP_USBIP_MUSB_ADI - #define TUP_DCD_ENDPOINT_MAX 12 - #define TUP_RHPORT_HIGHSPEED 1 + #define TUP_DCD_ENDPOINT_MAX 12 + #define TUP_RHPORT_HIGHSPEED 1 #define TUD_ENDPOINT_ONE_DIRECTION_ONLY //--------------------------------------------------------------------+ @@ -600,46 +606,44 @@ #elif TU_CHECK_MCU(OPT_MCU_AT32F403A_407) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_AT32F413) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_AT32F415) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 4 + #define TUP_DCD_ENDPOINT_MAX 4 #elif TU_CHECK_MCU(OPT_MCU_AT32F435_437) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_AT32F423) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #elif TU_CHECK_MCU(OPT_MCU_AT32F402_405) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 // AT32F405xx has on-chip HS PHY - #if defined(AT32F405CBT7) || defined(AT32F405CBU7) || \ - defined(AT32F405CCT7) || defined(AT32F405CCU7) || \ - defined(AT32F405KBU7_4) || defined(AT32F405KCU7_4) || \ - defined(AT32F405RBT7_7) || defined(AT32F405RBT7) || \ - defined(AT32F405RCT7_7) || defined(AT32F405RCT7) - #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS + #if defined(AT32F405CBT7) || defined(AT32F405CBU7) || defined(AT32F405CCT7) || defined(AT32F405CCU7) || \ + defined(AT32F405KBU7_4) || defined(AT32F405KCU7_4) || defined(AT32F405RBT7_7) || defined(AT32F405RBT7) || \ + defined(AT32F405RCT7_7) || defined(AT32F405RCT7) + #define TUP_RHPORT_HIGHSPEED 1 // Port0: FS, Port1: HS #endif #elif TU_CHECK_MCU(OPT_MCU_AT32F425) #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_AT32 - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif @@ -649,7 +653,7 @@ #if defined(CFG_TUH_MAX3421) && CFG_TUH_MAX3421 #ifndef CFG_TUH_MAX3421_ENDPOINT_TOTAL - #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4*(CFG_TUH_DEVICE_MAX-1)) + #define CFG_TUH_MAX3421_ENDPOINT_TOTAL (8 + 4 * (CFG_TUH_DEVICE_MAX - 1)) #endif #endif @@ -659,17 +663,17 @@ //--------------------------------------------------------------------+ #ifndef TUP_MCU_MULTIPLE_CORE -#define TUP_MCU_MULTIPLE_CORE 0 + #define TUP_MCU_MULTIPLE_CORE 0 #endif #if !defined(TUP_DCD_ENDPOINT_MAX) && defined(CFG_TUD_ENABLED) && CFG_TUD_ENABLED #warning "TUP_DCD_ENDPOINT_MAX is not defined for this MCU, default to 8" - #define TUP_DCD_ENDPOINT_MAX 8 + #define TUP_DCD_ENDPOINT_MAX 8 #endif // Default to fullspeed if not defined #ifndef TUP_RHPORT_HIGHSPEED - #define TUP_RHPORT_HIGHSPEED 0 + #define TUP_RHPORT_HIGHSPEED 0 #endif // fast function, normally mean placing function in SRAM @@ -677,8 +681,13 @@ #define TU_ATTR_FAST_FUNC #endif -// USBIP that support ISO alloc & activate API -#if defined(TUP_USBIP_DWC2) || defined(TUP_USBIP_FSDEV) || defined(TUP_USBIP_MUSB) +#if defined(TUP_USBIP_CHIPIDEA_FS) || defined(TUP_USBIP_IP3511) || defined(TUP_USBIP_RUSB2) || \ + (defined(TUP_USBIP_WCH_USBFS) && CFG_TUD_WCH_USBIP_USBFS) + #define TUP_DCD_EDPT_CLOSE_API +#endif + +// USBIP implement dcd_edpt_close() and does not support ISO alloc & activate API +#ifndef TUP_DCD_EDPT_CLOSE_API #define TUP_DCD_EDPT_ISO_ALLOC #endif diff --git a/src/device/dcd.h b/src/device/dcd.h index 1b0289280..353f836ee 100644 --- a/src/device/dcd.h +++ b/src/device/dcd.h @@ -171,7 +171,12 @@ void dcd_edpt_stall (uint8_t rhport, uint8_t ep_addr); // This API never calls with control endpoints, since it is auto cleared when receiving setup packet void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr); -#ifdef TUP_DCD_EDPT_ISO_ALLOC +#ifdef TUP_DCD_EDPT_CLOSE_API +// Close an endpoint. +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); + +#else + // Allocate packet buffer used by ISO endpoints // Some MCU need manual packet buffer allocation, we allocate the largest size to avoid clustering bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size); @@ -179,10 +184,6 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet // Configure and enable an ISO endpoint according to descriptor bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep); -#else -// Close an endpoint. -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr); - #endif //--------------------------------------------------------------------+ diff --git a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c index 34a8be3b6..6ed4be410 100644 --- a/src/portable/bridgetek/ft9xx/dcd_ft9xx.c +++ b/src/portable/bridgetek/ft9xx/dcd_ft9xx.c @@ -806,6 +806,20 @@ void dcd_edpt_close_all(uint8_t rhport) _ft9xx_reset_edpts(); } +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} + + // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { @@ -1200,5 +1214,4 @@ void ft9xx_usbd_pm_ISR(void) } } } - #endif diff --git a/src/portable/chipidea/ci_fs/dcd_ci_fs.c b/src/portable/chipidea/ci_fs/dcd_ci_fs.c index 11ddb683f..8b5c42aa2 100644 --- a/src/portable/chipidea/ci_fs/dcd_ci_fs.c +++ b/src/portable/chipidea/ci_fs/dcd_ci_fs.c @@ -399,6 +399,7 @@ void dcd_edpt_close_all(uint8_t rhport) } } +#ifdef TUP_DCD_EDPT_CLOSE_API void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { const unsigned epn = tu_edpt_number(ep_addr); @@ -419,6 +420,22 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) dcd_int_enable(rhport); } +#else + +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} +#endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { const unsigned epn = tu_edpt_number(ep_addr); @@ -564,5 +581,4 @@ void dcd_int_handler(uint8_t rhport) process_tokdne(rhport); } } - #endif diff --git a/src/portable/chipidea/ci_hs/dcd_ci_hs.c b/src/portable/chipidea/ci_hs/dcd_ci_hs.c index 244f5a2d4..8c5253eb9 100644 --- a/src/portable/chipidea/ci_hs/dcd_ci_hs.c +++ b/src/portable/chipidea/ci_hs/dcd_ci_hs.c @@ -64,16 +64,19 @@ bool dcd_dcache_clean_invalidate(void const* addr, uint32_t data_size) { //--------------------------------------------------------------------+ // ENDPTCTRL +enum { + ENDPTCTRL_TYPE_POS = 2, // Endpoint type is 2-bit field +}; + enum { ENDPTCTRL_STALL = TU_BIT(0), ENDPTCTRL_TOGGLE_INHIBIT = TU_BIT(5), // used for test only ENDPTCTRL_TOGGLE_RESET = TU_BIT(6), - ENDPTCTRL_ENABLE = TU_BIT(7) + ENDPTCTRL_ENABLE = TU_BIT(7), }; -enum { - ENDPTCTRL_TYPE_POS = 2, // Endpoint type is 2-bit field -}; +#define ENDPTCTRL_TYPE(_type) ((_type) << ENDPTCTRL_TYPE_POS) + #define ENDPTCTRL_RESET_MASK (ENDPTCTRL_TYPE(TUSB_XFER_BULK) | (ENDPTCTRL_TYPE(TUSB_XFER_BULK) << 16u)) // USBSTS, USBINTR enum { @@ -170,9 +173,7 @@ static dcd_data_t _dcd_data; // Prototypes and Helper Functions //--------------------------------------------------------------------+ -TU_ATTR_ALWAYS_INLINE -static inline uint8_t ci_ep_count(ci_hs_regs_t const* dcd_reg) -{ +TU_ATTR_ALWAYS_INLINE static inline uint8_t ci_ep_count(const ci_hs_regs_t *dcd_reg) { return dcd_reg->DCCPARAMS & DCCPARAMS_DEN_MASK; } @@ -191,9 +192,8 @@ static void bus_reset(uint8_t rhport) // type (e.g. bulk). Leaving an un-configured endpoint control will cause undefined behavior // for the data PID tracking on the active endpoint. uint8_t const ep_count = ci_ep_count(dcd_reg); - for( uint8_t i=1; i < ep_count; i++) - { - dcd_reg->ENDPTCTRL[i] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); + for (uint8_t i = 1; i < ep_count; i++) { + dcd_reg->ENDPTCTRL[i] = ENDPTCTRL_RESET_MASK; } //------------- Clear All Registers -------------// @@ -315,26 +315,25 @@ void dcd_sof_enable(uint8_t rhport, bool en) // HELPER //--------------------------------------------------------------------+ -static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) -{ - dcd_dcache_clean_invalidate((uint32_t*) tu_align((uint32_t) data_ptr, 4), total_bytes); +static void qtd_init(dcd_qtd_t *p_qtd, void *data_ptr, uint16_t total_bytes) { + dcd_dcache_clean_invalidate((uint32_t *)tu_align((uint32_t)data_ptr, 4), total_bytes); tu_memclr(p_qtd, sizeof(dcd_qtd_t)); - p_qtd->next = QTD_NEXT_INVALID; - p_qtd->active = 1; - p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; - p_qtd->int_on_complete = true; + p_qtd->next = QTD_NEXT_INVALID; + p_qtd->active = 1; + p_qtd->total_bytes = p_qtd->expected_bytes = total_bytes; + p_qtd->int_on_complete = true; - if (data_ptr != NULL) - { - p_qtd->buffer[0] = (uint32_t) data_ptr; + if (data_ptr != NULL) { + p_qtd->buffer[0] = (uint32_t)data_ptr; - uint32_t const bufend = p_qtd->buffer[0] + total_bytes; - for(uint8_t i=1; i<5; i++) - { - uint32_t const next_page = tu_align4k( p_qtd->buffer[i-1] ) + 4096; - if ( bufend <= next_page ) break; + const uint32_t bufend = p_qtd->buffer[0] + total_bytes; + for (uint8_t i = 1; i < 5; i++) { + const uint32_t next_page = tu_align4k(p_qtd->buffer[i - 1]) + 4096; + if (bufend <= next_page) { + break; + } p_qtd->buffer[i] = next_page; @@ -346,6 +345,35 @@ static void qtd_init(dcd_qtd_t* p_qtd, void * data_ptr, uint16_t total_bytes) //--------------------------------------------------------------------+ // DCD Endpoint Port //--------------------------------------------------------------------+ +TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_write(volatile uint32_t *epctrl, uint8_t dir, uint32_t value) { + if (dir == TUSB_DIR_OUT) { + *epctrl = (*epctrl & 0xFFFF0000u) | value; + } else { + *epctrl = (*epctrl & 0x0000FFFFu) | (value << 16); + } +} + +TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_mask(volatile uint32_t *epctrl, uint8_t dir, uint32_t and_mask, + uint32_t or_mask) { + uint32_t value = *epctrl; + if (and_mask != 0) { + value &= (dir == TUSB_DIR_OUT) ? and_mask : (and_mask << 16u); + } + if (or_mask != 0) { + value |= (dir == TUSB_DIR_OUT) ? or_mask : (or_mask << 16u); + } + + *epctrl = value; +} + +TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_set(volatile uint32_t *epctrl, uint8_t dir, uint32_t mask) { + ep_ctrl_mask(epctrl, dir, 0, mask); +} + +TU_ATTR_ALWAYS_INLINE static inline void ep_ctrl_clear(volatile uint32_t *epctrl, uint8_t dir, uint32_t mask) { + ep_ctrl_mask(epctrl, dir, ~mask, 0); +} + void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { uint8_t const epnum = tu_edpt_number(ep_addr); @@ -366,80 +394,91 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) // data toggle also need to be reset ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); dcd_reg->ENDPTCTRL[epnum] |= ENDPTCTRL_TOGGLE_RESET << ( dir ? 16 : 0 ); - dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << ( dir ? 16 : 0)); + dcd_reg->ENDPTCTRL[epnum] &= ~(ENDPTCTRL_STALL << (dir ? 16 : 0)); } -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) -{ - uint8_t const epnum = tu_edpt_number(p_endpoint_desc->bEndpointAddress); - uint8_t const dir = tu_edpt_dir(p_endpoint_desc->bEndpointAddress); - - ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); - - // Must not exceed max endpoint number - TU_ASSERT(epnum < ci_ep_count(dcd_reg)); - - //------------- Prepare Queue Head -------------// - dcd_qhd_t * p_qhd = &_dcd_data.qhd[epnum][dir]; +static void qhd_init(dcd_qhd_t *p_qhd, uint16_t max_packet_size, uint8_t iso_mult) { tu_memclr(p_qhd, sizeof(dcd_qhd_t)); - p_qhd->zero_length_termination = 1; - p_qhd->max_packet_size = tu_edpt_packet_size(p_endpoint_desc); - if (p_endpoint_desc->bmAttributes.xfer == TUSB_XFER_ISOCHRONOUS) - { - p_qhd->iso_mult = 1; - } - + p_qhd->max_packet_size = max_packet_size; + p_qhd->iso_mult = iso_mult; p_qhd->qtd_overlay.next = QTD_NEXT_INVALID; - dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); +} - // Enable EP Control - uint32_t const epctrl = (p_endpoint_desc->bmAttributes.xfer << ENDPTCTRL_TYPE_POS) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; +bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *endpoint_desc) { + ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); + const uint8_t epnum = tu_edpt_number(endpoint_desc->bEndpointAddress); + const uint8_t dir = tu_edpt_dir(endpoint_desc->bEndpointAddress); + const uint8_t xfer_type = endpoint_desc->bmAttributes.xfer; + TU_ASSERT(epnum < ci_ep_count(dcd_reg)); - if ( dir == TUSB_DIR_OUT ) - { - dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0xFFFF0000u) | epctrl; - }else - { - dcd_reg->ENDPTCTRL[epnum] = (dcd_reg->ENDPTCTRL[epnum] & 0x0000FFFFu) | (epctrl << 16); - } + dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; + qhd_init(p_qhd, tu_edpt_packet_size(endpoint_desc), 0u); + + // EP Control + const uint32_t epctrl = ENDPTCTRL_TYPE(xfer_type) | ENDPTCTRL_ENABLE | ENDPTCTRL_TOGGLE_RESET; + ep_ctrl_write(&dcd_reg->ENDPTCTRL[epnum], dir, epctrl); return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ - ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; - // Disable all non-control endpoints - uint8_t const ep_count = ci_ep_count(dcd_reg); - for (uint8_t epnum = 1; epnum < ep_count; epnum++) - { - _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; - _dcd_data.qhd[epnum][TUSB_DIR_IN ].qtd_overlay.halted = 1; + ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); + const uint8_t epnum = tu_edpt_number(ep_addr); + const uint8_t dir = tu_edpt_dir(ep_addr); + TU_ASSERT(epnum < ci_ep_count(dcd_reg)); - dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum+16); - dcd_reg->ENDPTCTRL[epnum] = (TUSB_XFER_BULK << ENDPTCTRL_TYPE_POS) | (TUSB_XFER_BULK << (16+ENDPTCTRL_TYPE_POS)); - } + // EP Control: set type but not enabled yet + const uint32_t epctrl = ENDPTCTRL_TYPE(TUSB_XFER_ISOCHRONOUS) | ENDPTCTRL_TOGGLE_RESET; + ep_ctrl_write(&dcd_reg->ENDPTCTRL[epnum], dir, epctrl); + + return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - uint8_t const epnum = tu_edpt_number(ep_addr); - uint8_t const dir = tu_edpt_dir(ep_addr); +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + const uint8_t epnum = tu_edpt_number(desc_ep->bEndpointAddress); + const uint8_t dir = tu_edpt_dir(desc_ep->bEndpointAddress); + ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); + TU_ASSERT(epnum < ci_ep_count(dcd_reg)); - ci_hs_regs_t* dcd_reg = CI_HS_REG(rhport); + dcd_qhd_t *p_qhd = &_dcd_data.qhd[epnum][dir]; + volatile uint32_t *endptctrl = &dcd_reg->ENDPTCTRL[epnum]; - _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; + // _dcd_data.qhd[epnum][dir].qtd_overlay.halted = 1; + // dcd_dcache_clean_invalidate(&_dcd_data, sizeof(dcd_data_t)); // Flush EP - uint32_t const flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); - dcd_reg->ENDPTFLUSH = flush_mask; - while(dcd_reg->ENDPTFLUSH & flush_mask); + const uint32_t flush_mask = TU_BIT(epnum + (dir ? 16 : 0)); + dcd_reg->ENDPTFLUSH = flush_mask; + while (dcd_reg->ENDPTFLUSH & flush_mask) {} + + // disable to change max packet size + ep_ctrl_clear(endptctrl, dir, ENDPTCTRL_ENABLE); - // Clear EP enable - dcd_reg->ENDPTCTRL[epnum] &=~(ENDPTCTRL_ENABLE << (dir ? 16 : 0)); + qhd_init(p_qhd, tu_edpt_packet_size(desc_ep), 1u); + + ep_ctrl_set(endptctrl, dir, ENDPTCTRL_ENABLE); + + return true; +} + +void dcd_edpt_close_all(uint8_t rhport) { + ci_hs_regs_t *dcd_reg = CI_HS_REG(rhport); + + // Disable all non-control endpoints + uint8_t const ep_count = ci_ep_count(dcd_reg); + for (uint8_t epnum = 1; epnum < ep_count; epnum++) { + _dcd_data.qhd[epnum][TUSB_DIR_OUT].qtd_overlay.halted = 1; + _dcd_data.qhd[epnum][TUSB_DIR_IN].qtd_overlay.halted = 1; + + dcd_reg->ENDPTFLUSH = TU_BIT(epnum) | TU_BIT(epnum + 16); + dcd_reg->ENDPTCTRL[epnum] = ENDPTCTRL_RESET_MASK; + } } static void qhd_start_xfer(uint8_t rhport, uint8_t epnum, uint8_t dir) @@ -678,5 +717,4 @@ void dcd_int_handler(uint8_t rhport) dcd_event_sof(rhport, frame, true); } } - #endif diff --git a/src/portable/dialog/da146xx/dcd_da146xx.c b/src/portable/dialog/da146xx/dcd_da146xx.c index 56ecb7575..868a10dd9 100644 --- a/src/portable/dialog/da146xx/dcd_da146xx.c +++ b/src/portable/dialog/da146xx/dcd_da146xx.c @@ -1025,6 +1025,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) tu_memclr(xfer, sizeof(*xfer)); } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} +#endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { uint8_t const epnum = tu_edpt_number(ep_addr); @@ -1218,5 +1233,4 @@ void dcd_int_handler(uint8_t rhport) handle_alt_ev(); } } - #endif diff --git a/src/portable/microchip/pic/dcd_pic.c b/src/portable/microchip/pic/dcd_pic.c index b4a698199..8413a7ddd 100644 --- a/src/portable/microchip/pic/dcd_pic.c +++ b/src/portable/microchip/pic/dcd_pic.c @@ -687,6 +687,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) if (ie) intr_enable(rhport); } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} +#endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { @@ -866,5 +881,4 @@ void dcd_int_handler(uint8_t rhport) intr_clear(rhport); } - #endif diff --git a/src/portable/microchip/pic32mz/dcd_pic32mz.c b/src/portable/microchip/pic32mz/dcd_pic32mz.c index cbd157d6b..b039bb505 100644 --- a/src/portable/microchip/pic32mz/dcd_pic32mz.c +++ b/src/portable/microchip/pic32mz/dcd_pic32mz.c @@ -438,12 +438,20 @@ void dcd_edpt_close_all (uint8_t rhport) } } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { uint8_t const epnum = tu_edpt_number(ep_addr); @@ -744,5 +752,4 @@ void dcd_int_handler(uint8_t rhport) } } } - #endif diff --git a/src/portable/microchip/samd/dcd_samd.c b/src/portable/microchip/samd/dcd_samd.c index e43439f2a..383cf60e5 100644 --- a/src/portable/microchip/samd/dcd_samd.c +++ b/src/portable/microchip/samd/dcd_samd.c @@ -245,11 +245,17 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return true; } -void dcd_edpt_close (uint8_t rhport, uint8_t ep_addr) { +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; + (void)largest_packet_size; + return false; +} - // TODO: implement if necessary? +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } void dcd_edpt_close_all (uint8_t rhport) @@ -427,5 +433,4 @@ void dcd_int_handler (uint8_t rhport) // Handle complete transfer maybe_transfer_complete(); } - #endif diff --git a/src/portable/microchip/samg/dcd_samg.c b/src/portable/microchip/samg/dcd_samg.c index a5c768839..879b2eb2b 100644 --- a/src/portable/microchip/samg/dcd_samg.c +++ b/src/portable/microchip/samg/dcd_samg.c @@ -270,9 +270,17 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; (void) ep_addr; - // TODO implement dcd_edpt_close() +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } void dcd_edpt_close_all (uint8_t rhport) @@ -494,5 +502,4 @@ void dcd_int_handler(uint8_t rhport) } } } - #endif diff --git a/src/portable/microchip/samx7x/dcd_samx7x.c b/src/portable/microchip/samx7x/dcd_samx7x.c index 8aec1568d..51308f7a2 100644 --- a/src/portable/microchip/samx7x/dcd_samx7x.c +++ b/src/portable/microchip/samx7x/dcd_samx7x.c @@ -559,15 +559,17 @@ void dcd_edpt_close_all (uint8_t rhport) // TODO implement dcd_edpt_close_all() } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; - uint8_t const epnum = tu_edpt_number(ep_addr); + (void) ep_addr; + (void) largest_packet_size; + return false; +} - // Disable endpoint interrupt - USB_REG->DEVIDR = 1 << (DEVIDR_PEP_0_Pos + epnum); - // Disable EP - USB_REG->DEVEPT &=~(1 << (DEVEPT_EPEN0_Pos + epnum)); +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; } static void dcd_transmit_packet(xfer_ctl_t * xfer, uint8_t ep_ix) @@ -773,5 +775,4 @@ void dcd_edpt_clear_stall (uint8_t rhport, uint8_t ep_addr) USB_REG->DEVEPTIDR[epnum] = DEVEPTIDR_CTRL_STALLRQC; USB_REG->DEVEPTIER[epnum] = HSTPIPIER_RSTDTS; } - #endif diff --git a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c index 1ce3da27e..a232810a2 100644 --- a/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c +++ b/src/portable/mindmotion/mm32/dcd_mm32f327x_otg.c @@ -26,7 +26,7 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && ( CFG_TUSB_MCU == OPT_MCU_MM32F327X ) +#if CFG_TUD_ENABLED && (CFG_TUSB_MCU == OPT_MCU_MM32F327X) #include "reg_usb_otg_fs.h" #include "mm32_device.h" @@ -43,56 +43,53 @@ enum { TOK_PID_SETUP = 0xDu, }; -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { union { uint32_t head; struct { union { struct { - uint16_t : 2; - uint16_t tok_pid : 4; - uint16_t data : 1; - uint16_t own : 1; - uint16_t : 8; + uint16_t : 2; + uint16_t tok_pid : 4; + uint16_t data : 1; + uint16_t own : 1; + uint16_t : 8; }; struct { - uint16_t : 2; - uint16_t bdt_stall: 1; - uint16_t dts : 1; - uint16_t ninc : 1; - uint16_t keep : 1; - uint16_t : 10; + uint16_t : 2; + uint16_t bdt_stall : 1; + uint16_t dts : 1; + uint16_t ninc : 1; + uint16_t keep : 1; + uint16_t : 10; }; }; - uint16_t bc : 10; - uint16_t : 6; + uint16_t bc : 10; + uint16_t : 6; }; }; uint8_t *addr; -}buffer_descriptor_t; +} buffer_descriptor_t; -TU_VERIFY_STATIC( sizeof(buffer_descriptor_t) == 8, "size is not correct" ); +TU_VERIFY_STATIC(sizeof(buffer_descriptor_t) == 8, "size is not correct"); -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { union { uint32_t state; struct { - uint32_t max_packet_size :11; + uint32_t max_packet_size : 11; uint32_t : 5; uint32_t odd : 1; - uint32_t :15; + uint32_t : 15; }; }; uint16_t length; uint16_t remaining; -}endpoint_state_t; +} endpoint_state_t; -TU_VERIFY_STATIC( sizeof(endpoint_state_t) == 8, "size is not correct" ); +TU_VERIFY_STATIC(sizeof(endpoint_state_t) == 8, "size is not correct"); -typedef struct -{ +typedef struct { union { /* [#EP][OUT,IN][EVEN,ODD] */ buffer_descriptor_t bdt[16][2][2]; @@ -104,7 +101,7 @@ typedef struct }; uint8_t setup_packet[8]; uint8_t addr; -}dcd_data_t; +} dcd_data_t; //--------------------------------------------------------------------+ // INTERNAL OBJECT & FUNCTION DECLARATION @@ -112,10 +109,9 @@ typedef struct // BDT(Buffer Descriptor Table) must be 256-byte aligned CFG_TUD_MEM_SECTION TU_ATTR_ALIGNED(512) static dcd_data_t _dcd; -TU_VERIFY_STATIC( sizeof(_dcd.bdt) == 512, "size is not correct" ); +TU_VERIFY_STATIC(sizeof(_dcd.bdt) == 512, "size is not correct"); -static void prepare_next_setup_packet(uint8_t rhport) -{ +static void prepare_next_setup_packet(uint8_t rhport) { const unsigned out_odd = _dcd.endpoint[0][0].odd; const unsigned in_odd = _dcd.endpoint[0][1].odd; if (_dcd.bdt[0][0][out_odd].own) { @@ -126,12 +122,10 @@ static void prepare_next_setup_packet(uint8_t rhport) _dcd.bdt[0][0][out_odd ^ 1].data = 1; _dcd.bdt[0][1][in_odd].data = 1; _dcd.bdt[0][1][in_odd ^ 1].data = 0; - dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), - _dcd.setup_packet, sizeof(_dcd.setup_packet)); + dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_OUT), _dcd.setup_packet, sizeof(_dcd.setup_packet)); } -static void process_stall(uint8_t rhport) -{ +static void process_stall(uint8_t rhport) { if (USB_OTG_FS->EP_CTL[0] & USB_ENDPT_EPSTALL_MASK) { /* clear stall condition of the control pipe */ prepare_next_setup_packet(rhport); @@ -139,13 +133,12 @@ static void process_stall(uint8_t rhport) } } -static void process_tokdne(uint8_t rhport) -{ - const unsigned s = USB_OTG_FS->STAT; - USB_OTG_FS->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ - buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; - endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; - unsigned odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; +static void process_tokdne(uint8_t rhport) { + const unsigned s = USB_OTG_FS->STAT; + USB_OTG_FS->INT_STAT = USB_ISTAT_TOKDNE_MASK; /* fetch the next token if received */ + buffer_descriptor_t *bd = (buffer_descriptor_t *)&_dcd.bda[s]; + endpoint_state_t *ep = &_dcd.endpoint_unified[s >> 3]; + unsigned odd = (s & USB_STAT_ODD_MASK) ? 1 : 0; /* fetch pid before discarded by the next steps */ const unsigned pid = bd->tok_pid; @@ -155,7 +148,7 @@ static void process_tokdne(uint8_t rhport) bd->ninc = 0; bd->keep = 0; /* update the odd variable to prepare for the next transfer */ - ep->odd = odd ^ 1; + ep->odd = odd ^ 1; if (pid == TOK_PID_SETUP) { dcd_event_setup_received(rhport, bd->addr, true); USB_OTG_FS->CTL &= ~USB_CTL_TXSUSPENDTOKENBUSY_MASK; @@ -165,25 +158,24 @@ static void process_tokdne(uint8_t rhport) TU_LOG1("TKDNE %x\r\n", s); } - const unsigned bc = bd->bc; + const unsigned bc = bd->bc; const unsigned remaining = ep->remaining - bc; if (remaining && bc == ep->max_packet_size) { /* continue the transferring consecutive data */ - ep->remaining = remaining; + ep->remaining = remaining; const int next_remaining = remaining - ep->max_packet_size; if (next_remaining > 0) { /* prepare to the after next transfer */ bd->addr += ep->max_packet_size * 2; - bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size: next_remaining; + bd->bc = next_remaining > ep->max_packet_size ? ep->max_packet_size : next_remaining; __DSB(); - bd->own = 1; /* the own bit must set after addr */ + bd->own = 1; /* the own bit must set after addr */ } return; } const unsigned length = ep->length; - dcd_event_xfer_complete(rhport, - ((s & USB_STAT_TX_MASK) << 4) | (s >> USB_STAT_ENDP_SHIFT), - length - remaining, XFER_RESULT_SUCCESS, true); + dcd_event_xfer_complete(rhport, ((s & USB_STAT_TX_MASK) << 4) | (s >> USB_STAT_ENDP_SHIFT), length - remaining, + XFER_RESULT_SUCCESS, true); if (0 == (s & USB_STAT_ENDP_MASK) && 0 == length) { /* After completion a ZLP of control transfer, * it prepares for the next steup transfer. */ @@ -191,24 +183,23 @@ static void process_tokdne(uint8_t rhport) /* When the transfer was the SetAddress, * the device address should be updated here. */ USB_OTG_FS->ADDR = _dcd.addr; - _dcd.addr = 0; + _dcd.addr = 0; } prepare_next_setup_packet(rhport); } } -static void process_bus_reset(uint8_t rhport) -{ - USB_OTG_FS->CTL |= USB_CTL_ODDRST_MASK; - USB_OTG_FS->ADDR = 0; - USB_OTG_FS->INT_ENB = (USB_OTG_FS->INT_ENB & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; +static void process_bus_reset(uint8_t rhport) { + USB_OTG_FS->CTL |= USB_CTL_ODDRST_MASK; + USB_OTG_FS->ADDR = 0; + USB_OTG_FS->INT_ENB = (USB_OTG_FS->INT_ENB & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; USB_OTG_FS->EP_CTL[0] = USB_ENDPT_EPHSHK_MASK | USB_ENDPT_EPRXEN_MASK | USB_ENDPT_EPTXEN_MASK; for (unsigned i = 1; i < 16; ++i) { USB_OTG_FS->EP_CTL[i] = 0; } buffer_descriptor_t *bd = _dcd.bdt[0][0]; - for (unsigned i = 0; i < sizeof(_dcd.bdt)/sizeof(*bd); ++i, ++bd) { + for (unsigned i = 0; i < sizeof(_dcd.bdt) / sizeof(*bd); ++i, ++bd) { bd->head = 0; } const endpoint_state_t ep0 = { @@ -226,31 +217,29 @@ static void process_bus_reset(uint8_t rhport) dcd_event_bus_reset(rhport, TUSB_SPEED_FULL, true); } -static void process_bus_inactive(uint8_t rhport) -{ - (void) rhport; +static void process_bus_inactive(uint8_t rhport) { + (void)rhport; const unsigned inten = USB_OTG_FS->INT_ENB; - USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; + USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_SLEEPEN_MASK) | USB_INTEN_RESUMEEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_SUSPEND, true); } -static void process_bus_active(uint8_t rhport) -{ - (void) rhport; +static void process_bus_active(uint8_t rhport) { + (void)rhport; const unsigned inten = USB_OTG_FS->INT_ENB; - USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; + USB_OTG_FS->INT_ENB = (inten & ~USB_INTEN_RESUMEEN_MASK) | USB_INTEN_SLEEPEN_MASK; dcd_event_bus_signal(rhport, DCD_EVENT_RESUME, true); } /*------------------------------------------------------------------*/ /* Device API *------------------------------------------------------------------*/ -bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { - (void) rhport; - (void) rh_init; +bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { + (void)rhport; + (void)rh_init; tu_memclr(&_dcd, sizeof(_dcd)); - USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); + USB_OTG_FS->BDT_PAGE_01 = (uint8_t)((uintptr_t)_dcd.bdt >> 8); USB_OTG_FS->BDT_PAGE_02 = (uint8_t)((uintptr_t)_dcd.bdt >> 16); USB_OTG_FS->BDT_PAGE_03 = (uint8_t)((uintptr_t)_dcd.bdt >> 24); @@ -259,27 +248,24 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { return true; } #define USB_DEVICE_INTERRUPT_PRIORITY (3U) -void dcd_int_enable(uint8_t rhport) -{ +void dcd_int_enable(uint8_t rhport) { uint8_t irqNumber; irqNumber = USB_FS_IRQn; - (void) rhport; - USB_OTG_FS->INT_ENB = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | - USB_INTEN_SLEEPEN_MASK | USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; + (void)rhport; + USB_OTG_FS->INT_ENB = USB_INTEN_USBRSTEN_MASK | USB_INTEN_TOKDNEEN_MASK | USB_INTEN_SLEEPEN_MASK | + USB_INTEN_ERROREN_MASK | USB_INTEN_STALLEN_MASK; NVIC_SetPriority((IRQn_Type)irqNumber, USB_DEVICE_INTERRUPT_PRIORITY); NVIC_EnableIRQ(USB_FS_IRQn); } -void dcd_int_disable(uint8_t rhport) -{ - (void) rhport; +void dcd_int_disable(uint8_t rhport) { + (void)rhport; NVIC_DisableIRQ(USB_FS_IRQn); USB_OTG_FS->INT_ENB = 0; } -void dcd_set_address(uint8_t rhport, uint8_t dev_addr) -{ - (void) rhport; +void dcd_set_address(uint8_t rhport, uint8_t dev_addr) { + (void)rhport; _dcd.addr = dev_addr & 0x7F; /* Response with status first before changing device address */ dcd_edpt_xfer(rhport, tu_edpt_addr(0, TUSB_DIR_IN), NULL, 0); @@ -296,31 +282,29 @@ extern u32 SystemCoreClock; #pragma GCC diagnostic pop #endif -void dcd_remote_wakeup(uint8_t rhport) -{ - (void) rhport; +void dcd_remote_wakeup(uint8_t rhport) { + (void)rhport; unsigned cnt = SystemCoreClock / 100; USB_OTG_FS->CTL |= USB_CTL_RESUME_MASK; - while (cnt--) __NOP(); + while (cnt--) { + __NOP(); + } USB_OTG_FS->CTL &= ~USB_CTL_RESUME_MASK; } -void dcd_connect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_FS->CTL |= USB_CTL_USBENSOFEN_MASK; +void dcd_connect(uint8_t rhport) { + (void)rhport; + USB_OTG_FS->CTL |= USB_CTL_USBENSOFEN_MASK; } -void dcd_disconnect(uint8_t rhport) -{ - (void) rhport; - USB_OTG_FS->CTL = 0; +void dcd_disconnect(uint8_t rhport) { + (void)rhport; + USB_OTG_FS->CTL = 0; } -void dcd_sof_enable(uint8_t rhport, bool en) -{ - (void) rhport; - (void) en; +void dcd_sof_enable(uint8_t rhport, bool en) { + (void)rhport; + (void)en; // TODO implement later } @@ -328,24 +312,23 @@ void dcd_sof_enable(uint8_t rhport, bool en) //--------------------------------------------------------------------+ // Endpoint API //--------------------------------------------------------------------+ -bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) -{ - (void) rhport; - - const unsigned ep_addr = ep_desc->bEndpointAddress; - const unsigned epn = ep_addr & 0xFu; - const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; - const unsigned xfer = ep_desc->bmAttributes.xfer; - endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; - const unsigned odd = ep->odd; - buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; +bool dcd_edpt_open(uint8_t rhport, const tusb_desc_endpoint_t *ep_desc) { + (void)rhport; + + const unsigned ep_addr = ep_desc->bEndpointAddress; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + const unsigned xfer = ep_desc->bmAttributes.xfer; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + const unsigned odd = ep->odd; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; /* No support for control transfer */ TU_ASSERT(epn && (xfer != TUSB_XFER_CONTROL)); ep->max_packet_size = tu_edpt_packet_size(ep_desc); - unsigned val = USB_ENDPT_EPCTLDIS_MASK; - val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK: 0; + unsigned val = USB_ENDPT_EPCTLDIS_MASK; + val |= (xfer != TUSB_XFER_ISOCHRONOUS) ? USB_ENDPT_EPHSHK_MASK : 0; val |= dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; USB_OTG_FS->EP_CTL[epn] |= val; @@ -359,21 +342,19 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * ep_desc) return true; } -void dcd_edpt_close_all (uint8_t rhport) -{ - (void) rhport; +void dcd_edpt_close_all(uint8_t rhport) { + (void)rhport; // TODO implement dcd_edpt_close_all() } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; +void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; - const unsigned epn = ep_addr & 0xFu; - const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; - endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; - buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; - const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][0]; + const unsigned msk = dir ? USB_ENDPT_EPTXEN_MASK : USB_ENDPT_EPRXEN_MASK; USB_OTG_FS->EP_CTL[epn] &= ~msk; ep->max_packet_size = 0; ep->length = 0; @@ -381,14 +362,28 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) bd->head = 0; } -bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) -{ - (void) rhport; + #if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} + #endif + +bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t *buffer, uint16_t total_bytes) { + (void)rhport; NVIC_DisableIRQ(USB_FS_IRQn); - const unsigned epn = ep_addr & 0xFu; - const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; - endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; - buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + endpoint_state_t *ep = &_dcd.endpoint[epn][dir]; + buffer_descriptor_t *bd = &_dcd.bdt[epn][dir][ep->odd]; if (bd->own) { TU_LOG1("DCD XFER fail %x %d %lx %lx\r\n", ep_addr, total_bytes, ep->state, bd->head); @@ -399,42 +394,40 @@ bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t to const unsigned mps = ep->max_packet_size; if (total_bytes > mps) { - buffer_descriptor_t *next = ep->odd ? bd - 1: bd + 1; + buffer_descriptor_t *next = ep->odd ? bd - 1 : bd + 1; /* When total_bytes is greater than the max packet size, * it prepares to the next transfer to avoid NAK in advance. */ - next->bc = total_bytes >= 2 * mps ? mps: total_bytes - mps; + next->bc = total_bytes >= 2 * mps ? mps : total_bytes - mps; next->addr = buffer + mps; next->own = 1; } - bd->bc = total_bytes >= mps ? mps: total_bytes; - bd->addr = buffer; + bd->bc = total_bytes >= mps ? mps : total_bytes; + bd->addr = buffer; __DSB(); - bd->own = 1; /* the own bit must set after addr */ + bd->own = 1; /* the own bit must set after addr */ NVIC_EnableIRQ(USB_FS_IRQn); return true; } -void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; +void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; const unsigned epn = ep_addr & 0xFu; if (0 == epn) { - USB_OTG_FS->EP_CTL[epn] |= USB_ENDPT_EPSTALL_MASK; + USB_OTG_FS->EP_CTL[epn] |= USB_ENDPT_EPSTALL_MASK; } else { - const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; - buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; - bd[0].bdt_stall = 1; - bd[1].bdt_stall = 1; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; + bd[0].bdt_stall = 1; + bd[1].bdt_stall = 1; } } -void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) -{ - (void) rhport; - const unsigned epn = ep_addr & 0xFu; - const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; - const unsigned odd = _dcd.endpoint[epn][dir].odd; - buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; +void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { + (void)rhport; + const unsigned epn = ep_addr & 0xFu; + const unsigned dir = (ep_addr & TUSB_DIR_IN_MASK) ? TUSB_DIR_IN : TUSB_DIR_OUT; + const unsigned odd = _dcd.endpoint[epn][dir].odd; + buffer_descriptor_t *bd = _dcd.bdt[epn][dir]; bd[odd ^ 1].own = 0; bd[odd ^ 1].data = 1; @@ -447,19 +440,18 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) //--------------------------------------------------------------------+ // ISR //--------------------------------------------------------------------+ -void dcd_int_handler(uint8_t rhport) -{ - (void) rhport; +void dcd_int_handler(uint8_t rhport) { + (void)rhport; - uint32_t is = USB_OTG_FS->INT_STAT; - uint32_t msk = USB_OTG_FS->INT_ENB; + uint32_t is = USB_OTG_FS->INT_STAT; + uint32_t msk = USB_OTG_FS->INT_ENB; USB_OTG_FS->INT_STAT = is & ~msk; is &= msk; if (is & USB_ISTAT_ERROR_MASK) { /* TODO: */ - uint32_t es = USB_OTG_FS->ERR_STAT; + uint32_t es = USB_OTG_FS->ERR_STAT; USB_OTG_FS->ERR_STAT = es; - USB_OTG_FS->INT_STAT = is; /* discard any pending events */ + USB_OTG_FS->INT_STAT = is; /* discard any pending events */ return; } @@ -493,5 +485,4 @@ void dcd_int_handler(uint8_t rhport) return; } } - #endif diff --git a/src/portable/nordic/nrf5x/dcd_nrf5x.c b/src/portable/nordic/nrf5x/dcd_nrf5x.c index 9e5f5117f..730ca7fb1 100644 --- a/src/portable/nordic/nrf5x/dcd_nrf5x.c +++ b/src/portable/nordic/nrf5x/dcd_nrf5x.c @@ -426,6 +426,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { __DSB(); } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} +#endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { (void) rhport; @@ -1062,5 +1077,4 @@ void tusb_hal_nrf_power_event(uint32_t event) { break; } } - #endif diff --git a/src/portable/nxp/khci/dcd_khci.c b/src/portable/nxp/khci/dcd_khci.c index 3d5e195a9..da1c5c888 100644 --- a/src/portable/nxp/khci/dcd_khci.c +++ b/src/portable/nxp/khci/dcd_khci.c @@ -428,6 +428,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) if (ie) NVIC_EnableIRQ(USB0_IRQn); } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} + #endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { (void) rhport; @@ -577,5 +592,4 @@ void dcd_int_handler(uint8_t rhport) process_tokdne(rhport); } } - #endif diff --git a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c index 855c59cd1..5516e1ba6 100644 --- a/src/portable/nxp/lpc17_40/dcd_lpc17_40.c +++ b/src/portable/nxp/lpc17_40/dcd_lpc17_40.c @@ -337,9 +337,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; (void) ep_addr; - // TODO implement dcd_edpt_close() +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } void dcd_edpt_close_all (uint8_t rhport) @@ -600,5 +608,4 @@ void dcd_int_handler(uint8_t rhport) TU_BREAKPOINT(); } } - #endif diff --git a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c index 7c637ce0c..1c135f3be 100644 --- a/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c +++ b/src/portable/nxp/lpc_ip3511/dcd_lpc_ip3511.c @@ -432,6 +432,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) _dcd.ep[ep_id][0].cmd_sts.disable = _dcd.ep[ep_id][1].cmd_sts.disable = 1; } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} +#endif + static void prepare_ep_xfer(uint8_t rhport, uint8_t ep_id, uint16_t buf_offset, uint16_t total_bytes) { uint16_t nbytes; ep_cmd_sts_t* ep_cs = get_ep_cs(ep_id); @@ -631,5 +646,4 @@ void dcd_int_handler(uint8_t rhport) // Endpoint transfer complete interrupt process_xfer_isr(rhport, int_status); } - #endif diff --git a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c index 60afbd435..25ef117c2 100644 --- a/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c +++ b/src/portable/raspberrypi/pio_usb/dcd_pio_usb.c @@ -113,6 +113,19 @@ void dcd_edpt_close_all (uint8_t rhport) (void) rhport; } +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} + // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer (uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { @@ -207,5 +220,4 @@ void __no_inline_not_in_flash_func(pio_usb_device_irq_handler)(uint8_t root_id) // clear all rport->ints &= ~ints; } - #endif diff --git a/src/portable/renesas/rusb2/dcd_rusb2.c b/src/portable/renesas/rusb2/dcd_rusb2.c index ecd28973c..2cc79aa74 100644 --- a/src/portable/renesas/rusb2/dcd_rusb2.c +++ b/src/portable/renesas/rusb2/dcd_rusb2.c @@ -859,6 +859,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) _dcd.ep[dir][epn] = 0; } +#if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} +#endif + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { rusb2_reg_t* rusb = RUSB2_REG(rhport); @@ -1028,5 +1043,4 @@ void dcd_int_handler(uint8_t rhport) } } } - #endif diff --git a/src/portable/sunxi/dcd_sunxi_musb.c b/src/portable/sunxi/dcd_sunxi_musb.c index f1f4897cb..8e6dc8c63 100644 --- a/src/portable/sunxi/dcd_sunxi_musb.c +++ b/src/portable/sunxi/dcd_sunxi_musb.c @@ -1082,6 +1082,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) musb_int_unmask(); } + #if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} + #endif + // Submit a transfer, When complete dcd_event_xfer_complete() is invoked to notify the stack bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t * buffer, uint16_t total_bytes) { @@ -1210,5 +1225,4 @@ void dcd_int_handler(uint8_t rhport) rxis &= ~TU_BIT(num); } } - #endif diff --git a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c index 64cbc5087..e4c28a56f 100644 --- a/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c +++ b/src/portable/ti/msp430x5xx/dcd_msp430x5xx.c @@ -333,11 +333,20 @@ bool dcd_edpt_open (uint8_t rhport, tusb_desc_endpoint_t const * desc_edpt) return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; (void) ep_addr; - // TODO implement dcd_edpt_close() +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; } +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; +} + + void dcd_edpt_close_all (uint8_t rhport) { (void) rhport; @@ -821,5 +830,4 @@ void dcd_int_handler(uint8_t rhport) } } - #endif diff --git a/src/portable/valentyusb/eptri/dcd_eptri.c b/src/portable/valentyusb/eptri/dcd_eptri.c index a03c94558..f0e52ae47 100644 --- a/src/portable/valentyusb/eptri/dcd_eptri.c +++ b/src/portable/valentyusb/eptri/dcd_eptri.c @@ -438,9 +438,17 @@ bool dcd_edpt_open(uint8_t rhport, tusb_desc_endpoint_t const * p_endpoint_desc) return true; } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { - (void) rhport; (void) ep_addr; - // TODO implement dcd_edpt_close() +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void)rhport; + (void)ep_addr; + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } void dcd_edpt_close_all (uint8_t rhport) @@ -659,5 +667,4 @@ void dcd_int_handler(uint8_t rhport) } } } - #endif diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index c248ba14e..f8c3b05c3 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -283,12 +283,20 @@ void dcd_edpt_close_all(uint8_t rhport) { // TODO optional } -void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { (void) rhport; (void) ep_addr; - // TODO optional + (void)largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { + (void)rhport; + (void)desc_ep; + return false; } + bool dcd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t total_bytes) { (void) rhport; uint8_t ep = tu_edpt_number(ep_addr); @@ -344,5 +352,4 @@ void dcd_edpt_clear_stall(uint8_t rhport, uint8_t ep_addr) { } } } - #endif diff --git a/src/portable/wch/dcd_ch32_usbhs.c b/src/portable/wch/dcd_ch32_usbhs.c index 4a208b9df..36fdc89ef 100644 --- a/src/portable/wch/dcd_ch32_usbhs.c +++ b/src/portable/wch/dcd_ch32_usbhs.c @@ -27,13 +27,14 @@ #include "tusb_option.h" -#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && defined(CFG_TUD_WCH_USBIP_USBHS) && CFG_TUD_WCH_USBIP_USBHS -#include "ch32_usbhs_reg.h" +#if CFG_TUD_ENABLED && defined(TUP_USBIP_WCH_USBHS) && defined(CFG_TUD_WCH_USBIP_USBHS) && \ + (CFG_TUD_WCH_USBIP_USBHS == 1) + #include "ch32_usbhs_reg.h" -#include "device/dcd.h" + #include "device/dcd.h" -// Max number of bi-directional endpoints including EP0 -#define EP_MAX 16 + // Max number of bi-directional endpoints including EP0 + #define EP_MAX 16 typedef struct { uint8_t* buffer; @@ -288,6 +289,21 @@ void dcd_edpt_close(uint8_t rhport, uint8_t ep_addr) { } } + #if 0 +bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet_size) { + (void) rhport; + (void) ep_addr; + (void) largest_packet_size; + return false; +} + +bool dcd_edpt_iso_activate(uint8_t rhport, tusb_desc_endpoint_t const * desc_ep) { + (void) rhport; + (void) desc_ep; + return false; +} + #endif + void dcd_edpt_stall(uint8_t rhport, uint8_t ep_addr) { (void) rhport; @@ -419,5 +435,4 @@ void dcd_int_handler(uint8_t rhport) { USBHSD->INT_FG = USBHS_SUSPEND_FLAG; /* Clear flag */ } } - #endif -- cgit v1.3.1 From f6a77b87f04386ea27effb7c1faf8e1a33da0fa1 Mon Sep 17 00:00:00 2001 From: hathach Date: Wed, 19 Nov 2025 22:27:47 +0700 Subject: Bump version to 0.20.0 --- AGENTS.md | 33 ++++- docs/info/changelog.rst | 93 +++++++++++++ hw/bsp/BoardPresets.json | 342 +++++++++++++++++++++++++++++++++++++++++++---- library.json | 2 +- repository.yml | 3 +- sonar-project.properties | 2 +- src/tusb_option.h | 2 +- tools/make_release.py | 17 ++- 8 files changed, 452 insertions(+), 42 deletions(-) (limited to 'docs') diff --git a/AGENTS.md b/AGENTS.md index d00a4b114..a6163dd42 100644 --- a/AGENTS.md +++ b/AGENTS.md @@ -164,11 +164,36 @@ python3 tools/build.py -b BOARD_NAME ## Release Instructions +**DO NOT commit files automatically - only modify files and let the maintainer review before committing.** + 1. Bump the release version variable at the top of `tools/make_release.py`. -2. Execute `python tools/make_release.py` to refresh `src/tusb_option.h`, `repository.yml`, and `library.json`. -3. Generate release notes by running `git log ..HEAD`, then add a new entry to - `docs/info/changelog.rst` that follows the existing format (heading, date, highlights, categorized bullet lists). -4. Proceed with tagging/publishing once builds and tests succeed. +2. Execute `python3 tools/make_release.py` to refresh: + - `src/tusb_option.h` (version defines) + - `repository.yml` (version mapping) + - `library.json` (PlatformIO version) + - `sonar-project.properties` (SonarQube version) + - `docs/reference/boards.rst` (generated board documentation) + - `hw/bsp/BoardPresets.json` (CMake presets) +3. Generate release notes for `docs/info/changelog.rst`: + - Get commit list: `git log ..HEAD --oneline` + - **Visit GitHub PRs** for merged pull requests to understand context and gather details + - Use GitHub tools to search/read PRs: `github-mcp-server-list_pull_requests`, `github-mcp-server-pull_request_read` + - Extract key changes, API modifications, bug fixes, and new features from PR descriptions + - Add new changelog entry following the existing format: + - Version heading with equals underline (e.g., `0.20.0` followed by `======`) + - Release date in italics (e.g., `*November 19, 2024*`) + - Major sections: General, API Changes, Controller Driver (DCD & HCD), Device Stack, Host Stack, Testing + - Use bullet lists with descriptive categorization + - Reference function names, config macros, and file paths using RST inline code (double backticks) + - Include meaningful descriptions, not just commit messages +4. **Validation before commit**: + - Run unit tests: `cd test/unit-test && ceedling test:all` + - Build at least one example: `cd examples/device/cdc_msc && make BOARD=stm32f407disco all` + - Verify changed files look correct: `git diff --stat` +5. **Leave files unstaged** for maintainer to review, modify if needed, and commit with message: `Bump version to X.Y.Z` +6. **After maintainer commits**: Create annotated tag with `git tag -a vX.Y.Z -m "Release X.Y.Z"` +7. Push commit and tag: `git push origin && git push origin vX.Y.Z` +8. Create GitHub release from the tag with changelog content ## Repository Structure Quick Reference ``` diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index d6bf846ed..3addce27b 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,6 +2,99 @@ Changelog ********* +0.20.0 +====== + +*November 19, 2024* + +General +------- + +- New MCUs and Boards: + + - Add STM32U3 device support (adjusted from STM32U0) + - Add nRF54H20 support with initial board configuration + - Rename board names: pca10056→nrf52840dk, pca10059→nrf52840dongle, pca10095→nrf5340dk + - Improve CMake: Move startup and linker files from board target to executable. Enhance target warning flags and fix various build warnings + +- Code Quality and Static Analysis: + + - Add PVS-Studio static analysis to CI + - Add SonarQube scan support + - Add IAR C-Stat analysis capability + - Add ``.clang-format`` for consistent code formatting + - Fix numerous alerts and warnings found by static analysis tools + +- Documentation: + + - Improve Getting Started documentation structure and flow + - Add naming conventions and buffer handling documentation + +Controller Driver (DCD & HCD) +----------------------------- + +- DWC2 + + - Fix incorrect handling of Zero-Length Packets (ZLP) in the DWC2 driver when receiving data (OUT transfers) + - Improve EP0 multi-packet logic + - Support EP0 with max packet size = 8 + - For IN endpoint, write initial packet directly to FIFO and only use TXFE interrupt for subsequent packets + - Fix ISO with bInterval > 2 using incomplete IN interrupt handling. + - Fix compile issues when enabling both host and device + - Clear pending suspend interrupt after USB reset (enum end) + - Improve host closing endpoint and channel handling when device is unplugged + +- FSDEV (STM32) + + - Fix AT32 USB interrupt remapping in ``dcd_int_enable()`` + +- OHCI + + - Add initial LPC55 OHCI support + - Improve data cache support + +Device Stack +------------ + +- USBD Core + + - Support configurable EP0 buffer size CFG_TUD_ENDPOINT0_BUFSIZE + - Make dcd_edpt_iso_alloc/activate as default API for ISO endpoint + +- Audio + + - Add UAC1 support + - Implement RX FIFO threshold adjustment with `tud_audio_get/set_ep_in_fifo_threshold()` + +- CDC + + - Migrate to endpoint stream API + +- HID + + - Fix HID stylus descriptor + +- MIDI + + - Migrate to endpoint stream API + - Add ``tud_midi_n_packet_write_n()`` and ``tud_midi_n_packet_read_n()`` + +- MTP + + - Fix incorrect MTP xact_len calculation + +- Video + + - Add bufferless operation callback for dynamic frame generation with tud_video_prepare_payload_cb() + + +Host Stack +---------- + +- USBH Core + + - Improve transfer closing and channel management + 0.19.0 ====== diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 044c74ee1..5df924138 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -362,6 +362,10 @@ "name": "metro_m7_1011_sd", "inherits": "default" }, + { + "name": "metro_nrf52840", + "inherits": "default" + }, { "name": "mimxrt1010_evk", "inherits": "default" @@ -419,19 +423,43 @@ "inherits": "default" }, { - "name": "pca10056", + "name": "nrf52833dk", "inherits": "default" }, { - "name": "pca10059", + "name": "nrf52840dk", "inherits": "default" }, { - "name": "pca10095", + "name": "nrf52840dongle", "inherits": "default" }, { - "name": "pca10100", + "name": "nrf5340dk", + "inherits": "default" + }, + { + "name": "nrf54h20dk", + "inherits": "default" + }, + { + "name": "nutiny_nuc126v", + "inherits": "default" + }, + { + "name": "nutiny_sdk_nuc120", + "inherits": "default" + }, + { + "name": "nutiny_sdk_nuc121", + "inherits": "default" + }, + { + "name": "nutiny_sdk_nuc125", + "inherits": "default" + }, + { + "name": "nutiny_sdk_nuc505", "inherits": "default" }, { @@ -490,6 +518,10 @@ "name": "raspberry_pi_pico2", "inherits": "default" }, + { + "name": "raspberry_pi_pico2_riscv", + "inherits": "default" + }, { "name": "raspberry_pi_pico_w", "inherits": "default" @@ -514,6 +546,14 @@ "name": "same54_xplained", "inherits": "default" }, + { + "name": "same70_qmtech", + "inherits": "default" + }, + { + "name": "same70_xplained", + "inherits": "default" + }, { "name": "samg55_xplained", "inherits": "default" @@ -534,10 +574,18 @@ "name": "sipeed_longan_nano", "inherits": "default" }, + { + "name": "sltb009a", + "inherits": "default" + }, { "name": "sparkfun_samd21_mini_usb", "inherits": "default" }, + { + "name": "spresense", + "inherits": "default" + }, { "name": "stlinkv3mini", "inherits": "default" @@ -698,6 +746,10 @@ "name": "stm32l476disco", "inherits": "default" }, + { + "name": "stm32l496nucleo", + "inherits": "default" + }, { "name": "stm32l4p5nucleo", "inherits": "default" @@ -1336,6 +1388,11 @@ "description": "Build preset for the metro_m7_1011_sd board", "configurePreset": "metro_m7_1011_sd" }, + { + "name": "metro_nrf52840", + "description": "Build preset for the metro_nrf52840 board", + "configurePreset": "metro_nrf52840" + }, { "name": "mimxrt1010_evk", "description": "Build preset for the mimxrt1010_evk board", @@ -1407,24 +1464,54 @@ "configurePreset": "nanoch32v305" }, { - "name": "pca10056", - "description": "Build preset for the pca10056 board", - "configurePreset": "pca10056" + "name": "nrf52833dk", + "description": "Build preset for the nrf52833dk board", + "configurePreset": "nrf52833dk" + }, + { + "name": "nrf52840dk", + "description": "Build preset for the nrf52840dk board", + "configurePreset": "nrf52840dk" + }, + { + "name": "nrf52840dongle", + "description": "Build preset for the nrf52840dongle board", + "configurePreset": "nrf52840dongle" + }, + { + "name": "nrf5340dk", + "description": "Build preset for the nrf5340dk board", + "configurePreset": "nrf5340dk" + }, + { + "name": "nrf54h20dk", + "description": "Build preset for the nrf54h20dk board", + "configurePreset": "nrf54h20dk" }, { - "name": "pca10059", - "description": "Build preset for the pca10059 board", - "configurePreset": "pca10059" + "name": "nutiny_nuc126v", + "description": "Build preset for the nutiny_nuc126v board", + "configurePreset": "nutiny_nuc126v" }, { - "name": "pca10095", - "description": "Build preset for the pca10095 board", - "configurePreset": "pca10095" + "name": "nutiny_sdk_nuc120", + "description": "Build preset for the nutiny_sdk_nuc120 board", + "configurePreset": "nutiny_sdk_nuc120" }, { - "name": "pca10100", - "description": "Build preset for the pca10100 board", - "configurePreset": "pca10100" + "name": "nutiny_sdk_nuc121", + "description": "Build preset for the nutiny_sdk_nuc121 board", + "configurePreset": "nutiny_sdk_nuc121" + }, + { + "name": "nutiny_sdk_nuc125", + "description": "Build preset for the nutiny_sdk_nuc125 board", + "configurePreset": "nutiny_sdk_nuc125" + }, + { + "name": "nutiny_sdk_nuc505", + "description": "Build preset for the nutiny_sdk_nuc505 board", + "configurePreset": "nutiny_sdk_nuc505" }, { "name": "pico_sdk", @@ -1496,6 +1583,11 @@ "description": "Build preset for the raspberry_pi_pico2 board", "configurePreset": "raspberry_pi_pico2" }, + { + "name": "raspberry_pi_pico2_riscv", + "description": "Build preset for the raspberry_pi_pico2_riscv board", + "configurePreset": "raspberry_pi_pico2_riscv" + }, { "name": "raspberry_pi_pico_w", "description": "Build preset for the raspberry_pi_pico_w board", @@ -1526,6 +1618,16 @@ "description": "Build preset for the same54_xplained board", "configurePreset": "same54_xplained" }, + { + "name": "same70_qmtech", + "description": "Build preset for the same70_qmtech board", + "configurePreset": "same70_qmtech" + }, + { + "name": "same70_xplained", + "description": "Build preset for the same70_xplained board", + "configurePreset": "same70_xplained" + }, { "name": "samg55_xplained", "description": "Build preset for the samg55_xplained board", @@ -1551,11 +1653,21 @@ "description": "Build preset for the sipeed_longan_nano board", "configurePreset": "sipeed_longan_nano" }, + { + "name": "sltb009a", + "description": "Build preset for the sltb009a board", + "configurePreset": "sltb009a" + }, { "name": "sparkfun_samd21_mini_usb", "description": "Build preset for the sparkfun_samd21_mini_usb board", "configurePreset": "sparkfun_samd21_mini_usb" }, + { + "name": "spresense", + "description": "Build preset for the spresense board", + "configurePreset": "spresense" + }, { "name": "stlinkv3mini", "description": "Build preset for the stlinkv3mini board", @@ -1756,6 +1868,11 @@ "description": "Build preset for the stm32l476disco board", "configurePreset": "stm32l476disco" }, + { + "name": "stm32l496nucleo", + "description": "Build preset for the stm32l496nucleo board", + "configurePreset": "stm32l496nucleo" + }, { "name": "stm32l4p5nucleo", "description": "Build preset for the stm32l4p5nucleo board", @@ -3153,6 +3270,19 @@ } ] }, + { + "name": "metro_nrf52840", + "steps": [ + { + "type": "configure", + "name": "metro_nrf52840" + }, + { + "type": "build", + "name": "metro_nrf52840" + } + ] + }, { "name": "mimxrt1010_evk", "steps": [ @@ -3336,54 +3466,132 @@ ] }, { - "name": "pca10056", + "name": "nrf52833dk", + "steps": [ + { + "type": "configure", + "name": "nrf52833dk" + }, + { + "type": "build", + "name": "nrf52833dk" + } + ] + }, + { + "name": "nrf52840dk", + "steps": [ + { + "type": "configure", + "name": "nrf52840dk" + }, + { + "type": "build", + "name": "nrf52840dk" + } + ] + }, + { + "name": "nrf52840dongle", "steps": [ { "type": "configure", - "name": "pca10056" + "name": "nrf52840dongle" }, { "type": "build", - "name": "pca10056" + "name": "nrf52840dongle" } ] }, { - "name": "pca10059", + "name": "nrf5340dk", "steps": [ { "type": "configure", - "name": "pca10059" + "name": "nrf5340dk" }, { "type": "build", - "name": "pca10059" + "name": "nrf5340dk" } ] }, { - "name": "pca10095", + "name": "nrf54h20dk", "steps": [ { "type": "configure", - "name": "pca10095" + "name": "nrf54h20dk" }, { "type": "build", - "name": "pca10095" + "name": "nrf54h20dk" } ] }, { - "name": "pca10100", + "name": "nutiny_nuc126v", "steps": [ { "type": "configure", - "name": "pca10100" + "name": "nutiny_nuc126v" }, { "type": "build", - "name": "pca10100" + "name": "nutiny_nuc126v" + } + ] + }, + { + "name": "nutiny_sdk_nuc120", + "steps": [ + { + "type": "configure", + "name": "nutiny_sdk_nuc120" + }, + { + "type": "build", + "name": "nutiny_sdk_nuc120" + } + ] + }, + { + "name": "nutiny_sdk_nuc121", + "steps": [ + { + "type": "configure", + "name": "nutiny_sdk_nuc121" + }, + { + "type": "build", + "name": "nutiny_sdk_nuc121" + } + ] + }, + { + "name": "nutiny_sdk_nuc125", + "steps": [ + { + "type": "configure", + "name": "nutiny_sdk_nuc125" + }, + { + "type": "build", + "name": "nutiny_sdk_nuc125" + } + ] + }, + { + "name": "nutiny_sdk_nuc505", + "steps": [ + { + "type": "configure", + "name": "nutiny_sdk_nuc505" + }, + { + "type": "build", + "name": "nutiny_sdk_nuc505" } ] }, @@ -3569,6 +3777,19 @@ } ] }, + { + "name": "raspberry_pi_pico2_riscv", + "steps": [ + { + "type": "configure", + "name": "raspberry_pi_pico2_riscv" + }, + { + "type": "build", + "name": "raspberry_pi_pico2_riscv" + } + ] + }, { "name": "raspberry_pi_pico_w", "steps": [ @@ -3647,6 +3868,32 @@ } ] }, + { + "name": "same70_qmtech", + "steps": [ + { + "type": "configure", + "name": "same70_qmtech" + }, + { + "type": "build", + "name": "same70_qmtech" + } + ] + }, + { + "name": "same70_xplained", + "steps": [ + { + "type": "configure", + "name": "same70_xplained" + }, + { + "type": "build", + "name": "same70_xplained" + } + ] + }, { "name": "samg55_xplained", "steps": [ @@ -3712,6 +3959,19 @@ } ] }, + { + "name": "sltb009a", + "steps": [ + { + "type": "configure", + "name": "sltb009a" + }, + { + "type": "build", + "name": "sltb009a" + } + ] + }, { "name": "sparkfun_samd21_mini_usb", "steps": [ @@ -3725,6 +3985,19 @@ } ] }, + { + "name": "spresense", + "steps": [ + { + "type": "configure", + "name": "spresense" + }, + { + "type": "build", + "name": "spresense" + } + ] + }, { "name": "stlinkv3mini", "steps": [ @@ -4245,6 +4518,19 @@ } ] }, + { + "name": "stm32l496nucleo", + "steps": [ + { + "type": "configure", + "name": "stm32l496nucleo" + }, + { + "type": "build", + "name": "stm32l496nucleo" + } + ] + }, { "name": "stm32l4p5nucleo", "steps": [ diff --git a/library.json b/library.json index 718fd84d3..efad438a7 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TinyUSB", - "version": "0.19.0", + "version": "0.20.0", "description": "TinyUSB is an open-source cross-platform USB Host/Device stack for embedded system, designed to be memory-safe with no dynamic allocation and thread-safe with all interrupt events are deferred then handled in the non-ISR task function.", "keywords": "usb, host, device", "repository": diff --git a/repository.yml b/repository.yml index 5c2aaa6fa..f4da056e3 100644 --- a/repository.yml +++ b/repository.yml @@ -17,5 +17,6 @@ repo.versions: "0.17.0": "0.17.0" "0.18.0": "0.18.0" "0.19.0": "0.19.0" - "0-latest": "0.19.0" + "0.20.0": "0.20.0" + "0-latest": "0.20.0" "0-dev": "0.0.0" diff --git a/sonar-project.properties b/sonar-project.properties index 5a19a234d..c0032d6e4 100644 --- a/sonar-project.properties +++ b/sonar-project.properties @@ -4,7 +4,7 @@ sonar.organization=hathach # This is the name and version displayed in the SonarCloud UI. sonar.projectName=tinyusb -sonar.projectVersion=0.19.0 +sonar.projectVersion=0.20.0 # Path is relative to the sonar-project.properties file. Replace "\" by "/" on Windows. diff --git a/src/tusb_option.h b/src/tusb_option.h index eed14214d..c8265f898 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -31,7 +31,7 @@ // Version is release as major.minor.revision eg 1.0.0 #define TUSB_VERSION_MAJOR 0 -#define TUSB_VERSION_MINOR 19 +#define TUSB_VERSION_MINOR 20 #define TUSB_VERSION_REVISION 0 #define TUSB_VERSION_NUMBER (TUSB_VERSION_MAJOR * 10000 + TUSB_VERSION_MINOR * 100 + TUSB_VERSION_REVISION) diff --git a/tools/make_release.py b/tools/make_release.py index 0e7919f46..71c1e6f64 100755 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,8 +1,9 @@ #!/usr/bin/env python3 import re import gen_doc +import gen_presets -version = '0.19.0' +version = '0.20.0' print('version {}'.format(version)) ver_id = version.split('.') @@ -50,15 +51,19 @@ with open(f_library_json, 'w') as f: f_sonar_properties = 'sonar-project.properties' with open(f_sonar_properties) as f: fdata = f.read() - fdata = re.sub(r'(sonar\.projectVersion=)\d+\.\d+\.\d+', rf'\1{version}', fdata) +fdata = re.sub(r'(sonar\.projectVersion=)\d+\.\d+\.\d+', r'\g<1>{}'.format(version), fdata) with open(f_sonar_properties, 'w') as f: f.write(fdata) -################### -# docs/info/changelog.rst -################### - +# gen docs gen_doc.gen_deps_doc() +gen_doc.gen_boards_doc() +# gen presets +gen_presets.main() + +##################(ver# +# docs/info/changelog.rst +################### print("Update docs/info/changelog.rst") -- cgit v1.3.1 From 551520ddb87cc47f90ddb9a0470a6f78ab2a55e8 Mon Sep 17 00:00:00 2001 From: hathach Date: Thu, 20 Nov 2025 00:09:39 +0700 Subject: update changelog.rst --- docs/info/changelog.rst | 5 +---- 1 file changed, 1 insertion(+), 4 deletions(-) (limited to 'docs') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index 3addce27b..df23ce7d8 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -87,13 +87,10 @@ Device Stack - Add bufferless operation callback for dynamic frame generation with tud_video_prepare_payload_cb() - Host Stack ---------- -- USBH Core - - - Improve transfer closing and channel management +No changes 0.19.0 ====== -- cgit v1.3.1 From a85f29b2ae44d6a1ad75c1d81ecee60da207095d Mon Sep 17 00:00:00 2001 From: Thomas Rubin Date: Thu, 20 Nov 2025 10:26:41 +0100 Subject: Doc: Typo in docs/integration.rst Signed-off-by: Thomas Rubin --- docs/integration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/integration.rst b/docs/integration.rst index 3480746d0..f7c5be2ca 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -59,7 +59,7 @@ Minimal Example } void USB1_IRQHandler(void) { - // forward interrupt port 0 to TinyUSB stack + // forward interrupt port 1 to TinyUSB stack tusb_int_handler(1, true); } -- cgit v1.3.1 From c9b623aa63d24d58a7a5e55dd296afd1261b2ab8 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 21 Nov 2025 17:02:56 +0700 Subject: edpt stream support xfer_fifo for device CFG_TUD_EDPT_DEDICATED_HWFIFO cdc device omit ep buffer when hwfifo is supported --- docs/info/changelog.rst | 2 +- src/class/cdc/cdc_device.c | 18 ++++++++++++++---- src/common/tusb_fifo.h | 4 ++++ src/common/tusb_private.h | 6 +++--- src/device/usbd.c | 11 ++++++++++- src/tusb.c | 22 ++++++++++++++++------ src/tusb_option.h | 16 ++++++++++------ 7 files changed, 58 insertions(+), 21 deletions(-) (limited to 'docs') diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index df23ce7d8..35c8515cc 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -5,7 +5,7 @@ Changelog 0.20.0 ====== -*November 19, 2024* +*November 19, 2025* General ------- diff --git a/src/class/cdc/cdc_device.c b/src/class/cdc/cdc_device.c index 9e62c6509..a11de2f91 100644 --- a/src/class/cdc/cdc_device.c +++ b/src/class/cdc/cdc_device.c @@ -67,8 +67,11 @@ typedef struct { #define ITF_MEM_RESET_SIZE offsetof(cdcd_interface_t, line_coding) typedef struct { + // Don't use local EP buffer if dedicated FIFO is supported + #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 TUD_EPBUF_DEF(epout, CFG_TUD_CDC_EP_BUFSIZE); TUD_EPBUF_DEF(epin, CFG_TUD_CDC_EP_BUFSIZE); + #endif #if CFG_TUD_CDC_NOTIFY TUD_EPBUF_TYPE_DEF(cdc_notify_msg_t, epnotify); @@ -268,8 +271,6 @@ void cdcd_init(void) { tu_memclr(_cdcd_itf, sizeof(_cdcd_itf)); for (uint8_t i = 0; i < CFG_TUD_CDC; i++) { cdcd_interface_t *p_cdc = &_cdcd_itf[i]; - cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; - p_cdc->wanted_char = (char) -1; // default line coding is : stop bit = 1, parity = none, data bits = 8 @@ -278,14 +279,23 @@ void cdcd_init(void) { p_cdc->line_coding.parity = 0; p_cdc->line_coding.data_bits = 8; + #if CFG_TUD_EDPT_DEDICATED_HWFIFO + uint8_t *epout_buf = NULL; + uint8_t *epin_buf = NULL; + #else + cdcd_epbuf_t *p_epbuf = &_cdcd_epbuf[i]; + uint8_t *epout_buf = p_epbuf->epout; + uint8_t *epin_buf = p_epbuf->epin; + #endif + tu_edpt_stream_init(&p_cdc->stream.rx, false, false, false, p_cdc->stream.rx_ff_buf, CFG_TUD_CDC_RX_BUFSIZE, - p_epbuf->epout, CFG_TUD_CDC_EP_BUFSIZE); + epout_buf, CFG_TUD_CDC_EP_BUFSIZE); // TX fifo can be configured to change to overwritable if not connected (DTR bit not set). Without DTR we do not // know if data is actually polled by terminal. This way the most current data is prioritized. // Default: is overwritable tu_edpt_stream_init(&p_cdc->stream.tx, false, true, _cdcd_cfg.tx_overwritabe_if_not_connected, - p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, p_epbuf->epin, CFG_TUD_CDC_EP_BUFSIZE); + p_cdc->stream.tx_ff_buf, CFG_TUD_CDC_TX_BUFSIZE, epin_buf, CFG_TUD_CDC_EP_BUFSIZE); } } diff --git a/src/common/tusb_fifo.h b/src/common/tusb_fifo.h index c16216606..0b8e83760 100644 --- a/src/common/tusb_fifo.h +++ b/src/common/tusb_fifo.h @@ -48,6 +48,10 @@ extern "C" { // for OS None, we don't get preempted #define CFG_FIFO_MUTEX OSAL_MUTEX_REQUIRED +#if CFG_TUD_EDPT_DEDICATED_HWFIFO || CFG_TUH_EDPT_DEDICATED_HWFIFO + #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32 +#endif + /* Write/Read index is always in the range of: * 0 .. 2*depth-1 * The extra window allow us to determine the fifo state of empty or full with only 2 indices diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index be1264a71..48fd1d6d2 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -60,7 +60,7 @@ typedef struct { uint8_t ep_addr; uint16_t ep_bufsize; - uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer + uint8_t *ep_buf; // set to NULL to use xfer_fifo when CFG_TUD_EDPT_DEDICATED_HWFIFO = 1 tu_fifo_t ff; // mutex: read if rx, otherwise write @@ -98,7 +98,7 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove // Deinit an endpoint stream bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); -// Open an stream for an endpoint +// Open an endpoint stream TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { s->ep_addr = desc_ep->bEndpointAddress; s->is_mps512 = tu_edpt_packet_size(desc_ep) == 512; @@ -150,7 +150,7 @@ uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Complete read transfer by writing EP -> FIFO. Must be called in the transfer complete callback TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete(tu_edpt_stream_t* s, uint32_t xferred_bytes) { - if (0u != tu_fifo_depth(&s->ff)) { + if (0u != tu_fifo_depth(&s->ff) && s->ep_buf != NULL) { tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); } } diff --git a/src/device/usbd.c b/src/device/usbd.c index a65d14daf..5e7d0ffa7 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -1474,6 +1474,7 @@ bool usbd_edpt_xfer(uint8_t rhport, uint8_t ep_addr, uint8_t* buffer, uint16_t t // success message. If total_bytes is too big, the FIFO will copy only what is available // into the USB buffer! bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_t total_bytes, bool is_isr) { + #if CFG_TUD_EDPT_DEDICATED_HWFIFO rhport = _usbd_rhport; uint8_t const epnum = tu_edpt_number(ep_addr); @@ -1481,7 +1482,7 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_ TU_LOG_USBD(" Queue ISO EP %02X with %u bytes ... ", ep_addr, total_bytes); - // Attempt to transfer on a busy endpoint, sound like an race condition ! + // Attempt to transfer on a busy endpoint, sound like a race condition ! TU_ASSERT(_usbd_dev.ep_status[epnum][dir].busy == 0); // Set busy first since the actual transfer can be complete before dcd_edpt_xfer() could return @@ -1499,6 +1500,14 @@ bool usbd_edpt_xfer_fifo(uint8_t rhport, uint8_t ep_addr, tu_fifo_t* ff, uint16_ TU_BREAKPOINT(); return false; } + #else + (void)rhport; + (void)ep_addr; + (void)ff; + (void)total_bytes; + (void)is_isr; + return false; + #endif } bool usbd_edpt_busy(uint8_t rhport, uint8_t ep_addr) { diff --git a/src/tusb.c b/src/tusb.c index 3852da76b..1b8fdc460 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -387,8 +387,12 @@ TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_strea #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); - #endif + if (s->ep_buf == NULL) { + return usbd_edpt_xfer_fifo(hwid, s->ep_addr, &s->ff, count, false); + } else { + return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count, false); + } + #endif } return false; } @@ -419,12 +423,17 @@ bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint3 } uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s) { - // skip if no data - TU_VERIFY(tu_fifo_count(&s->ff) > 0, 0); + const uint16_t ff_count = tu_fifo_count(&s->ff); + TU_VERIFY(ff_count > 0, 0); // skip if no data TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf - const uint16_t count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + uint16_t count; + if (s->ep_buf == NULL) { + count = ff_count; + } else { + count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); + } if (count > 0) { TU_ASSERT(stream_xfer(hwid, s, count), 0); @@ -441,7 +450,8 @@ uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t *s, const void *buf TU_VERIFY(bufsize > 0); // TODO support ZLP if (0 == tu_fifo_depth(&s->ff)) { - // no fifo for buffered + // no fifo for buffered, ep_buf must be valid + TU_VERIFY(s->ep_buf != NULL, 0); TU_VERIFY(stream_claim(hwid, s), 0); const uint32_t xact_len = tu_min32(bufsize, s->ep_bufsize); memcpy(s->ep_buf, buffer, xact_len); diff --git a/src/tusb_option.h b/src/tusb_option.h index e2eaecd2d..d7b61d58d 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -306,18 +306,14 @@ #if defined(TUP_USBIP_DWC2) #if CFG_TUD_DWC2_SLAVE_ENABLE - #define CFG_TUD_EDPT_DEDICATED_FIFO + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 1 #endif #if CFG_TUD_DWC2_SLAVE_ENABLE - #define CFG_TUH_EDPT_DEDICATED_FIFO + #define CFG_TUH_EDPT_DEDICATED_HWFIFO 1 #endif #endif -#if defined(CFG_TUD_EDPT_DEDICATED_FIFO) || defined(CFG_TUH_EDPT_DEDICATED_FIFO) - #define CFG_TUSB_FIFO_ACCESS_FIXED_ADDR_RW32 -#endif - //------------- ChipIdea -------------// // Enable CI_HS VBUS Charge. Set this to 1 if the USB_VBUS pin is not connected to 5V VBUS (note: 3.3V is // insufficient). @@ -590,6 +586,10 @@ #define CFG_TUD_NCM 0 #endif +#ifndef CFG_TUD_EDPT_DEDICATED_HWFIFO + #define CFG_TUD_EDPT_DEDICATED_HWFIFO 0 +#endif + //-------------------------------------------------------------------- // Host Options (Default) //-------------------------------------------------------------------- @@ -729,6 +729,10 @@ #define CFG_TUH_API_EDPT_XFER 0 #endif +#ifndef CFG_TUH_EDPT_DEDICATED_HWFIFO + #define CFG_TUH_EDPT_DEDICATED_HWFIFO 0 +#endif + //--------------------------------------------------------------------+ // TypeC Options (Default) //--------------------------------------------------------------------+ -- cgit v1.3.1 From 308bb956bf9d98e0f01db76b9433673d5563ec58 Mon Sep 17 00:00:00 2001 From: LeZerb Date: Thu, 11 Dec 2025 09:05:06 +0100 Subject: Use role TUSB_ROLE_HOST in host stack initialization --- docs/integration.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/integration.rst b/docs/integration.rst index f7c5be2ca..32f90f793 100644 --- a/docs/integration.rst +++ b/docs/integration.rst @@ -40,7 +40,7 @@ Minimal Example // init host stack on roothub port 1 for fullspeed host tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_DEVICE, + .role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_FULL }; tusb_init(1, &host_init); -- cgit v1.3.1 From 003d6ebac75e3b56814a68a957fc1ec52c98006e Mon Sep 17 00:00:00 2001 From: Aleksei Musin Date: Mon, 22 Dec 2025 15:16:09 +0400 Subject: ThreadX OSAL header is added. Docs are updated. --- docs/faq.rst | 2 +- src/osal/osal.h | 2 + src/osal/osal_threadx.h | 210 ++++++++++++++++++++++++++++++++++++++++++++++++ src/tusb_option.h | 1 + 4 files changed, 214 insertions(+), 1 deletion(-) create mode 100644 src/osal/osal_threadx.h (limited to 'docs') diff --git a/docs/faq.rst b/docs/faq.rst index a5fe09495..97e8e72ff 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -15,7 +15,7 @@ Yes, TinyUSB is released under the MIT license, allowing commercial use with min **Q: Does TinyUSB require an RTOS?** -No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, and Mynewt. +No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, ThreadX, and Mynewt. **Q: How much memory does TinyUSB use?** diff --git a/src/osal/osal.h b/src/osal/osal.h index 44521620f..7311fc962 100644 --- a/src/osal/osal.h +++ b/src/osal/osal.h @@ -65,6 +65,8 @@ typedef void (*osal_task_func_t)(void* param); #include "osal_rtx4.h" #elif CFG_TUSB_OS == OPT_OS_ZEPHYR #include "osal_zephyr.h" +#elif CFG_TUSB_OS == OPT_OS_THREADX + #include "osal_threadx.h" #elif CFG_TUSB_OS == OPT_OS_CUSTOM #include "tusb_os_custom.h" // implemented by application #else diff --git a/src/osal/osal_threadx.h b/src/osal/osal_threadx.h new file mode 100644 index 000000000..32c1c62c2 --- /dev/null +++ b/src/osal/osal_threadx.h @@ -0,0 +1,210 @@ +/* + * 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 TUSB_OSAL_THREADX_H_ +#define TUSB_OSAL_THREADX_H_ + +// ThreadX Headers +#include "tx_api.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/* +typedef struct +{ + uint16_t depth; + uint16_t item_sz; + void* buf; + char const* name; + TX_QUEUE *queue; + +} osal_queue_def_t; + +typedef TX_QUEUE * osal_queue_t; +*/ +//--------------------------------------------------------------------+ +// TASK API +//--------------------------------------------------------------------+ + +TU_ATTR_ALWAYS_INLINE static inline uint32_t _osal_ms2tick(uint32_t msec) { + if ( msec == TX_WAIT_FOREVER ) return TX_WAIT_FOREVER; + if ( msec == 0 ) return 0; + + uint32_t ticks = msec * TX_TIMER_TICKS_PER_SECOND / 1000; + + // TX_TIMER_TICKS_PER_SECOND is less than 1000 and 1 tick > 1 ms + // we still need to delay at least 1 tick + if ( ticks == 0 ) ticks = 1; + + return ticks; +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_task_delay(uint32_t msec) { + tx_thread_sleep(_osal_ms2tick(msec)); +} + +//--------------------------------------------------------------------+ +// Spinlock API +//--------------------------------------------------------------------+ +//--------------------------------------------------------------------+ +// Spinlock API +//--------------------------------------------------------------------+ +typedef struct { + void (* interrupt_set)(bool); +} osal_spinlock_t; + +// For SMP, spinlock must be locked by hardware, cannot just use interrupt +#define OSAL_SPINLOCK_DEF(_name, _int_set) \ + osal_spinlock_t _name = { .interrupt_set = _int_set } + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_init(osal_spinlock_t *ctx) { + (void) ctx; +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_lock(osal_spinlock_t *ctx, bool in_isr) { +// if (!in_isr) { +// ctx->interrupt_set(false); +// } +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_spin_unlock(osal_spinlock_t *ctx, bool in_isr) { +// if (!in_isr) { +// ctx->interrupt_set(true); +// } +} + + +//--------------------------------------------------------------------+ +// Binary Semaphore API +//--------------------------------------------------------------------+ +typedef TX_SEMAPHORE osal_semaphore_def_t, * osal_semaphore_t; + +/* +TU_ATTR_ALWAYS_INLINE static inline osal_semaphore_t osal_semaphore_create(osal_semaphore_def_t *semdef) { + tx_semaphore_create(semdef->semaphore, semdef->name, 0); + return semdef; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_delete(osal_semaphore_t semd_hdl) { + (void) semd_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_post(osal_semaphore_t sem_hdl, bool in_isr) { + (void) in_isr; + tx_semaphore_put(sem_hdl); + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_semaphore_wait(osal_semaphore_t sem_hdl, uint32_t msec) { + return TX_SUCCESS == tx_semaphore_get(sem_hdl, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline void osal_semaphore_reset(osal_semaphore_t sem_hdl) { +} +*/ +//--------------------------------------------------------------------+ +// MUTEX API +//--------------------------------------------------------------------+ +typedef TX_MUTEX osal_mutex_def_t, *osal_mutex_t; + +TU_ATTR_ALWAYS_INLINE static inline osal_mutex_t osal_mutex_create(osal_mutex_def_t *mdef) { + if (TX_SUCCESS == tx_mutex_create(mdef, mdef->tx_mutex_name, TX_NO_INHERIT)) { + return mdef; + } else { + return NULL; + } +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_delete(osal_mutex_t mutex_hdl) { + (void) mutex_hdl; + return true; // nothing to do +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_lock(osal_mutex_t mutex_hdl, uint32_t msec) { + return TX_SUCCESS == tx_mutex_get(mutex_hdl, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_mutex_unlock(osal_mutex_t mutex_hdl) { + return TX_SUCCESS == tx_mutex_put(mutex_hdl); +} + +//--------------------------------------------------------------------+ +// QUEUE API +//--------------------------------------------------------------------+ + +typedef TX_QUEUE osal_queue_def_t, * osal_queue_t; + +// _int_set is not used with an RTOS _usbd_qdef + +#define OSAL_QUEUE_DEF(_int_set, _name, _depth, _type) \ +static _type _name##_buf[_depth]; \ +osal_queue_def_t _name = { \ + .tx_queue_name = #_name, \ + .tx_queue_message_size = (sizeof(_type) + 3) / 4, \ + .tx_queue_capacity = _depth, \ + .tx_queue_start = _name##_buf } + + +// Event queue: usbd_int_set() is used as mutex in OS NONE config +/* +OSAL_QUEUE_DEF(usbd_int_set, _usbd_qdef, CFG_TUD_TASK_QUEUE_SZ, dcd_event_t); +static osal_queue_t _usbd_q; +*/ + + +TU_ATTR_ALWAYS_INLINE static inline osal_queue_t osal_queue_create(osal_queue_def_t* qdef) { + return TX_SUCCESS == + tx_queue_create(qdef, qdef->tx_queue_name, qdef->tx_queue_message_size, qdef->tx_queue_start, qdef->tx_queue_capacity * qdef->tx_queue_message_size * 4) + ? qdef : 0; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_delete(osal_queue_t qhdl) { + (void) qhdl; + return true; +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_receive(osal_queue_t qhdl, void* data, uint32_t msec) { + return 0 == tx_queue_receive(qhdl, data, _osal_ms2tick(msec)); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_send(osal_queue_t qhdl, void *data, bool in_isr) { + return 0 == tx_queue_send(qhdl, data, in_isr ? TX_NO_WAIT : TX_WAIT_FOREVER); +} + +TU_ATTR_ALWAYS_INLINE static inline bool osal_queue_empty(osal_queue_t qhdl) { + ULONG enqueued; + tx_queue_info_get(qhdl, 0, &enqueued, 0, 0, 0, 0); + return enqueued == 0; +} + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/src/tusb_option.h b/src/tusb_option.h index 64fe899db..08bf0ebc5 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -237,6 +237,7 @@ #define OPT_OS_RTTHREAD 6 ///< RT-Thread #define OPT_OS_RTX4 7 ///< Keil RTX 4 #define OPT_OS_ZEPHYR 8 ///< Zephyr +#define OPT_OS_THREADX 9 ///< ThreadX //--------------------------------------------------------------------+ // Mode and Speed -- cgit v1.3.1 From 83542ce912f902d78908eac7e0b0bb8830cb7741 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:18:17 +0000 Subject: Add detailed build instructions for rp2040 and esp32 to getting_started.rst - Added dedicated "Building for RP2040" section with pico-sdk installation steps - Added dedicated "Building for ESP32" section with esp-idf installation steps - Included platform-specific instructions for Linux/macOS and Windows - Added PICO_SDK_PATH export steps before cmake for rp2040 - Added esp-idf source/export steps before cmake for esp32 - Updated note section to reference new detailed sections - Documentation builds successfully without errors Co-authored-by: HiFiPhile <4375114+HiFiPhile@users.noreply.github.com> --- docs/getting_started.rst | 129 ++++++++++++++++++++++++++++++++++++++++++++++- 1 file changed, 128 insertions(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 0c3fcec80..9f558bfa4 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -34,7 +34,10 @@ Get the Code $ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7 .. note:: - For rp2040 `pico-sdk `_ or `esp-idf `_ for Espressif targets are required; install them per vendor instructions. + Some MCU families require additional SDKs: + + * **rp2040**: Requires `pico-sdk `_ - see `Building for RP2040`_ below + * **Espressif (esp32)**: Requires `esp-idf `_ - see `Building for ESP32`_ below Simple Device Example --------------------- @@ -149,6 +152,130 @@ A MCU can support multiple operational speed. By default, the example build syst $ make BOARD=stm32h743eval RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all +Building for RP2040 +------------------- + +RP2040 boards (like Raspberry Pi Pico) require the Pico SDK to be installed and configured before building. + +Install Pico SDK +^^^^^^^^^^^^^^^^ + +**Linux/macOS:** + +.. code-block:: bash + + $ cd ~ + $ git clone https://github.com/raspberrypi/pico-sdk.git + $ cd pico-sdk + $ git submodule update --init + +**Windows:** + +.. code-block:: bash + + C:\> cd %USERPROFILE% + C:\Users\YourName> git clone https://github.com/raspberrypi/pico-sdk.git + C:\Users\YourName> cd pico-sdk + C:\Users\YourName\pico-sdk> git submodule update --init + +Set PICO_SDK_PATH +^^^^^^^^^^^^^^^^^ + +Before running cmake, export the SDK path: + +**Linux/macOS:** + +.. code-block:: bash + + $ export PICO_SDK_PATH=~/pico-sdk + +**Windows (Command Prompt):** + +.. code-block:: bash + + C:\> set PICO_SDK_PATH=%USERPROFILE%\pico-sdk + +**Windows (PowerShell):** + +.. code-block:: bash + + PS C:\> $env:PICO_SDK_PATH = "$env:USERPROFILE\pico-sdk" + +Build Example for RP2040 +^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ cmake -DBOARD=raspberry_pi_pico -B build + $ cmake --build build + +.. tip:: + Add the PICO_SDK_PATH export to your shell's profile file (e.g., ``~/.bashrc``, ``~/.zshrc``) to make it permanent. + + +Building for ESP32 +------------------ + +ESP32 boards require the ESP-IDF (Espressif IoT Development Framework) to be installed and sourced before building. + +Install ESP-IDF +^^^^^^^^^^^^^^^ + +**Linux/macOS:** + +.. code-block:: bash + + $ cd ~ + $ git clone --recursive https://github.com/espressif/esp-idf.git + $ cd esp-idf + $ ./install.sh all + +**Windows:** + +.. code-block:: bash + + C:\> cd %USERPROFILE% + C:\Users\YourName> git clone --recursive https://github.com/espressif/esp-idf.git + C:\Users\YourName> cd esp-idf + C:\Users\YourName\esp-idf> install.bat all + +Source ESP-IDF Environment +^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +Before running cmake, source the ESP-IDF export script: + +**Linux/macOS:** + +.. code-block:: bash + + $ source ~/esp-idf/export.sh + +**Windows (Command Prompt):** + +.. code-block:: bash + + C:\> %USERPROFILE%\esp-idf\export.bat + +**Windows (PowerShell):** + +.. code-block:: bash + + PS C:\> . $env:USERPROFILE\esp-idf\export.ps1 + +Build Example for ESP32 +^^^^^^^^^^^^^^^^^^^^^^^^ + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ cmake -DBOARD=espressif_s3_devkitc -B build + $ cmake --build build + +.. tip:: + You need to source the ESP-IDF export script in each new terminal session. Consider creating an alias in your shell's profile file for convenience. + + IAR Embedded Workbench ---------------------- -- cgit v1.3.1 From 1bb1efa8202c0cb5e49fa3fc50c608ac03daaa71 Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:19:52 +0000 Subject: Use appropriate syntax highlighting for Windows commands - Changed Windows Command Prompt blocks from bash to bat for proper highlighting - Changed PowerShell blocks from bash to powershell for proper highlighting - Improves documentation readability and accuracy Co-authored-by: HiFiPhile <4375114+HiFiPhile@users.noreply.github.com> --- docs/getting_started.rst | 12 ++++++------ 1 file changed, 6 insertions(+), 6 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 9f558bfa4..7ab3116df 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -171,7 +171,7 @@ Install Pico SDK **Windows:** -.. code-block:: bash +.. code-block:: bat C:\> cd %USERPROFILE% C:\Users\YourName> git clone https://github.com/raspberrypi/pico-sdk.git @@ -191,13 +191,13 @@ Before running cmake, export the SDK path: **Windows (Command Prompt):** -.. code-block:: bash +.. code-block:: bat C:\> set PICO_SDK_PATH=%USERPROFILE%\pico-sdk **Windows (PowerShell):** -.. code-block:: bash +.. code-block:: powershell PS C:\> $env:PICO_SDK_PATH = "$env:USERPROFILE\pico-sdk" @@ -233,7 +233,7 @@ Install ESP-IDF **Windows:** -.. code-block:: bash +.. code-block:: bat C:\> cd %USERPROFILE% C:\Users\YourName> git clone --recursive https://github.com/espressif/esp-idf.git @@ -253,13 +253,13 @@ Before running cmake, source the ESP-IDF export script: **Windows (Command Prompt):** -.. code-block:: bash +.. code-block:: bat C:\> %USERPROFILE%\esp-idf\export.bat **Windows (PowerShell):** -.. code-block:: bash +.. code-block:: powershell PS C:\> . $env:USERPROFILE\esp-idf\export.ps1 -- cgit v1.3.1 From db08f5f3fefb91ef59526558ad79bf9d8ae84e7c Mon Sep 17 00:00:00 2001 From: "copilot-swe-agent[bot]" <198982749+Copilot@users.noreply.github.com> Date: Sun, 28 Dec 2025 14:26:06 +0000 Subject: Fix trailing whitespace in getting_started.rst - Removed trailing whitespace from line 37 as detected by pre-commit check - Documentation builds successfully Co-authored-by: HiFiPhile <4375114+HiFiPhile@users.noreply.github.com> --- docs/getting_started.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 7ab3116df..d9d81f23f 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -35,7 +35,7 @@ Get the Code .. note:: Some MCU families require additional SDKs: - + * **rp2040**: Requires `pico-sdk `_ - see `Building for RP2040`_ below * **Espressif (esp32)**: Requires `esp-idf `_ - see `Building for ESP32`_ below -- cgit v1.3.1 From 239e20ba7399fc026325c4cd8c98c08a160a9773 Mon Sep 17 00:00:00 2001 From: zhiqiang-ch Date: Tue, 30 Dec 2025 10:44:03 +0800 Subject: support for the AT32F45X series --- README.rst | 3 +- docs/reference/boards.rst | 3 + docs/reference/dependencies.rst | 1 + hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h | 177 ++++++++++++++++ hw/bsp/at32f45x/at32f45x_clock.c | 114 ++++++++++ hw/bsp/at32f45x/at32f45x_clock.h | 45 ++++ hw/bsp/at32f45x/at32f45x_conf.h | 174 +++++++++++++++ hw/bsp/at32f45x/at32f45x_int.c | 101 +++++++++ hw/bsp/at32f45x/at32f45x_int.h | 60 ++++++ hw/bsp/at32f45x/boards/at_start_f455/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f455/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f455/board.mk | 7 + hw/bsp/at32f45x/boards/at_start_f456/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f456/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f456/board.mk | 7 + hw/bsp/at32f45x/boards/at_start_f457/board.cmake | 8 + hw/bsp/at32f45x/boards/at_start_f457/board.h | 96 +++++++++ hw/bsp/at32f45x/boards/at_start_f457/board.mk | 7 + hw/bsp/at32f45x/family.c | 258 +++++++++++++++++++++++ hw/bsp/at32f45x/family.cmake | 97 +++++++++ hw/bsp/at32f45x/family.mk | 40 ++++ src/common/tusb_mcu.h | 5 + src/portable/synopsys/dwc2/dwc2_at32.h | 5 + src/tusb_option.h | 1 + tools/get_deps.py | 3 + 25 files changed, 1419 insertions(+), 1 deletion(-) create mode 100644 hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/at32f45x/at32f45x_clock.c create mode 100644 hw/bsp/at32f45x/at32f45x_clock.h create mode 100644 hw/bsp/at32f45x/at32f45x_conf.h create mode 100644 hw/bsp/at32f45x/at32f45x_int.c create mode 100644 hw/bsp/at32f45x/at32f45x_int.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f455/board.mk create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f456/board.mk create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.cmake create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.h create mode 100644 hw/bsp/at32f45x/boards/at_start_f457/board.mk create mode 100644 hw/bsp/at32f45x/family.c create mode 100644 hw/bsp/at32f45x/family.cmake create mode 100644 hw/bsp/at32f45x/family.mk (limited to 'docs') diff --git a/README.rst b/README.rst index 178a084ce..29b2f4fca 100644 --- a/README.rst +++ b/README.rst @@ -141,7 +141,8 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ | Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | Packet SRAM 512 | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | F415, F435_437, F423, F425 | ✔ | ✔ | | dwc2 | | +| | F415, F435_437, F423, | ✔ | ✔ | | dwc2 | | +| | F425, F45x | | | | | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS | +--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 12da5c90b..cacf52e1a 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -44,6 +44,9 @@ at_start_f423 AT-START-F423 at32f423 https:/ at_start_f425 AT-START-F425 at32f425 https://www.arterychip.com/en/product/AT32F425.jsp at_start_f435 AT-START-F435 at32f435_437 https://www.arterychip.com/en/product/AT32F435.jsp at_start_f437 AT-START-F437 at32f435_437 https://www.arterychip.com/en/product/AT32F437.jsp +at_start_f455 AT-START-F455 at32f45x https://www.arterychip.com/en/product/AT32F455.jsp +at_start_f456 AT-START-F456 at32f45x https://www.arterychip.com/en/product/AT32F456.jsp +at_start_f457 AT-START-F457 at32f45x https://www.arterychip.com/en/product/AT32F457.jsp ========================= ============================= ============= ==================================================== ====== Bridgetek diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index de1603383..ce5f265d5 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -16,6 +16,7 @@ hw/mcu/artery/at32f415 https://github.com/ArteryTek/AT32F415_ hw/mcu/artery/at32f423 https://github.com/ArteryTek/AT32F423_Firmware_Library.git 2afa7f12852e57a9e8aab3a892c641e1a8635a18 at32f423 hw/mcu/artery/at32f425 https://github.com/ArteryTek/AT32F425_Firmware_Library.git 620233e1357d5c1b7e2bde6b9dd5196822b91817 at32f425 hw/mcu/artery/at32f435_437 https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git 25439cc6650a8ae0345934e8707a5f38c7ae41f8 at32f435_437 +hw/mcu/artery/at32f45x https://github.com/ArteryTek/AT32F45x_Firmware_Library.git 3d4a1b38be8ebac292e2350ca53bc4bfa4430233 at32f45x hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 diff --git a/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..8a9906d39 --- /dev/null +++ b/hw/bsp/at32f45x/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,177 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ +// Include MCU header + #include "at32f45x.h" + +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE ( 1024 ) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 128 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +#ifdef __RX__ +/* Renesas RX series */ +#define vSoftwareInterruptISR INT_Excep_ICU_SWINT +#define vTickISR INT_Excep_CMT0_CMI0 +#define configPERIPHERAL_CLOCK_HZ (configCPU_CLOCK_HZ/2) +#define configKERNEL_INTERRUPT_PRIORITY 1 +#define configMAX_SYSCALL_INTERRUPT_PRIORITY 4 + +#else + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ +#if defined(__NVIC_PRIO_BITS) + // For Cortex-M specific: __NVIC_PRIO_BITS is defined in core_cmx.h + #define configPRIO_BITS __NVIC_PRIO_BITS + +#elif defined(__ECLIC_INTCTLBITS) + // RISC-V Bumblebee core from nuclei + #define configPRIO_BITS __ECLIC_INTCTLBITS + +#elif defined(__IASMARM__) + // FIXME: IAR Assembler cannot include mcu header directly to get __NVIC_PRIO_BITS. + // Therefore we will hard coded it to minimum value of 2 to get pass ci build. + // IAR user must update this to correct value of the target MCU + #message "configPRIO_BITS is hard coded to 2 to pass IAR build only. User should update it per MCU" + #define configPRIO_BITS 2 + +#else + #error "FreeRTOS configPRIO_BITS to be defined" +#endif + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<dt = (*((uint8_t const *) buf) & 0x01FF); + buf++; + } + return len; +#else + (void) buf; + (void) len; + return 0; +#endif +} + +#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; +} + +void SVC_Handler(void) { +} + +void PendSV_Handler(void) { +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void); +void _init(void) { +} + +#ifdef USE_FULL_ASSERT +void assert_failed(const char *file, uint32_t line) { + /* USER CODE BEGIN 6 */ + /* User can add his own implementation to report the file name and line number, + tex: printf("Wrong parameters value: file %s on line %d\r\n", file, line) */ + /* USER CODE END 6 */ +} +#endif /* USE_FULL_ASSERT */ diff --git a/hw/bsp/at32f45x/family.cmake b/hw/bsp/at32f45x/family.cmake new file mode 100644 index 000000000..fe13347af --- /dev/null +++ b/hw/bsp/at32f45x/family.cmake @@ -0,0 +1,97 @@ +include_guard() + +set(AT32_FAMILY at32f45x) +set(AT32_SDK_LIB ${TOP}/hw/mcu/artery/${AT32_FAMILY}/libraries) + +string(TOUPPER ${AT32_FAMILY} AT32_FAMILY_UPPER) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS ${AT32_FAMILY_UPPER} CACHE INTERNAL "") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +set(STARTUP_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s) +set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) +set(STARTUP_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s) +if (NOT DEFINED LD_FILE_GNU) +set(LD_FILE_GNU ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld) +endif () +set(LD_FILE_Clang ${LD_FILE_GNU}) +set(LD_FILE_IAR ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${AT32_SDK_LIB}/cmsis/cm4/device_support/system_${AT32_FAMILY}.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_gpio.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_misc.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_usart.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_acc.c + ${AT32_SDK_LIB}/drivers/src/${AT32_FAMILY}_crm.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${AT32_SDK_LIB}/cmsis/cm4/core_support + ${AT32_SDK_LIB}/cmsis/cm4/device_support + ${AT32_SDK_LIB}/drivers/inc + ) + + update_board(${BOARD_TARGET}) +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_${AT32_FAMILY_UPPER}) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_clock.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/${AT32_FAMILY}_int.c + ${TOP}/src/portable/synopsys/dwc2/dcd_dwc2.c + ${TOP}/src/portable/synopsys/dwc2/hcd_dwc2.c + ${TOP}/src/portable/synopsys/dwc2/dwc2_common.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + + set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES + SKIP_LINTING ON + COMPILE_OPTIONS -w) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) +endfunction() diff --git a/hw/bsp/at32f45x/family.mk b/hw/bsp/at32f45x/family.mk new file mode 100644 index 000000000..e42f27557 --- /dev/null +++ b/hw/bsp/at32f45x/family.mk @@ -0,0 +1,40 @@ +AT32_FAMILY = at32f45x +AT32_SDK_LIB = hw/mcu/artery/${AT32_FAMILY}/libraries + +include $(TOP)/$(BOARD_PATH)/board.mk + +CPU_CORE ?= cortex-m4 + +CFLAGS_GCC += \ + -flto + +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_AT32F45X \ + +LDFLAGS_GCC += \ + -flto --specs=nosys.specs -nostdlib -nostartfiles + +SRC_C += \ + src/portable/synopsys/dwc2/dcd_dwc2.c \ + src/portable/synopsys/dwc2/hcd_dwc2.c \ + src/portable/synopsys/dwc2/dwc2_common.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_gpio.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_misc.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_usart.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_crm.c \ + $(AT32_SDK_LIB)/drivers/src/${AT32_FAMILY}_acc.c \ + $(AT32_SDK_LIB)/cmsis/cm4/device_support/system_${AT32_FAMILY}.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(AT32_SDK_LIB)/drivers/inc \ + $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/core_support \ + $(TOP)/$(AT32_SDK_LIB)/cmsis/cm4/device_support + +SRC_S_GCC += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/startup_${AT32_FAMILY}.s +SRC_S_IAR += ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/startup_${AT32_FAMILY}.s + +LD_FILE_GCC ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/gcc/linker/${MCU_LINKER_NAME}_FLASH.ld +LD_FILE_IAR ?= ${AT32_SDK_LIB}/cmsis/cm4/device_support/startup/iar/linker/${MCU_LINKER_NAME}.icf + +flash: flash-atlink diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 55f7e0b7c..ce690acb8 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -661,6 +661,11 @@ #define TUP_USBIP_DWC2_AT32 #define TUP_DCD_ENDPOINT_MAX 8 +#elif TU_CHECK_MCU(OPT_MCU_AT32F45X) + #define TUP_USBIP_DWC2 + #define TUP_USBIP_DWC2_AT32 + #define TUP_DCD_ENDPOINT_MAX 8 + //--------------------------------------------------------------------+ // HPMicro //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dwc2_at32.h b/src/portable/synopsys/dwc2/dwc2_at32.h index 513495eb1..10824ae92 100644 --- a/src/portable/synopsys/dwc2/dwc2_at32.h +++ b/src/portable/synopsys/dwc2/dwc2_at32.h @@ -61,6 +61,11 @@ #define OTG1_FIFO_SIZE 1280 #define OTG1_IRQn OTGFS1_IRQn #define DWC2_OTG1_REG_BASE 0x50000000UL +#elif CFG_TUSB_MCU == OPT_MCU_AT32F45X + #include + #define OTG1_FIFO_SIZE 1280 + #define OTG1_IRQn OTGFS1_IRQn + #define DWC2_OTG1_REG_BASE 0x50000000UL #endif #ifdef __cplusplus diff --git a/src/tusb_option.h b/src/tusb_option.h index 64fe899db..35a0d97db 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -216,6 +216,7 @@ #define OPT_MCU_AT32F402_405 2504 ///< ArteryTek AT32F402_405 #define OPT_MCU_AT32F425 2505 ///< ArteryTek AT32F425 #define OPT_MCU_AT32F413 2506 ///< ArteryTek AT32F413 +#define OPT_MCU_AT32F45X 2507 ///< ArteryTek AT32F45x // HPMicro #define OPT_MCU_HPM 2600 ///< HPMicro diff --git a/tools/get_deps.py b/tools/get_deps.py index deacbb23b..773445adc 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -244,6 +244,9 @@ deps_optional = { 'hw/mcu/artery/at32f413': ['https://github.com/ArteryTek/AT32F413_Firmware_Library.git', 'f6fe62dfec9fd40c5b63d92fc5ef2c2b5e77a450', 'at32f413'], + 'hw/mcu/artery/at32f45x': ['https://github.com/ArteryTek/AT32F45x_Firmware_Library.git', + '3d4a1b38be8ebac292e2350ca53bc4bfa4430233', + 'at32f45x'], 'hw/mcu/hpmicro/hpm_sdk': ['https://github.com/hpmicro/hpm_sdk', '8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff', 'hpmicro'], -- cgit v1.3.1 From 104d3f2545e460ead95dc8482fcadcf98c3749e1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 14 Jan 2026 00:18:26 +0100 Subject: bsp: add TI EK-TM4C1294XL Signed-off-by: HiFiPhile --- docs/reference/boards.rst | 1 + examples/device/dfu/skip.txt | 2 +- hw/bsp/BoardPresets.json | 44 ++++++++++++++ hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h | 8 ++- hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h | 6 ++ hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld | 2 +- hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf | 28 +++++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake | 13 +++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h | 75 ++++++++++++++++++++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk | 16 ++++++ hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld | 66 +++++++++++++++++++++ hw/bsp/tm4c/family.c | 76 ++++++++++++++++++++----- hw/bsp/tm4c/family.cmake | 14 ++--- hw/bsp/tm4c/family.mk | 6 +- src/portable/mentor/musb/musb_ti.h | 5 +- src/portable/mentor/musb/musb_type.h | 2 +- 16 files changed, 333 insertions(+), 31 deletions(-) create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk create mode 100644 hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index cacf52e1a..09c90e08f 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -333,6 +333,7 @@ Board Name Family URL msp_exp430f5529lp MSP430F5529 LaunchPad msp430 https://www.ti.com/tool/MSP-EXP430F5529LP msp_exp432e401y MSP432E401Y LaunchPad msp432e4 https://www.ti.com/tool/MSP-EXP432E401Y ek_tm4c123gxl TM4C123G LaunchPad tm4c https://www.ti.com/tool/EK-TM4C123GXL +ek_tm4c1294xl TM4C1294 LaunchPad tm4c https://www.ti.com/tool/EK-TM4C1294XL ================= ===================== ======== ========================================= ====== Tomu diff --git a/examples/device/dfu/skip.txt b/examples/device/dfu/skip.txt index 9dde06c30..79d3da9d2 100644 --- a/examples/device/dfu/skip.txt +++ b/examples/device/dfu/skip.txt @@ -1,3 +1,3 @@ -mcu:TM4C123 +mcu:TM4C mcu:BCM2835 family:espressif diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 440ef8733..fabbeed93 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -174,6 +174,10 @@ "name": "ek_tm4c123gxl", "inherits": "default" }, + { + "name": "ek_tm4c1294xl", + "inherits": "default" + }, { "name": "f1c100s", "inherits": "default" @@ -718,6 +722,10 @@ "name": "stm32h745disco", "inherits": "default" }, + { + "name": "stm32h747disco", + "inherits": "default" + }, { "name": "stm32h750_weact", "inherits": "default" @@ -1108,6 +1116,11 @@ "description": "Build preset for the ek_tm4c123gxl board", "configurePreset": "ek_tm4c123gxl" }, + { + "name": "ek_tm4c1294xl", + "description": "Build preset for the ek_tm4c1294xl board", + "configurePreset": "ek_tm4c1294xl" + }, { "name": "espressif_addax_1", "description": "Build preset for the espressif_addax_1 board", @@ -1833,6 +1846,11 @@ "description": "Build preset for the stm32h745disco board", "configurePreset": "stm32h745disco" }, + { + "name": "stm32h747disco", + "description": "Build preset for the stm32h747disco board", + "configurePreset": "stm32h747disco" + }, { "name": "stm32h750_weact", "description": "Build preset for the stm32h750_weact board", @@ -2542,6 +2560,19 @@ } ] }, + { + "name": "ek_tm4c1294xl", + "steps": [ + { + "type": "configure", + "name": "ek_tm4c1294xl" + }, + { + "type": "build", + "name": "ek_tm4c1294xl" + } + ] + }, { "name": "espressif_addax_1", "steps": [ @@ -4427,6 +4458,19 @@ } ] }, + { + "name": "stm32h747disco", + "steps": [ + { + "type": "configure", + "name": "stm32h747disco" + }, + { + "type": "build", + "name": "stm32h747disco" + } + ] + }, { "name": "stm32h750_weact", "steps": [ diff --git a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h index 454b085e9..b4423e269 100644 --- a/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h +++ b/hw/bsp/tm4c/FreeRTOSConfig/FreeRTOSConfig.h @@ -44,7 +44,13 @@ // skip if included from IAR assembler #ifndef __IASMARM__ - #include "TM4C123.h" + #ifdef TM4C123GH6PM + #include "TM4C123.h" + #elif TM4C1294NCPDT + #include "TM4C129.h" + #else + #error "Unknown TM4C device" + #endif #endif /* Cortex M23/M33 port configuration. */ diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h index c0ceb4cd8..fc0ab4c60 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/board.h @@ -36,20 +36,26 @@ extern "C" { #endif +#include "TM4C123.h" + #define BOARD_UART UART0 #define BOARD_UART_PORT GPIOA +#define BTN_PORT_CLK 5 #define BOARD_BTN_PORT GPIOF #define BOARD_BTN 4 #define BOARD_BTN_Msk (1u<<4) #define BUTTON_STATE_ACTIVE 0 +#define LED_PORT_CLK 5 #define LED_PORT GPIOF #define LED_PIN_RED 1 #define LED_PIN_BLUE 2 #define LED_PIN_GREEN 3 #define LED_STATE_ON 1 +#define BOARD_LED_PIN LED_PIN_BLUE + #ifdef __cplusplus } #endif diff --git a/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld b/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld index 11e9608cc..3f06d8f03 100644 --- a/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld +++ b/hw/bsp/tm4c/boards/ek_tm4c123gxl/tm4c123.ld @@ -17,7 +17,7 @@ SECTIONS .text : { . = ALIGN(4) ; - *(.vectors) + KEEP(*(.vectors)) *(.text) *(.text.*) *(.init) diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf b/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf new file mode 100644 index 000000000..2dba41866 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/TM4C1294NC.icf @@ -0,0 +1,28 @@ +/*###ICF### Section handled by ICF editor, don't touch! ****/ +/*-Editor annotation file-*/ +/* IcfEditorFile="$TOOLKIT_DIR$\config\ide\IcfEditor\cortex_v1_0.xml" */ +/*-Specials-*/ +define symbol __ICFEDIT_intvec_start__ = 0x00000000; +/*-Memory Regions-*/ +define symbol __ICFEDIT_region_ROM_start__ = 0x00000000; +define symbol __ICFEDIT_region_ROM_end__ = 0x000FFFFF; +define symbol __ICFEDIT_region_RAM_start__ = 0x20000000; +define symbol __ICFEDIT_region_RAM_end__ = 0x2003FFFF; +/*-Sizes-*/ +define symbol __ICFEDIT_size_cstack__ = 0x8000; +define symbol __ICFEDIT_size_heap__ = 0x10000; +/**** End of ICF editor section. ###ICF###*/ + +define memory mem with size = 4G; +define region ROM_region = mem:[from __ICFEDIT_region_ROM_start__ to __ICFEDIT_region_ROM_end__]; +define region RAM_region = mem:[from __ICFEDIT_region_RAM_start__ to __ICFEDIT_region_RAM_end__]; + +define block CSTACK with alignment = 8, size = __ICFEDIT_size_cstack__ { }; +define block HEAP with alignment = 8, size = __ICFEDIT_size_heap__ { }; + +initialize by copy { readwrite }; + +place at address mem:__ICFEDIT_intvec_start__ { readonly section .intvec }; +place in ROM_region { readonly }; +place in RAM_region { readwrite, + block CSTACK, block HEAP }; diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake new file mode 100644 index 000000000..3e03b3f72 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.cmake @@ -0,0 +1,13 @@ +set(MCU_SUB_VARIANT 129) + +set(JLINK_DEVICE TM4C1294NCPDT) +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/tm4c1294nc.ld) +set(LD_FILE_IAR ${CMAKE_CURRENT_LIST_DIR}/TM4C1294NC.icf) + +set(OPENOCD_OPTION "-f board/ti_ek-tm4c1294xl.cfg") + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + TM4C1294NCPDT + ) +endfunction() diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h new file mode 100644 index 000000000..4530e9430 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.h @@ -0,0 +1,75 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, 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. + */ + +/* metadata: + name: TM4C1294 LaunchPad + url: https://www.ti.com/tool/EK-TM4C1294XL +*/ + +#ifndef _BOARD_H_ +#define _BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#include "TM4C129.h" + +#define BOARD_UART UART0 +#define BOARD_UART_PORT GPIOA + +#define BTN_PORT_CLK 8 +#define BOARD_BTN_PORT GPIOJ +#define BOARD_BTN 0 +#define BOARD_BTN_Msk (1u<<0) +#define BUTTON_STATE_ACTIVE 0 + +#define LED_PORT_CLK 12 +#define LED_PORT GPION +#define LED_PIN_1 1 +#define LED_PIN_2 0 +#define LED_STATE_ON 1 + +#define BOARD_LED_PIN LED_PIN_2 + +#define GPIOA GPIOA_AHB +#define GPIOB GPIOB_AHB +#define GPIOC GPIOC_AHB +#define GPIOD GPIOD_AHB +#define GPIOE GPIOE_AHB +#define GPIOF GPIOF_AHB +#define GPIOG GPIOG_AHB +#define GPIOH GPIOH_AHB +#define GPIOI GPIOI_AHB +#define GPIOJ GPIOJ_AHB + +#define GPIOA_Type GPIOA_AHB_Type + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk new file mode 100644 index 000000000..b01977674 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/board.mk @@ -0,0 +1,16 @@ +MCU_SUB_VARIANT = 129 + +CFLAGS += -DTM4C1294NCPDT + +LD_FILE_GCC = $(BOARD_PATH)/tm4c1294nc.ld +LD_FILE_IAR = $(BOARD_PATH)/TM4C1294NC.icf + +# For flash-jlink target +JLINK_DEVICE = TM4C1294NCPDT + +# flash using openocd +OPENOCD_OPTION = -f board/ti_ek-tm4c1294xl.cfg + +UNIFLASH_OPTION = -c ${TOP}/${BOARD_PATH}/${BOARD}.ccxml -r 1 + +flash: flash-openocd diff --git a/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld b/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld new file mode 100644 index 000000000..fa4ea4dc5 --- /dev/null +++ b/hw/bsp/tm4c/boards/ek_tm4c1294xl/tm4c1294nc.ld @@ -0,0 +1,66 @@ +ENTRY(Reset_Handler) + +_estack = 0x20008000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0; /* required amount of heap */ +_Min_Stack_Size = 0x1000; /* required amount of stack */ + + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x00100000 + SRAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x00040000 +} + +SECTIONS +{ + .text : + { + . = ALIGN(4) ; + _text = . ; + KEEP(*(.isr_vector)) + *(.text) + *(.text.*) + *(.init) + *(.fini) + *(.rodata) + *(.rodata.*) + *(.ARM.exidx*) + _etext = . ; + . = ALIGN(4) ; + } >FLASH + + .data : AT(ADDR(.text) + SIZEOF(.text)) + { + _data = .; + . = ALIGN(4); + _ldata = LOADADDR (.data); + *(.data) + *(.data.*) + _edata = .; + . = ALIGN(4); + + } >SRAM + + .bss : + { + . = ALIGN(4) ; + _bss = .; + *(.bss) + *(.bss.*) + *(.COMMON) + _ebss = .; + . = ALIGN(4); + }>SRAM + + /* User_heap_stack section, used to check that there is enough RAM left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >SRAM +} diff --git a/hw/bsp/tm4c/family.c b/hw/bsp/tm4c/family.c index ee1fa2a3c..ae7f22f00 100644 --- a/hw/bsp/tm4c/family.c +++ b/hw/bsp/tm4c/family.c @@ -2,7 +2,6 @@ manufacturer: Texas Instruments */ -#include "TM4C123.h" #include "bsp/board_api.h" #include "board.h" @@ -27,6 +26,9 @@ static void board_uart_init(void) { SYSCTL->RCGCUART |= (1 << 0); // Enable the clock to UART0 SYSCTL->RCGCGPIO |= (1 << 0); // Enable the clock to GPIOA + while (!(SYSCTL->PRGPIO & (1 << 0))) {} // Wait for the GPIOA clock to stabilize + while (!(SYSCTL->PRUART & (1 << 0))) {} // Wait for the UART0 clock to stabilize + GPIOA->AFSEL |= (1 << 1) | (1 << 0); // Enable the alternate function on pin PA0 & PA1 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 @@ -44,12 +46,26 @@ static void board_uart_init(void) { UART0->CTL = (1 << 0) | (1 << 8) | (1 << 9); // UART0 Enable, Transmit Enable, Receive Enable } -static void initialize_board_led(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { - /* Enable PortF Clock */ - SYSCTL->RCGCGPIO |= (1 << 5); +static void board_button_init(GPIOA_Type* port, uint8_t PinMsk) { + /* Enable Port Clock */ + SYSCTL->RCGCGPIO |= (1 << BTN_PORT_CLK); + + /* Let the clock stabilize */ + while (!((SYSCTL->PRGPIO) & (1 << BTN_PORT_CLK))) {} + + /* Port Digital Enable */ + port->DEN |= PinMsk; + + /* Set direction */ + port->DIR &= ~PinMsk; +} + +static void board_led_init(GPIOA_Type* port, uint8_t PinMsk, uint8_t dirmsk) { + /* Enable Port Clock */ + SYSCTL->RCGCGPIO |= (1 << LED_PORT_CLK); /* Let the clock stabilize */ - while (!((SYSCTL->PRGPIO) & (1 << 5))) {} + while (!((SYSCTL->PRGPIO) & (1 << LED_PORT_CLK))) {} /* Port Digital Enable */ port->DEN |= PinMsk; @@ -71,7 +87,9 @@ static uint32_t ReadGPIOPin(GPIOA_Type* port, uint8_t pinMsk) { } void board_init(void) { +#ifdef TM4C123_H SystemCoreClockUpdate(); +#endif #if CFG_TUSB_OS == OPT_OS_NONE // 1ms tick timer @@ -83,6 +101,7 @@ void board_init(void) { NVIC_SetPriority(USB0_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY ); #endif +#ifdef TM4C123_H /* Reset USB */ SYSCTL->SRCR2 |= (1u << 16); @@ -99,7 +118,7 @@ void board_init(void) { /* USB IO Initialization */ SYSCTL->RCGCGPIO |= (1u << 3); - /* Let the clock stabilize */ + /* Let the clock stabilize */ while (!(SYSCTL->PRGPIO & (1u << 3))) {} /* USB IOs to Analog Mode */ @@ -107,16 +126,43 @@ void board_init(void) { GPIOD->DEN &= ~((1u << 4) | (1u << 5)); GPIOD->AMSEL |= ((1u << 4) | (1u << 5)); - uint8_t leds = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); - uint8_t dirmsk = (1 << LED_PIN_RED) | (1 << LED_PIN_BLUE) | (1 << LED_PIN_GREEN); +#else // TM4C129 + /* Reset USB */ + SYSCTL->SRUSB = 1; - /* Configure GPIO for board LED */ - initialize_board_led(LED_PORT, leds, dirmsk); + for (volatile uint8_t i = 0; i < 20; i++) {} + + SYSCTL->SRUSB = 0; - /* Configure GPIO for board switch */ - GPIOF->DIR &= ~(1 << BOARD_BTN); - GPIOF->PUR |= (1 << BOARD_BTN); - GPIOF->DEN |= (1 << BOARD_BTN); + /* Open the USB clock gate */ + SYSCTL->RCGCUSB = 1; + + /* Let the clock stabilize */ + while(!(SYSCTL->PRUSB & 1)) {} + + /* USB IO Initialization */ + SYSCTL->RCGCGPIO |= (1u << 10); + + /* Let the clock stabilize */ + while (!(SYSCTL->PRGPIO & (1u << 10))) {} + + /* USB IOs to Analog Mode */ + GPIOL->AFSEL &= ~((1u << 6) | (1u << 7)); + GPIOL->DEN &= ~((1u << 6) | (1u << 7)); + GPIOL->AMSEL |= ((1u << 6) | (1u << 7)); + + /* USB Clock Configuration */ + USB0->CC = 0x207; +#endif + + uint8_t leds = 1 << BOARD_LED_PIN; + uint8_t dirmsk = 1 << BOARD_LED_PIN; + + /* Configure GPIO for board button */ + board_button_init(BOARD_BTN_PORT, BOARD_BTN_Msk); + + /* Configure GPIO for board LED */ + board_led_init(LED_PORT, leds, dirmsk); /* Initialize board UART */ board_uart_init(); @@ -125,7 +171,7 @@ void board_init(void) { } void board_led_write(bool state) { - WriteGPIOPin(LED_PORT, (1 << LED_PIN_BLUE), state); + WriteGPIOPin(LED_PORT, (1 << BOARD_LED_PIN), state); } uint32_t board_button_read(void) { diff --git a/hw/bsp/tm4c/family.cmake b/hw/bsp/tm4c/family.cmake index 12f0448a3..9cef96b9d 100644 --- a/hw/bsp/tm4c/family.cmake +++ b/hw/bsp/tm4c/family.cmake @@ -5,14 +5,14 @@ include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) set(MCU_VARIANT tm4c${MCU_SUB_VARIANT}) set(MCU_VARIANT_UPPER TM4C${MCU_SUB_VARIANT}) -set(SDK_DIR ${TOP}/hw/mcu/ti/${MCU_VARIANT}xx) +set(SDK_DIR ${TOP}/hw/mcu/ti/tm4c) set(CMSIS_DIR ${TOP}/lib/CMSIS_5) # toolchain set up set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) -set(FAMILY_MCUS TM4C123 CACHE INTERNAL "") +set(FAMILY_MCUS TM4C CACHE INTERNAL "") #------------------------------------ # Startup & Linker script @@ -20,7 +20,7 @@ set(FAMILY_MCUS TM4C123 CACHE INTERNAL "") set(LD_FILE_Clang ${LD_FILE_GNU}) set(STARTUP_FILE_GNU ${SDK_DIR}/Source/GCC/${MCU_VARIANT}_startup.c) set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - +set(STARTUP_FILE_IAR ${SDK_DIR}/Source/IAR/${MCU_VARIANT}_startup.c) #------------------------------------ # Board Target #------------------------------------ @@ -29,7 +29,7 @@ function(family_add_board BOARD_TARGET) ${SDK_DIR}/Source/system_${MCU_VARIANT_UPPER}.c ) target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_DIR}/Include/${MCU_VARIANT_UPPER} + ${SDK_DIR}/Include ${CMSIS_DIR}/CMSIS/Core/Include ) @@ -41,7 +41,7 @@ endfunction() #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_TM4C123) + family_add_tinyusb(${TARGET} OPT_MCU_TM4C${MCU_SUB_VARIANT}) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c @@ -72,12 +72,10 @@ function(family_configure_example TARGET RTOS) if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") endif () - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) # Flashing family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) family_flash_openocd(${TARGET}) family_flash_uniflash(${TARGET}) endfunction() diff --git a/hw/bsp/tm4c/family.mk b/hw/bsp/tm4c/family.mk index 76ae785b2..bc966d98e 100644 --- a/hw/bsp/tm4c/family.mk +++ b/hw/bsp/tm4c/family.mk @@ -4,11 +4,11 @@ CPU_CORE ?= cortex-m4 MCU_VARIANT = tm4c${MCU_SUB_VARIANT} MCU_VARIANT_UPPER = TM4C${MCU_SUB_VARIANT} -SDK_DIR = hw/mcu/ti/${MCU_VARIANT}xx +SDK_DIR = hw/mcu/ti/tm4c CFLAGS += \ -flto \ - -DCFG_TUSB_MCU=OPT_MCU_TM4C123 \ + -DCFG_TUSB_MCU=OPT_MCU_TM4C${MCU_SUB_VARIANT} \ -uvectors \ # mcu driver cause following warnings @@ -18,7 +18,7 @@ LDFLAGS_GCC += --specs=nosys.specs --specs=nano.specs INC += \ $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(SDK_DIR)/Include/${MCU_VARIANT_UPPER} \ + $(TOP)/$(SDK_DIR)/Include \ $(TOP)/$(BOARD_PATH) SRC_C += \ diff --git a/src/portable/mentor/musb/musb_ti.h b/src/portable/mentor/musb/musb_ti.h index d17e836ee..68e89d77d 100644 --- a/src/portable/mentor/musb/musb_ti.h +++ b/src/portable/mentor/musb/musb_ti.h @@ -35,7 +35,10 @@ #include "TM4C123.h" #define FIFO0_WORD FIFO0 #define FIFO1_WORD FIFO1 -//#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 +#elif CFG_TUSB_MCU == OPT_MCU_TM4C129 + #include "TM4C129.h" + #define FIFO0_WORD FIFOA + #define FIFO1_WORD FIFOB #elif CFG_TUSB_MCU == OPT_MCU_MSP432E4 #include "msp.h" #else diff --git a/src/portable/mentor/musb/musb_type.h b/src/portable/mentor/musb/musb_type.h index 4e448c0ed..b2f6492fa 100644 --- a/src/portable/mentor/musb/musb_type.h +++ b/src/portable/mentor/musb/musb_type.h @@ -147,7 +147,7 @@ typedef struct TU_ATTR_PACKED { TU_VERIFY_STATIC(sizeof(musb_ep_csr_t) == 16, "size is not correct"); -typedef struct TU_ATTR_PACKED { +typedef struct { //------------- Common -------------// __IO uint8_t faddr; // 0x00: FADDR union { -- cgit v1.3.1 From 7a4e3d0821fb7913fbcca55018b41e66a6339df6 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Wed, 14 Jan 2026 00:19:49 +0100 Subject: bsp: add STM32H747-DISCO Signed-off-by: HiFiPhile Signed-off-by: Zixun LI --- docs/reference/boards.rst | 1 + hw/bsp/stm32h7/boards/stm32h747disco/board.cmake | 23 +++ hw/bsp/stm32h7/boards/stm32h747disco/board.h | 169 +++++++++++++++++++++ hw/bsp/stm32h7/boards/stm32h747disco/board.mk | 15 ++ hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld | 184 +++++++++++++++++++++++ 5 files changed, 392 insertions(+) create mode 100644 hw/bsp/stm32h7/boards/stm32h747disco/board.cmake create mode 100644 hw/bsp/stm32h7/boards/stm32h747disco/board.h create mode 100644 hw/bsp/stm32h7/boards/stm32h747disco/board.mk create mode 100644 hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 09c90e08f..f6dd3cd91 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -292,6 +292,7 @@ stm32h723nucleo STM32 H723 Nucleo stm32h7 https://www.s stm32h743eval STM32 H743 Eval stm32h7 https://www.st.com/en/evaluation-tools/stm32h743i-eval.html stm32h743nucleo STM32 H743 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h743zi.html stm32h745disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html +stm32h747disco STM32 H747 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h747i-disco.html stm32h750_weact STM32 H750 WeAct stm32h7 https://www.adafruit.com/product/5032 stm32h750bdk STM32 H750b Discovery Kit stm32h7 https://www.st.com/en/evaluation-tools/stm32h750b-dk.html waveshare_openh743i Waveshare Open H743i stm32h7 https://www.waveshare.com/openh743i-c-standard.htm diff --git a/hw/bsp/stm32h7/boards/stm32h747disco/board.cmake b/hw/bsp/stm32h7/boards/stm32h747disco/board.cmake new file mode 100644 index 000000000..8bce542a5 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h747disco/board.cmake @@ -0,0 +1,23 @@ +set(MCU_VARIANT stm32h747xx) +set(JLINK_DEVICE stm32h747xi_m7) + +set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/../../linker/${MCU_VARIANT}_flash_CM7.ld) +set(LD_FILE_IAR ${ST_CMSIS}/Source/Templates/iar/linker/${MCU_VARIANT}_flash_CM7.icf) + +set(RHPORT_SPEED OPT_MODE_FULL_SPEED OPT_MODE_HIGH_SPEED) + +# device default to PORT 1 High Speed +if (NOT DEFINED RHPORT_DEVICE) + set(RHPORT_DEVICE 1) +endif() +if (NOT DEFINED RHPORT_HOST) + set(RHPORT_HOST 1) +endif() + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32H747xx + HSE_VALUE=25000000 + CORE_CM7 + ) +endfunction() diff --git a/hw/bsp/stm32h7/boards/stm32h747disco/board.h b/hw/bsp/stm32h7/boards/stm32h747disco/board.h new file mode 100644 index 000000000..71e8b1427 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h747disco/board.h @@ -0,0 +1,169 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2021, 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. + */ + +/* metadata: + name: STM32 H745 Discovery + url: https://www.st.com/en/evaluation-tools/stm32h745i-disco.html +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +// UART +#define UART_DEV USART3 +#define UART_CLK_EN __HAL_RCC_USART3_CLK_ENABLE + +// VBUS Sense detection +#define OTG_FS_VBUS_SENSE 1 +#define OTG_HS_VBUS_SENSE 0 + +// USB HS External PHY Pin: CLK, STP, DIR, NXT, D0-D7 +#define ULPI_PINS \ + {GPIOA, GPIO_PIN_3 }, {GPIOA, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_0 }, {GPIOB, GPIO_PIN_1 }, \ + {GPIOB, GPIO_PIN_5 }, {GPIOB, GPIO_PIN_10}, {GPIOB, GPIO_PIN_11}, {GPIOB, GPIO_PIN_12}, \ + {GPIOB, GPIO_PIN_13}, {GPIOC, GPIO_PIN_0 }, {GPIOH, GPIO_PIN_4 }, {GPIOI, GPIO_PIN_11} + +#define PINID_LED 0 +#define PINID_BUTTON 1 +#define PINID_UART_TX 2 +#define PINID_UART_RX 3 + +static board_pindef_t board_pindef[] = { + { // LED + .port = GPIOI, + .pin_init = { .Pin = GPIO_PIN_12, .Mode = GPIO_MODE_OUTPUT_PP, .Pull = GPIO_PULLDOWN, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, + .active_state = 0 + }, + { // Button + .port = GPIOC, + .pin_init = { .Pin = GPIO_PIN_13, .Mode = GPIO_MODE_INPUT, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = 0 }, + .active_state = 1 + }, + { // UART TX + .port = GPIOA, + .pin_init = { .Pin = GPIO_PIN_9, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, + .active_state = 0 + }, + { // UART RX + .port = GPIOA, + .pin_init = { .Pin = GPIO_PIN_10, .Mode = GPIO_MODE_AF_PP, .Pull = GPIO_PULLUP, .Speed = GPIO_SPEED_HIGH, .Alternate = GPIO_AF7_USART3 }, + .active_state = 0 + } +}; + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ +static inline void SystemClock_Config(void) +{ + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInitStruct = { 0 }; + + /*!< Supply configuration update enable */ + /* For STM32H750XB, use "HAL_PWREx_ConfigSupply(PWR_LDO_SUPPLY);" */ + HAL_PWREx_ConfigSupply(PWR_DIRECT_SMPS_SUPPLY); + + /* 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); + + while ((PWR->D3CR & (PWR_D3CR_VOSRDY)) != PWR_D3CR_VOSRDY) {} + + /* Enable HSE Oscillator and activate PLL with HSE as source */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSE; + RCC_OscInitStruct.HSEState = RCC_HSE_BYPASS; + RCC_OscInitStruct.HSIState = RCC_HSI_OFF; + RCC_OscInitStruct.CSIState = RCC_CSI_OFF; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSE; + + /* PLL1 for System Clock */ + RCC_OscInitStruct.PLL.PLLM = 5; + RCC_OscInitStruct.PLL.PLLN = 160; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLR = 2; + RCC_OscInitStruct.PLL.PLLQ = 4; + + RCC_OscInitStruct.PLL.PLLVCOSEL = RCC_PLL1VCOMEDIUM; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLL1VCIRANGE_2; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + /* PLL3 for USB Clock */ + PeriphClkInitStruct.PLL3.PLL3M = 25; + PeriphClkInitStruct.PLL3.PLL3N = 336; + PeriphClkInitStruct.PLL3.PLL3FRACN = 0; + PeriphClkInitStruct.PLL3.PLL3P = 2; + PeriphClkInitStruct.PLL3.PLL3R = 2; + PeriphClkInitStruct.PLL3.PLL3Q = 7; + + PeriphClkInitStruct.PeriphClockSelection = RCC_PERIPHCLK_USB; + PeriphClkInitStruct.UsbClockSelection = RCC_USBCLKSOURCE_PLL3; + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInitStruct); + + /* Select PLL as system clock source and configure bus clocks dividers */ + RCC_ClkInitStruct.ClockType = (RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_D1PCLK1 | RCC_CLOCKTYPE_PCLK1 | \ + RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_D3PCLK1); + + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.SYSCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.AHBCLKDivider = RCC_HCLK_DIV2; + RCC_ClkInitStruct.APB1CLKDivider = RCC_APB1_DIV2; + RCC_ClkInitStruct.APB2CLKDivider = RCC_APB2_DIV2; + RCC_ClkInitStruct.APB3CLKDivider = RCC_APB3_DIV1; + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); + + /*activate CSI clock mondatory for I/O Compensation Cell*/ + __HAL_RCC_CSI_ENABLE() ; + + /* Enable SYSCFG clock mondatory for I/O Compensation Cell */ + __HAL_RCC_SYSCFG_CLK_ENABLE() ; + + /* Enables the I/O Compensation Cell */ + HAL_EnableCompensationCell(); +} + +static inline void board_init2(void) { + // For this board does nothing +} + +void board_vbus_set(uint8_t rhport, bool state) { + (void) rhport; + (void) state; +} + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/stm32h7/boards/stm32h747disco/board.mk b/hw/bsp/stm32h7/boards/stm32h747disco/board.mk new file mode 100644 index 000000000..4b17246e2 --- /dev/null +++ b/hw/bsp/stm32h7/boards/stm32h747disco/board.mk @@ -0,0 +1,15 @@ +# STM32H747I-DISCO uses OTG_FS +# FIXME: Reset enumerates, un/replug USB plug does not enumerate +MCU_VARIANT = stm32h747xx +CFLAGS += -DSTM32H747xx -DCORE_CM7 -DHSE_VALUE=25000000 + +# Default is FulSpeed port +PORT ?= 0 + +LD_FILE_GCC = $(FAMILY_PATH)/linker/${MCU_VARIANT}_flash_CM7.ld +LD_FILE_IAR = $(ST_CMSIS)/Source/Templates/iar/linker/stm32h747xx_flash_CM7.icf + +# For flash-jlink target +JLINK_DEVICE = stm32h747xi_m7 +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld b/hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld new file mode 100644 index 000000000..5b7fe4528 --- /dev/null +++ b/hw/bsp/stm32h7/linker/stm32h747xx_flash_CM7.ld @@ -0,0 +1,184 @@ +/* +****************************************************************************** +** + +** File : LinkerScript.ld +** +** +** Abstract : Linker script for STM32H7 series +** 1024Kbytes FLASH and 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) 2019 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 = 0x20020000; /* end of RAM */ +/* Generate a link error if heap and stack don't fit into RAM */ +_Min_Heap_Size = 0x200; /* required amount of heap */ +_Min_Stack_Size = 0x400; /* required amount of stack */ + +/* Specify the memory areas */ +MEMORY +{ +FLASH (rx) : ORIGIN = 0x08000000, LENGTH = 1024K +RAM (xrw) : ORIGIN = 0x20000000, LENGTH = 128K +ITCMRAM (xrw) : ORIGIN = 0x00000000, LENGTH = 64K +} + +/* Define output sections */ +SECTIONS +{ + /* The startup code goes first into FLASH */ + .isr_vector : + { + . = ALIGN(4); + KEEP(*(.isr_vector)) /* Startup code */ + . = ALIGN(4); + } >FLASH + + /* The program code and other data goes into FLASH */ + .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 goes into FLASH */ + .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 goes into RAM, load LMA copy after code */ + .data : + { + . = ALIGN(4); + _sdata = .; /* create a global symbol at data start */ + *(.data) /* .data sections */ + *(.data*) /* .data* sections */ + + . = ALIGN(4); + _edata = .; /* define a global symbol at data end */ + } >RAM AT> FLASH + + + /* Uninitialized data section */ + . = 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 left */ + ._user_heap_stack : + { + . = ALIGN(8); + PROVIDE ( end = . ); + PROVIDE ( _end = . ); + . = . + _Min_Heap_Size; + . = . + _Min_Stack_Size; + . = ALIGN(8); + } >RAM + + + + /* Remove information from the standard libraries */ + /DISCARD/ : + { + libc.a ( * ) + libm.a ( * ) + libgcc.a ( * ) + } + + .ARM.attributes 0 : { *(.ARM.attributes) } +} -- cgit v1.3.1 From 320d0f88bf7f3c8fb9e2e8c86e55051a0d0980aa Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 7 Feb 2026 21:53:51 +0700 Subject: remove sdk setup instruction for rp2040 and espressif --- docs/getting_started.rst | 130 ++--------------------------------------------- 1 file changed, 3 insertions(+), 127 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index d9d81f23f..b7a962d50 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -34,10 +34,10 @@ Get the Code $ python tools/get_deps.py -b stm32h743eval # or python tools/get_deps.py stm32h7 .. note:: - Some MCU families require additional SDKs: + Some MCU families require additional SDKs, please follow their instructions to install and set it up - * **rp2040**: Requires `pico-sdk `_ - see `Building for RP2040`_ below - * **Espressif (esp32)**: Requires `esp-idf `_ - see `Building for ESP32`_ below + * **rp2040**: Requires `pico-sdk `_ + * **Espressif (esp32)**: Requires `esp-idf `_ Simple Device Example --------------------- @@ -152,130 +152,6 @@ A MCU can support multiple operational speed. By default, the example build syst $ make BOARD=stm32h743eval RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all -Building for RP2040 -------------------- - -RP2040 boards (like Raspberry Pi Pico) require the Pico SDK to be installed and configured before building. - -Install Pico SDK -^^^^^^^^^^^^^^^^ - -**Linux/macOS:** - -.. code-block:: bash - - $ cd ~ - $ git clone https://github.com/raspberrypi/pico-sdk.git - $ cd pico-sdk - $ git submodule update --init - -**Windows:** - -.. code-block:: bat - - C:\> cd %USERPROFILE% - C:\Users\YourName> git clone https://github.com/raspberrypi/pico-sdk.git - C:\Users\YourName> cd pico-sdk - C:\Users\YourName\pico-sdk> git submodule update --init - -Set PICO_SDK_PATH -^^^^^^^^^^^^^^^^^ - -Before running cmake, export the SDK path: - -**Linux/macOS:** - -.. code-block:: bash - - $ export PICO_SDK_PATH=~/pico-sdk - -**Windows (Command Prompt):** - -.. code-block:: bat - - C:\> set PICO_SDK_PATH=%USERPROFILE%\pico-sdk - -**Windows (PowerShell):** - -.. code-block:: powershell - - PS C:\> $env:PICO_SDK_PATH = "$env:USERPROFILE\pico-sdk" - -Build Example for RP2040 -^^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ cmake -DBOARD=raspberry_pi_pico -B build - $ cmake --build build - -.. tip:: - Add the PICO_SDK_PATH export to your shell's profile file (e.g., ``~/.bashrc``, ``~/.zshrc``) to make it permanent. - - -Building for ESP32 ------------------- - -ESP32 boards require the ESP-IDF (Espressif IoT Development Framework) to be installed and sourced before building. - -Install ESP-IDF -^^^^^^^^^^^^^^^ - -**Linux/macOS:** - -.. code-block:: bash - - $ cd ~ - $ git clone --recursive https://github.com/espressif/esp-idf.git - $ cd esp-idf - $ ./install.sh all - -**Windows:** - -.. code-block:: bat - - C:\> cd %USERPROFILE% - C:\Users\YourName> git clone --recursive https://github.com/espressif/esp-idf.git - C:\Users\YourName> cd esp-idf - C:\Users\YourName\esp-idf> install.bat all - -Source ESP-IDF Environment -^^^^^^^^^^^^^^^^^^^^^^^^^^^ - -Before running cmake, source the ESP-IDF export script: - -**Linux/macOS:** - -.. code-block:: bash - - $ source ~/esp-idf/export.sh - -**Windows (Command Prompt):** - -.. code-block:: bat - - C:\> %USERPROFILE%\esp-idf\export.bat - -**Windows (PowerShell):** - -.. code-block:: powershell - - PS C:\> . $env:USERPROFILE\esp-idf\export.ps1 - -Build Example for ESP32 -^^^^^^^^^^^^^^^^^^^^^^^^ - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ cmake -DBOARD=espressif_s3_devkitc -B build - $ cmake --build build - -.. tip:: - You need to source the ESP-IDF export script in each new terminal session. Consider creating an alias in your shell's profile file for convenience. - - IAR Embedded Workbench ---------------------- -- cgit v1.3.1 From e7c71fefa7576e971c6bb05c1a5bab6075bd044f Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 10 Feb 2026 11:25:46 +0700 Subject: update getting_started.rst and get_deps.py for clarity and improved dependency handling --- docs/getting_started.rst | 2 +- tools/get_deps.py | 24 +++++++----------------- 2 files changed, 8 insertions(+), 18 deletions(-) (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index b7a962d50..8442305d4 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -37,7 +37,7 @@ Get the Code Some MCU families require additional SDKs, please follow their instructions to install and set it up * **rp2040**: Requires `pico-sdk `_ - * **Espressif (esp32)**: Requires `esp-idf `_ + * **Espressif (esp32)**: Requires `esp-idf `_. Only a few examples support the ESP-IDF build system. Look for ones with `src/CMakeLists.txt` that contain `idf_component_register()`, such as `cdc_msc_freertos`. Simple Device Example --------------------- diff --git a/tools/get_deps.py b/tools/get_deps.py index deacbb23b..51c2b1012 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -327,18 +327,16 @@ def main(): parser.add_argument('-b', '--board', action='append', default=[], help='Boards to fetch') parser.add_argument('-D', '--define', action='append', default=[], help='Have no effect') parser.add_argument('-f1', '--build-flags-on', action='append', default=[], help='Have no effect') - parser.add_argument('--print', action='store_true', help='Print commit hash only') args = parser.parse_args() families = args.families boards = args.board - print_only = args.print status = 0 - deps = list(deps_mandatory.keys()) + deps = [] if 'all' in families: - deps += deps_optional.keys() + deps.extend(deps_optional.keys()) else: families = list(families) if boards is not None: @@ -346,24 +344,16 @@ def main(): f = find_family(b) if f is not None: families.append(f) - for f in families: for d in deps_optional: if d not in deps and f in deps_optional[d][2].split(): deps.append(d) + if len(deps) == 0: + print('WARN: no additional dependencies found for given boards or families') - if print_only: - pvalue = {} - # print only without arguments, always add CMSIS_5 - if len(families) == 0 and len(boards) == 0: - deps.append('lib/CMSIS_5') - for d in deps: - commit = deps_all[d][1] - pvalue[d] = commit - print(pvalue) - else: - with Pool() as pool: - status = sum(pool.map(get_a_dep, deps)) + deps.extend(deps_mandatory.keys()) + with Pool() as pool: + status = sum(pool.map(get_a_dep, deps)) return status -- cgit v1.3.1 From 5794e50c377b615ba7d29484cf8575433affe0fe Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Mar 2026 11:46:53 +0700 Subject: rename and migrate kinetis_k32l to new mcux-devices --- .github/workflows/ci_set_matrix.py | 2 +- docs/reference/boards.rst | 6 +- docs/reference/dependencies.rst | 4 +- .../kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h | 170 ------- .../kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.h | 96 ---- hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk | 18 - .../boards/frdm_k32l2a4s/clock_config.c | 491 --------------------- .../boards/frdm_k32l2a4s/clock_config.h | 164 ------- .../kinetis_k32l2/boards/frdm_k32l2b/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h | 82 ---- hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk | 18 - .../boards/frdm_k32l2b/clock_config.c | 220 --------- .../boards/frdm_k32l2b/clock_config.h | 110 ----- hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake | 15 - hw/bsp/kinetis_k32l2/boards/kuiic/board.h | 69 --- hw/bsp/kinetis_k32l2/boards/kuiic/board.mk | 18 - hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c | 39 -- hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h | 14 - hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld | 216 --------- hw/bsp/kinetis_k32l2/family.c | 175 -------- hw/bsp/kinetis_k32l2/family.cmake | 97 ---- hw/bsp/kinetis_k32l2/family.mk | 35 -- tools/get_deps.py | 11 +- 24 files changed, 13 insertions(+), 2087 deletions(-) delete mode 100644 hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/board.mk delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h delete mode 100644 hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld delete mode 100644 hw/bsp/kinetis_k32l2/family.c delete mode 100644 hw/bsp/kinetis_k32l2/family.cmake delete mode 100644 hw/bsp/kinetis_k32l2/family.mk (limited to 'docs') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index cd7dfa76b..b5c8d9544 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -34,7 +34,7 @@ family_list = { "hpmicro": ["riscv-gcc"], "imxrt": ["arm-gcc", "arm-clang"], "kinetis_k": ["arm-gcc", "arm-clang"], - "kinetis_k32l2": ["arm-gcc", "arm-clang"], + "kinetis_k32l": ["arm-gcc", "arm-clang"], "kinetis_kl": ["arm-gcc", "arm-clang"], "lpc11": ["arm-gcc", "arm-clang"], "lpc13": ["arm-gcc", "arm-clang"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index f6dd3cd91..eaef078d3 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -166,9 +166,9 @@ teensy_40 Teensy 4.0 imxrt ht teensy_41 Teensy 4.1 imxrt https://www.pjrc.com/store/teensy41.html frdm_k64f Freedom K64F kinetis_k https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F teensy_35 Teensy 3.5 kinetis_k https://www.pjrc.com/store/teensy35.html -frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l2 https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S -frdm_k32l2b Freedom K32L2B3 kinetis_k32l2 https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 -kuiic Kuiic kinetis_k32l2 https://github.com/nxf58843/kuiic +frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S +frdm_k32l2b Freedom K32L2B3 kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 +kuiic Kuiic kinetis_k32l https://github.com/nxf58843/kuiic frdm_kl25z fomu kinetis_kl https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z lpcxpresso11u37 LPCXpresso11U37 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13074 lpcxpresso11u68 LPCXpresso11U68 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index ce5f265d5..9b61e10a8 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -26,7 +26,7 @@ hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 -hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx imxrt +hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx imxrt hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git edcc97d684b6f716728a60d7a6fea049d9870bd6 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx @@ -81,7 +81,7 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 ra stm32n6 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all diff --git a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h deleted file mode 100644 index 0225abe8d..000000000 --- a/hw/bsp/kinetis_k32l2/FreeRTOSConfig/FreeRTOSConfig.h +++ /dev/null @@ -1,170 +0,0 @@ -/* - * FreeRTOS Kernel V10.0.0 - * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. - * - * 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. If you wish to use our Amazon - * FreeRTOS name, please do so in a fair use way that does not cause confusion. - * - * 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. - * - * http://www.FreeRTOS.org - * http://aws.amazon.com/freertos - * - * 1 tab == 4 spaces! - */ - - -#ifndef FREERTOS_CONFIG_H -#define FREERTOS_CONFIG_H - -/*----------------------------------------------------------- - * Application specific definitions. - * - * These definitions should be adjusted for your particular hardware and - * application requirements. - * - * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE - * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. - * - * See http://www.freertos.org/a00110.html. - *----------------------------------------------------------*/ - -// skip if included from IAR assembler -#ifndef __IASMARM__ - #include "fsl_device_registers.h" -#endif - -/* Cortex M23/M33 port configuration. */ -#define configENABLE_MPU 0 -#if defined(__ARM_FP) && __ARM_FP >= 4 - #define configENABLE_FPU 1 -#else - #define configENABLE_FPU 0 -#endif -#define configENABLE_TRUSTZONE 0 -#define configMINIMAL_SECURE_STACK_SIZE (1024) - -#define configUSE_PREEMPTION 1 -#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 -#define configCPU_CLOCK_HZ SystemCoreClock -#define configTICK_RATE_HZ ( 1000 ) -#define configMAX_PRIORITIES ( 5 ) -#define configMINIMAL_STACK_SIZE ( 128 ) -#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) -#define configMAX_TASK_NAME_LEN 16 -#define configUSE_16_BIT_TICKS 0 -#define configIDLE_SHOULD_YIELD 1 -#define configUSE_MUTEXES 1 -#define configUSE_RECURSIVE_MUTEXES 1 -#define configUSE_COUNTING_SEMAPHORES 1 -#define configQUEUE_REGISTRY_SIZE 2 -#define configUSE_QUEUE_SETS 0 -#define configUSE_TIME_SLICING 0 -#define configUSE_NEWLIB_REENTRANT 0 -#define configENABLE_BACKWARD_COMPATIBILITY 1 -#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 - -#define configSUPPORT_STATIC_ALLOCATION 1 -#define configSUPPORT_DYNAMIC_ALLOCATION 0 - -/* Hook function related definitions. */ -#define configUSE_IDLE_HOOK 0 -#define configUSE_TICK_HOOK 0 -#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning -#define configCHECK_FOR_STACK_OVERFLOW 2 -#define configCHECK_HANDLER_INSTALLATION 0 - -/* Run time and task stats gathering related definitions. */ -#define configGENERATE_RUN_TIME_STATS 0 -#define configRECORD_STACK_HIGH_ADDRESS 1 -#define configUSE_TRACE_FACILITY 1 // legacy trace -#define configUSE_STATS_FORMATTING_FUNCTIONS 0 - -/* Co-routine definitions. */ -#define configUSE_CO_ROUTINES 0 -#define configMAX_CO_ROUTINE_PRIORITIES 2 - -/* Software timer related definitions. */ -#define configUSE_TIMERS 1 -#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) -#define configTIMER_QUEUE_LENGTH 32 -#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE - -/* Optional functions - most linkers will remove unused functions anyway. */ -#define INCLUDE_vTaskPrioritySet 0 -#define INCLUDE_uxTaskPriorityGet 0 -#define INCLUDE_vTaskDelete 0 -#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY -#define INCLUDE_xResumeFromISR 0 -#define INCLUDE_vTaskDelayUntil 1 -#define INCLUDE_vTaskDelay 1 -#define INCLUDE_xTaskGetSchedulerState 0 -#define INCLUDE_xTaskGetCurrentTaskHandle 1 -#define INCLUDE_uxTaskGetStackHighWaterMark 0 -#define INCLUDE_xTaskGetIdleTaskHandle 0 -#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 -#define INCLUDE_pcTaskGetTaskName 0 -#define INCLUDE_eTaskGetState 0 -#define INCLUDE_xEventGroupSetBitFromISR 0 -#define INCLUDE_xTimerPendFunctionCall 0 - -/* Define to trap errors during development. */ -// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 -#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) - #define configASSERT(_exp) \ - do {\ - if ( !(_exp) ) { \ - volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ - if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ - taskDISABLE_INTERRUPTS(); \ - __asm("BKPT #0\n"); \ - }\ - }\ - } while(0) -#else - #define configASSERT( x ) -#endif - -/* FreeRTOS hooks to NVIC vectors */ -#define xPortPendSVHandler PendSV_Handler -#define xPortSysTickHandler SysTick_Handler -#define vPortSVCHandler SVC_Handler - -//--------------------------------------------------------------------+ -// Interrupt nesting behavior configuration. -//--------------------------------------------------------------------+ - -// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header -#define configPRIO_BITS 2 - -/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ -#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<CLKOUTCNFG = SCG_CLKOUTCNFG_CLKOUTSEL(setting); -} - -/*FUNCTION********************************************************************** - * - * Function Name : CLOCK_CONFIG_FircSafeConfig - * Description : This function is used to safely configure FIRC clock. - * In default out of reset, the CPU is clocked from FIRC(IRC48M). - * Before setting FIRC, change to use SIRC as system clock, - * then configure FIRC. After FIRC is set, change back to use FIRC - * in case SIRC need to be configured. - * Param fircConfig : FIRC configuration. - * - *END**************************************************************************/ -static void CLOCK_CONFIG_FircSafeConfig(const scg_firc_config_t *fircConfig) -{ - scg_sys_clk_config_t curConfig; - const scg_sirc_config_t scgSircConfig = {.enableMode = kSCG_SircEnable, - .div1 = kSCG_AsyncClkDisable, - .div3 = kSCG_AsyncClkDivBy2, - .range = kSCG_SircRangeHigh}; - scg_sys_clk_config_t sysClkSafeConfigSource = { - .divSlow = kSCG_SysClkDivBy4, /* Slow clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core clock divider */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* System clock source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; - /* Init Sirc. */ - CLOCK_InitSirc(&scgSircConfig); - /* Change to use SIRC as system clock source to prepare to change FIRCCFG register. */ - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); - - /* Init Firc. */ - CLOCK_InitFirc(fircConfig); - /* Change back to use FIRC as system clock source in order to configure SIRC if needed. */ - sysClkSafeConfigSource.src = kSCG_SysClkSrcFirc; - CLOCK_SetRunModeSysClkConfig(&sysClkSafeConfigSource); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != sysClkSafeConfigSource.src); -} - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: SIRCDIV3_CLK.outFreq, value: 4 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '2', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN = - { - .divSlow = kSCG_SysClkDivBy2, /* Slow Clock Divider: divided by 2 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcFirc, /* Fast IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDivBy2, /* Slow IRC Clock Divider 3: divided by 2 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockRUN = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockRUN configuration - ******************************************************************************/ -void BOARD_BootClockRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockRUN); - /* Set SCG to FIRC mode. */ - CLOCK_SetRunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKRUN_CORE_CLOCK; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockHSRUN -outputs: -- {id: CLKOUT.outFreq, value: 8 MHz} -- {id: Core_clock.outFreq, value: 96 MHz, locked: true, accuracy: '0.001'} -- {id: FIRCDIV1_CLK.outFreq, value: 48 MHz} -- {id: FIRCDIV3_CLK.outFreq, value: 48 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: OSC32KCLK.outFreq, value: 32.768 kHz} -- {id: PLLDIV1_CLK.outFreq, value: 96 MHz} -- {id: PLLDIV3_CLK.outFreq, value: 96 MHz} -- {id: SIRCDIV1_CLK.outFreq, value: 8 MHz} -- {id: SIRCDIV3_CLK.outFreq, value: 8 MHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: SOSCDIV1_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCDIV3_CLK.outFreq, value: 32.768 kHz} -- {id: SOSCER_CLK.outFreq, value: 32.768 kHz} -- {id: SOSC_CLK.outFreq, value: 32.768 kHz} -- {id: Slow_clock.outFreq, value: 24 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 96 MHz} -settings: -- {id: SCGMode, value: SPLL} -- {id: powerMode, value: HSRUN} -- {id: CLKOUTConfig, value: 'yes'} -- {id: SCG.DIVSLOW.scale, value: '4'} -- {id: SCG.FIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.FIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.PREDIV.scale, value: '4'} -- {id: SCG.SCSSEL.sel, value: SCG.SPLL_DIV2_CLK} -- {id: SCG.SIRCDIV1.scale, value: '1', locked: true} -- {id: SCG.SIRCDIV3.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV1.scale, value: '1', locked: true} -- {id: SCG.SOSCDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV1.scale, value: '1', locked: true} -- {id: SCG.SPLLDIV3.scale, value: '1', locked: true} -- {id: SCG.SPLLSRCSEL.sel, value: SCG.FIRC} -- {id: SCG_SOSCCFG_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: SCG_SOSCCSR_SOSCEN_CFG, value: Enabled} -- {id: SCG_SOSCCSR_SOSCERCLKEN_CFG, value: Enabled} -- {id: SCG_SPLLCSR_SPLLEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN = - { - .divSlow = kSCG_SysClkDivBy4, /* Slow Clock Divider: divided by 4 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSysPll, /* System PLL is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN = - { - .freq = 32768U, /* System Oscillator frequency: 32768Hz */ - .enableMode = kSCG_SysOscEnable | kSCG_SysOscEnableErClk,/* Enable System OSC clock, Enable OSCERCLK */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System OSC Clock Divider 3: divided by 1 */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeOscLowPower, /* Oscillator low power */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Slow IRC Clock Divider 3: divided by 1 */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_FircEnable, /* Enable FIRC clock */ - .div1 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* Fast IRC Clock Divider 3: divided by 1 */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockHSRUN = - { - .enableMode = kSCG_SysPllEnable, /* Enable SPLL clock */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 1: divided by 1 */ - .div3 = kSCG_AsyncClkDivBy1, /* System PLL Clock Divider 3: divided by 1 */ - .src = kSCG_SysPllSrcFirc, /* System PLL clock source is Fast IRC */ - .prediv = 3, /* Divided by 4 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -void BOARD_BootClockHSRUN(void) -{ - scg_sys_clk_config_t curConfig; - - /* Init SOSC according to board configuration. */ - CLOCK_InitSysOsc(&g_scgSysOscConfig_BOARD_BootClockHSRUN); - /* Set the XTAL0 frequency based on board settings. */ - CLOCK_SetXtal0Freq(g_scgSysOscConfig_BOARD_BootClockHSRUN.freq); - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockHSRUN); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockHSRUN); - /* Init SysPll. */ - CLOCK_InitSysPll(&g_scgSysPllConfig_BOARD_BootClockHSRUN); - /* Set HSRUN power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - SMC_SetPowerModeHsrun(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateHsrun) - { - } - - /* Set SCG to SPLL mode. */ - CLOCK_SetHsrunModeSysClkConfig(&g_sysClkConfig_BOARD_BootClockHSRUN); - /* Wait for clock source switch finished. */ - do - { - CLOCK_GetCurSysClkConfig(&curConfig); - } while (curConfig.src != g_sysClkConfig_BOARD_BootClockHSRUN.src); - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKHSRUN_CORE_CLOCK; - /* Set SCG CLKOUT selection. */ - CLOCK_CONFIG_SetScgOutSel(SCG_CLKOUTCNFG_SIRC); -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Core_clock.outFreq, value: 8 MHz, locked: true, accuracy: '0.001'} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: SIRC_CLK.outFreq, value: 8 MHz} -- {id: Slow_clock.outFreq, value: 1 MHz, locked: true, accuracy: '0.001'} -- {id: System_clock.outFreq, value: 8 MHz} -settings: -- {id: SCGMode, value: SIRC} -- {id: powerMode, value: VLPR} -- {id: SCG.DIVSLOW.scale, value: '8'} -- {id: SCG.SCSSEL.sel, value: SCG.SIRC} -- {id: SCG_FIRCCSR_FIRCLPEN_CFG, value: Enabled} -sources: -- {id: SCG.SOSC.outFreq, value: 32.768 kHz, enabled: true} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR = - { - .divSlow = kSCG_SysClkDivBy8, /* Slow Clock Divider: divided by 8 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved1 = 0, - .reserved2 = 0, - .reserved3 = 0, -#endif - .divCore = kSCG_SysClkDivBy1, /* Core Clock Divider: divided by 1 */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved4 = 0, -#endif - .src = kSCG_SysClkSrcSirc, /* Slow IRC is selected as System Clock Source */ -#if FSL_CLOCK_DRIVER_VERSION < MAKE_VERSION(2, 1, 1) - .reserved5 = 0, -#endif - }; -const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* System Oscillator frequency: 0Hz */ - .enableMode = SCG_SOSC_DISABLE, /* System OSC disabled */ - .monitorMode = kSCG_SysOscMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System OSC Clock Divider 3: Clock output is disabled */ - .capLoad = SCG_SYS_OSC_CAP_0P, /* Oscillator capacity load: 0pF */ - .workMode = kSCG_SysOscModeExt, /* Use external clock */ - }; -const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_SircEnable | kSCG_SircEnableInLowPower,/* Enable SIRC clock, Enable SIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Slow IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_SircRangeHigh, /* Slow IRC high range clock (8 MHz) */ - }; -const scg_firc_config_t g_scgFircConfig_BOARD_BootClockVLPR = - { - .enableMode = kSCG_FircEnable | kSCG_FircEnableInLowPower,/* Enable FIRC clock, Enable FIRC in low power mode */ - .div1 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* Fast IRC Clock Divider 3: Clock output is disabled */ - .range = kSCG_FircRange48M, /* Fast IRC is trimmed to 48MHz */ - .trimConfig = NULL, /* Fast IRC Trim disabled */ - }; -const scg_spll_config_t g_scgSysPllConfig_BOARD_BootClockVLPR = - { - .enableMode = SCG_SPLL_DISABLE, /* System PLL disabled */ - .monitorMode = kSCG_SysPllMonitorDisable, /* Monitor disabled */ - .div1 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 1: Clock output is disabled */ - .div3 = kSCG_AsyncClkDisable, /* System PLL Clock Divider 3: Clock output is disabled */ - .src = kSCG_SysPllSrcSysOsc, /* System PLL clock source is System OSC */ - .prediv = 0, /* Divided by 1 */ - .mult = 0, /* Multiply Factor is 16 */ - }; -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Init FIRC. */ - CLOCK_CONFIG_FircSafeConfig(&g_scgFircConfig_BOARD_BootClockVLPR); - /* Init SIRC. */ - CLOCK_InitSirc(&g_scgSircConfig_BOARD_BootClockVLPR); - /* Allow SMC all power modes. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); - /* Set VLPR power mode. */ - SMC_SetPowerModeVlpr(SMC); - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h deleted file mode 100644 index c01d5e03c..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2a4s/clock_config.h +++ /dev/null @@ -1,164 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define BOARD_XTAL0_CLK_HZ 32768U /*!< Board xtal0 frequency in Hz */ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief SCG set for BOARD_BootClockRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockRUN; -/*! @brief System OSC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockRUN; -/*! @brief SIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockRUN; -/*! @brief FIRC set for BOARD_BootClockRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockRUN; -/*! @brief Low Power FLL set for BOARD_BootClockRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockHSRUN ********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKHSRUN_CORE_CLOCK 96000000U /*!< Core clock frequency: 96000000Hz */ - -/*! @brief SCG set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockHSRUN; -/*! @brief System OSC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockHSRUN; -/*! @brief SIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockHSRUN; -/*! @brief FIRC set for BOARD_BootClockHSRUN configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockHSRUN; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockHSRUN; -/*! @brief Low Power FLL set for BOARD_BootClockHSRUN configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockHSRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockHSRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 8000000U /*!< Core clock frequency: 8000000Hz */ - -/*! @brief SCG set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sys_clk_config_t g_sysClkConfig_BOARD_BootClockVLPR; -/*! @brief System OSC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sosc_config_t g_scgSysOscConfig_BOARD_BootClockVLPR; -/*! @brief SIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_sirc_config_t g_scgSircConfig_BOARD_BootClockVLPR; -/*! @brief FIRC set for BOARD_BootClockVLPR configuration. - */ -extern const scg_firc_config_t g_scgFircConfigBOARD_BootClockVLPR; -extern const scg_spll_config_t g_scgSysPllConfigBOARD_BootClockVLPR; -/*! @brief Low Power FLL set for BOARD_BootClockVLPR configuration. - */ - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake deleted file mode 100644 index 2ec2acace..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.cmake +++ /dev/null @@ -1,15 +0,0 @@ -set(MCU_VARIANT K32L2B31A) - -set(JLINK_DEVICE K32L2B31xxxxA) -set(PYOCD_TARGET K32L2B) - -set(LD_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/K32L2B31xxxxA_flash.ld) - -function(update_board TARGET) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ) - target_compile_definitions(${TARGET} PUBLIC - CPU_K32L2B31VLH0A - ) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h deleted file mode 100644 index 854340d6d..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.h +++ /dev/null @@ -1,82 +0,0 @@ -/* - * 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. - */ - -/* metadata: - name: Freedom K32L2B3 - url: https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M - -// LED -#define LED_PIN_CLOCK kCLOCK_PortD -#define LED_GPIO GPIOD -#define LED_PORT PORTD -#define LED_PIN 5 -#define LED_STATE_ON 0 - -// SW3 button1 -#define BUTTON_PIN_CLOCK kCLOCK_PortC -#define BUTTON_GPIO GPIOC -#define BUTTON_PORT PORTC -#define BUTTON_PIN 3 -#define BUTTON_STATE_ACTIVE 0 - -// UART -#define UART_PORT LPUART0 -#define UART_PIN_CLOCK kCLOCK_PortA -#define UART_PIN_PORT PORTA -#define UART_PIN_RX 1u -#define UART_PIN_TX 2u -#define SOPT5_LPUART0RXSRC_LPUART_RX 0x00u /*!<@brief LPUART0 Receive Data Source Select: LPUART_RX pin */ -#define SOPT5_LPUART0TXSRC_LPUART_TX 0x00u /*!<@brief LPUART0 Transmit Data Source Select: LPUART0_TX pin */ -#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) - -static inline void BOARD_InitBootPins(void) { - /* PORTA1 (pin 23) is configured as LPUART0_RX */ - PORT_SetPinMux(PORTA, 1U, kPORT_MuxAlt2); - /* PORTA2 (pin 24) is configured as LPUART0_TX */ - PORT_SetPinMux(PORTA, 2U, kPORT_MuxAlt2); - - SIM->SOPT5 = ((SIM->SOPT5 & - /* Mask bits to zero which are setting */ - (~(SIM_SOPT5_LPUART0TXSRC_MASK | SIM_SOPT5_LPUART0RXSRC_MASK))) - /* LPUART0 Transmit Data Source Select: LPUART0_TX pin. */ - | SIM_SOPT5_LPUART0TXSRC(SOPT5_LPUART0TXSRC_LPUART_TX) - /* LPUART0 Receive Data Source Select: LPUART_RX pin. */ - | SIM_SOPT5_LPUART0RXSRC(SOPT5_LPUART0RXSRC_LPUART_RX)); - - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - CLOCK_SetLpuart0Clock(1); -} - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk deleted file mode 100644 index 9cf36c500..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/board.mk +++ /dev/null @@ -1,18 +0,0 @@ -MCU = K32L2B31A - -CFLAGS += -DCPU_K32L2B31VLH0A - -# mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls - -# All source paths should be relative to the top level. -LD_FILE = $(MCU_DIR)/gcc/K32L2B31xxxxA_flash.ld - -# For flash-jlink target -JLINK_DEVICE = K32L2B31xxxxA - -# For flash-pyocd target -PYOCD_TARGET = K32L2B - -# flash using pyocd -flash: flash-pyocd diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c deleted file mode 100644 index 86eb42ef8..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.c +++ /dev/null @@ -1,220 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ -/* - * How to setup clock using clock driver functions: - * - * 1. CLOCK_SetSimSafeDivs, to make sure core clock, bus clock, flexbus clock - * and flash clock are in allowed range during clock mode switch. - * - * 2. Call CLOCK_Osc0Init to setup OSC clock, if it is used in target mode. - * - * 3. Call CLOCK_SetMcgliteConfig to set MCG_Lite configuration. - * - * 4. Call CLOCK_SetSimConfig to set the clock configuration in SIM. - */ - -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!GlobalInfo -product: Clocks v7.0 -processor: K32L2B31xxxxA -package_id: K32L2B31VLH0A -mcu_data: ksdk2_0 -processor_version: 9.0.0 -board: FRDM-K32L2B - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -#include "fsl_smc.h" -#include "clock_config.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ -#define OSC_CAP0P 0U /*!< Oscillator 0pF capacitor load */ -#define OSC_ER_CLK_DISABLE 0U /*!< Disable external reference clock */ -#define SIM_OSC32KSEL_OSC32KCLK_CLK 0U /*!< OSC32KSEL select: OSC32KCLK clock */ - -/******************************************************************************* - * Variables - ******************************************************************************/ -/* System clock frequency. */ -//extern uint32_t SystemCoreClock; - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ -void BOARD_InitBootClocks(void) -{ - BOARD_BootClockRUN(); -} - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockRUN -called_from_default_init: true -outputs: -- {id: Bus_clock.outFreq, value: 24 MHz} -- {id: Core_clock.outFreq, value: 48 MHz} -- {id: Flash_clock.outFreq, value: 24 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 8 MHz} -- {id: MCGPCLK.outFreq, value: 48 MHz} -- {id: System_clock.outFreq, value: 48 MHz} -settings: -- {id: MCGMode, value: HIRC} -- {id: MCG.CLKS.sel, value: MCG.HIRC} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: MCG_C2_RANGE0_CFG, value: Very_high} -- {id: MCG_MC_HIRCEN_CFG, value: Enabled} -- {id: OSC0_CR_ERCLKEN_CFG, value: Enabled} -- {id: OSC_CR_ERCLKEN_CFG, value: Enabled} -- {id: SIM.CLKOUTSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.COPCLKSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.FLEXIOSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART0SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.LPUART1SRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -- {id: SIM.TPMSRCSEL.sel, value: MCG.MCGPCLK} -- {id: SIM.USBSRCSEL.sel, value: MCG.MCGPCLK} -sources: -- {id: MCG.HIRC.outFreq, value: 48 MHz} -- {id: OSC.OSC.outFreq, value: 32 MHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * 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_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockRUN = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = kOSC_ErClkEnable, /* Enable external reference clock, disable external reference clock in STOP mode */ - } - }; - -/******************************************************************************* - * 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; -} - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/* clang-format off */ -/* TEXT BELOW IS USED AS SETTING FOR TOOLS ************************************* -!!Configuration -name: BOARD_BootClockVLPR -outputs: -- {id: Bus_clock.outFreq, value: 1 MHz} -- {id: Core_clock.outFreq, value: 2 MHz} -- {id: Flash_clock.outFreq, value: 1 MHz} -- {id: LPO_clock.outFreq, value: 1 kHz} -- {id: MCGIRCLK.outFreq, value: 2 MHz} -- {id: System_clock.outFreq, value: 2 MHz} -settings: -- {id: MCGMode, value: LIRC2M} -- {id: powerMode, value: VLPR} -- {id: MCG_C2_OSC_MODE_CFG, value: ModeOscLowPower} -- {id: RTCCLKOUTConfig, value: 'yes'} -- {id: SIM.OUTDIV4.scale, value: '2', locked: true} -- {id: SIM.RTCCLKOUTSEL.sel, value: OSC.OSCERCLK} -sources: -- {id: MCG.LIRC.outFreq, value: 2 MHz} -- {id: OSC.OSC.outFreq, value: 32.768 kHz} - * BE CAREFUL MODIFYING THIS COMMENT - IT IS YAML SETTINGS FOR TOOLS **********/ -/* clang-format on */ - -/******************************************************************************* - * Variables for BOARD_BootClockVLPR configuration - ******************************************************************************/ -const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR = - { - .outSrc = kMCGLITE_ClkSrcLirc, /* MCGOUTCLK source is LIRC */ - .irclkEnableMode = kMCGLITE_IrclkEnable, /* MCGIRCLK enabled, MCGIRCLK disabled in STOP mode */ - .ircs = kMCGLITE_Lirc2M, /* Slow internal reference (LIRC) 2 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 = false, /* HIRC source is not enabled */ - }; -const sim_clock_config_t simConfig_BOARD_BootClockVLPR = - { - .er32kSrc = SIM_OSC32KSEL_OSC32KCLK_CLK, /* OSC32KSEL select: OSC32KCLK clock */ - .clkdiv1 = 0x10000U, /* SIM_CLKDIV1 - OUTDIV1: /1, OUTDIV4: /2 */ - }; -const osc_config_t oscConfig_BOARD_BootClockVLPR = - { - .freq = 0U, /* Oscillator frequency: 0Hz */ - .capLoad = (OSC_CAP0P), /* Oscillator capacity load: 0pF */ - .workMode = kOSC_ModeOscLowPower, /* Oscillator low power */ - .oscerConfig = - { - .enableMode = OSC_ER_CLK_DISABLE, /* Disable external reference clock */ - } - }; - -/******************************************************************************* - * Code for BOARD_BootClockVLPR configuration - ******************************************************************************/ -void BOARD_BootClockVLPR(void) -{ - /* Set the system clock dividers in SIM to safe value. */ - CLOCK_SetSimSafeDivs(); - /* Set MCG to LIRC2M mode. */ - CLOCK_SetMcgliteConfig(&mcgliteConfig_BOARD_BootClockVLPR); - /* Set the clock configuration in SIM module. */ - CLOCK_SetSimConfig(&simConfig_BOARD_BootClockVLPR); - /* Set VLPR power mode. */ - SMC_SetPowerModeProtection(SMC, kSMC_AllowPowerModeAll); -#if (defined(FSL_FEATURE_SMC_HAS_LPWUI) && FSL_FEATURE_SMC_HAS_LPWUI) - SMC_SetPowerModeVlpr(SMC, false); -#else - SMC_SetPowerModeVlpr(SMC); -#endif - while (SMC_GetPowerModeState(SMC) != kSMC_PowerStateVlpr) - { - } - /* Set SystemCoreClock variable. */ - SystemCoreClock = BOARD_BOOTCLOCKVLPR_CORE_CLOCK; -} diff --git a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h b/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h deleted file mode 100644 index 37328e7d8..000000000 --- a/hw/bsp/kinetis_k32l2/boards/frdm_k32l2b/clock_config.h +++ /dev/null @@ -1,110 +0,0 @@ -/* - * Copyright 2019 ,2021 NXP - * All rights reserved. - * - * SPDX-License-Identifier: BSD-3-Clause - */ - -/*********************************************************************************************************************** - * This file was generated by the MCUXpresso Config Tools. Any manual edits made to this file - * will be overwritten if the respective MCUXpresso Config Tools is used to update this file. - **********************************************************************************************************************/ - -#ifndef _CLOCK_CONFIG_H_ -#define _CLOCK_CONFIG_H_ - -#include "fsl_common.h" - -/******************************************************************************* - * Definitions - ******************************************************************************/ - -/******************************************************************************* - ************************ BOARD_InitBootClocks function ************************ - ******************************************************************************/ - -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes default configuration of clocks. - * - */ -void BOARD_InitBootClocks(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************** Configuration BOARD_BootClockRUN *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockRUN configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKRUN_CORE_CLOCK 48000000U /*!< Core clock frequency: 48000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockRUN configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockRUN; -/*! @brief SIM module set for BOARD_BootClockRUN configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockRUN; -/*! @brief OSC set for BOARD_BootClockRUN configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockRUN; - -/******************************************************************************* - * API for BOARD_BootClockRUN configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockRUN(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -/******************************************************************************* - ********************* Configuration BOARD_BootClockVLPR *********************** - ******************************************************************************/ -/******************************************************************************* - * Definitions for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#define BOARD_BOOTCLOCKVLPR_CORE_CLOCK 2000000U /*!< Core clock frequency: 2000000Hz */ - -/*! @brief MCG lite set for BOARD_BootClockVLPR configuration. - */ -extern const mcglite_config_t mcgliteConfig_BOARD_BootClockVLPR; -/*! @brief SIM module set for BOARD_BootClockVLPR configuration. - */ -extern const sim_clock_config_t simConfig_BOARD_BootClockVLPR; -/*! @brief OSC set for BOARD_BootClockVLPR configuration. - */ -extern const osc_config_t oscConfig_BOARD_BootClockVLPR; - -/******************************************************************************* - * API for BOARD_BootClockVLPR configuration - ******************************************************************************/ -#if defined(__cplusplus) -extern "C" { -#endif /* __cplusplus*/ - -/*! - * @brief This function executes configuration of clocks. - * - */ -void BOARD_BootClockVLPR(void); - -#if defined(__cplusplus) -} -#endif /* __cplusplus*/ - -#endif /* _CLOCK_CONFIG_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake b/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake deleted file mode 100644 index cf14000ac..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.cmake +++ /dev/null @@ -1,15 +0,0 @@ -set(MCU_VARIANT K32L2B31A) - -set(JLINK_DEVICE K32L2B31xxxxA) -set(PYOCD_TARGET K32L2B) - -set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/kuiic.ld) - -function(update_board TARGET) - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/clock_config.c - ) - target_compile_definitions(${TARGET} PUBLIC - CPU_K32L2B31VLH0A - ) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h b/hw/bsp/kinetis_k32l2/boards/kuiic/board.h deleted file mode 100644 index f5895fc65..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.h +++ /dev/null @@ -1,69 +0,0 @@ -/* - * 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. - */ - -/* metadata: - name: Kuiic - url: https://github.com/nxf58843/kuiic -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#include "fsl_device_registers.h" - -#define USB_CLOCK_SOURCE kCLOCK_UsbSrcIrc48M - -// 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 - -#define UART_CLOCK_SOURCE_HZ CLOCK_GetFreq(kCLOCK_McgIrc48MClk) - -static inline void BOARD_InitBootPins(void) { - /* 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)); - CLOCK_SetLpuart1Clock(1); -} - -#endif /* BOARD_H_ */ diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk b/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk deleted file mode 100644 index 2bc5b1e34..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/board.mk +++ /dev/null @@ -1,18 +0,0 @@ -MCU = K32L2B31A - -CFLAGS += -DCPU_K32L2B31VLH0A - -# mcu driver cause following warnings -CFLAGS += -Wno-error=unused-parameter -Wno-error=redundant-decls - -# All source paths should be relative to the top level. -LD_FILE = $(BOARD_PATH)/kuiic.ld - -# For flash-jlink target -JLINK_DEVICE = K32L2B31xxxxA - -# For flash-pyocd target -PYOCD_TARGET = K32L2B - -# flash using pyocd -flash: flash-pyocd diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c deleted file mode 100644 index c1a6d1a8d..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.c +++ /dev/null @@ -1,39 +0,0 @@ -#include "clock_config.h" -#include "fsl_clock.h" - -/******************************************************************************* - * 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; -} diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h b/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h deleted file mode 100644 index 920cad98f..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/clock_config.h +++ /dev/null @@ -1,14 +0,0 @@ -#ifndef CLOCK_CONFIG_H -#define CLOCK_CONFIG_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 */ - -void BOARD_BootClockRUN(void); - -#endif diff --git a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld b/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld deleted file mode 100644 index f478a99c7..000000000 --- a/hw/bsp/kinetis_k32l2/boards/kuiic/kuiic.ld +++ /dev/null @@ -1,216 +0,0 @@ -/* -** ################################################################### -** 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/kinetis_k32l2/family.c b/hw/bsp/kinetis_k32l2/family.c deleted file mode 100644 index ec8dc6ecf..000000000 --- a/hw/bsp/kinetis_k32l2/family.c +++ /dev/null @@ -1,175 +0,0 @@ -/* - * 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. - */ - -/* metadata: - manufacturer: NXP -*/ - -#include "fsl_gpio.h" -#include "fsl_port.h" -#include "fsl_clock.h" -#include "fsl_lpuart.h" - -#include "clock_config.h" -#include "bsp/board_api.h" -#include "board.h" - - -//--------------------------------------------------------------------+ -// 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); - - BOARD_InitBootPins(); - BOARD_BootClockRUN(); - SystemCoreClockUpdate(); - - gpio_pin_config_t led_config = {kGPIO_DigitalOutput, 0}; - GPIO_PinInit(LED_GPIO, LED_PIN, &led_config); - PORT_SetPinMux(LED_PORT, LED_PIN, 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, -#if defined(FSL_FEATURE_PORT_HAS_OPEN_DRAIN) && FSL_FEATURE_PORT_HAS_OPEN_DRAIN - kPORT_OpenDrainDisable, -#endif - kPORT_LowDriveStrength, - kPORT_MuxAsGpio, -#if defined(FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK) && FSL_FEATURE_PORT_HAS_PIN_CONTROL_LOCK - kPORT_UnlockRegister -#endif - }; - PORT_SetPinConfig(BUTTON_PORT, BUTTON_PIN, &BUTTON_CFG); -#endif - -#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, UART_CLOCK_SOURCE_HZ); - - // USB - CLOCK_EnableUsbfs0Clock(USB_CLOCK_SOURCE, 48000000U); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) { - GPIO_PinWrite(LED_GPIO, LED_PIN, state ? LED_STATE_ON : (1 - 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) { -#if 0 /* - Use this version if want the LED to blink during BOARD=board_test, - without having to hit a key. - */ - if( 0U != (kLPUART_RxDataRegFullFlag & LPUART_GetStatusFlags( UART_PORT )) ) - { - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; - } - - return( 0 ); -#else /* Wait for 'len' characters to come in */ - - LPUART_ReadBlocking(UART_PORT, buf, len); - return len; - -#endif -} - -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 tusb_time_millis_api(void) { - return system_ticks; -} - -#endif - -#ifndef __ICCARM__ -// Implement _start() since we use linker flag '-nostartfiles'. -// Requires defined __STARTUP_CLEAR_BSS, -extern int main(void); - -TU_ATTR_UNUSED void _start(void) { - // called by startup code - main(); - while (1) {} -} - -#ifdef __clang__ -void _exit (int __status) { - (void) __status; - while (1) {} -} -#endif - -#endif diff --git a/hw/bsp/kinetis_k32l2/family.cmake b/hw/bsp/kinetis_k32l2/family.cmake deleted file mode 100644 index 110335ab2..000000000 --- a/hw/bsp/kinetis_k32l2/family.cmake +++ /dev/null @@ -1,97 +0,0 @@ -include_guard() - -set(SDK_DIR ${TOP}/hw/mcu/nxp/mcux-sdk) -set(CMSIS_DIR ${TOP}/lib/CMSIS_5) - -# include board specific -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) - -# toolchain set up -set(CMAKE_SYSTEM_CPU cortex-m0plus CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS KINETIS_K32L CACHE INTERNAL "") - - -#------------------------------------ -# Startup & Linker script -#------------------------------------ -set(LD_FILE_Clang ${LD_FILE_GNU}) -set(STARTUP_FILE_GNU ${SDK_DIR}/devices/${MCU_VARIANT}/gcc/startup_${MCU_VARIANT}.S) -set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - -#------------------------------------ -# Board Target -#------------------------------------ -function(family_add_board BOARD_TARGET) - add_library(${BOARD_TARGET} STATIC - ${SDK_DIR}/drivers/gpio/fsl_gpio.c - ${SDK_DIR}/drivers/lpuart/fsl_lpuart.c - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers/fsl_clock.c - ${SDK_DIR}/devices/${MCU_VARIANT}/system_${MCU_VARIANT}.c - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - __STARTUP_CLEAR_BSS - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${CMSIS_DIR}/CMSIS/Core/Include - ${SDK_DIR}/devices/${MCU_VARIANT} - ${SDK_DIR}/devices/${MCU_VARIANT}/drivers - ${SDK_DIR}/drivers/common - ${SDK_DIR}/drivers/gpio - ${SDK_DIR}/drivers/lpuart - ${SDK_DIR}/drivers/port - ${SDK_DIR}/drivers/smc - ) - - update_board(${BOARD_TARGET}) -endfunction() - -#------------------------------------ -# Functions -#------------------------------------ -function(family_configure_example TARGET RTOS) - family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_KINETIS_K32L) - - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - ${TOP}/src/portable/nxp/khci/dcd_khci.c - ${TOP}/src/portable/nxp/khci/hcd_khci.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} - ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - --specs=nosys.specs --specs=nano.specs - -nostartfiles - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - target_link_options(${TARGET} PUBLIC - "LINKER:--script=${LD_FILE_GNU}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") - target_link_options(${TARGET} PUBLIC - "LINKER:--config=${LD_FILE_IAR}" - ) - endif () - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") - set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") - endif () - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) - - # Flashing - family_flash_jlink(${TARGET}) - family_add_bin_hex(${TARGET}) - family_flash_teensy(${TARGET}) -endfunction() diff --git a/hw/bsp/kinetis_k32l2/family.mk b/hw/bsp/kinetis_k32l2/family.mk deleted file mode 100644 index e18348d4d..000000000 --- a/hw/bsp/kinetis_k32l2/family.mk +++ /dev/null @@ -1,35 +0,0 @@ -UF2_FAMILY_ID = 0x7f83e793 -SDK_DIR = hw/mcu/nxp/mcux-sdk -MCU_DIR = $(SDK_DIR)/devices/$(MCU) - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= cortex-m0plus - -CFLAGS += \ - -DCFG_TUSB_MCU=OPT_MCU_KINETIS_K32L - -LDFLAGS_GCC += \ - -nostartfiles \ - -specs=nosys.specs -specs=nano.specs - -SRC_C += \ - src/portable/nxp/khci/dcd_khci.c \ - src/portable/nxp/khci/hcd_khci.c \ - $(MCU_DIR)/system_$(MCU).c \ - $(MCU_DIR)/drivers/fsl_clock.c \ - $(SDK_DIR)/drivers/gpio/fsl_gpio.c \ - $(SDK_DIR)/drivers/lpuart/fsl_lpuart.c - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/lib/CMSIS_5/CMSIS/Core/Include \ - $(TOP)/$(MCU_DIR) \ - $(TOP)/$(MCU_DIR)/project_template \ - $(TOP)/$(MCU_DIR)/drivers \ - $(TOP)/$(SDK_DIR)/drivers/common \ - $(TOP)/$(SDK_DIR)/drivers/gpio \ - $(TOP)/$(SDK_DIR)/drivers/lpuart \ - $(TOP)/$(SDK_DIR)/drivers/port \ - $(TOP)/$(SDK_DIR)/drivers/smc \ - -SRC_S += $(MCU_DIR)/gcc/startup_$(MCU).S diff --git a/tools/get_deps.py b/tools/get_deps.py index 115120ef7..77c3a593a 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -63,10 +63,13 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43'], 'hw/mcu/nxp/mcuxsdk-core': ['https://github.com/nxp-mcuxpresso/mcuxsdk-core', '0c5c6b16deb211110e06bde896cdff59ab213e16', - 'imxrt lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l lpc51 lpc55 mcx'], 'hw/mcu/nxp/mcux-sdk': ['https://github.com/nxp-mcuxpresso/mcux-sdk', 'a1bdae309a14ec95a4f64a96d3315a4f89c397c6', - 'kinetis_k kinetis_k32l2 kinetis_kl lpc54 rw61x'], + 'kinetis_k kinetis_kl lpc54 rw61x'], + 'hw/mcu/nxp/mcux-devices-kinetis': ['https://github.com/nxp-mcuxpresso/mcux-devices-kinetis', + '98a155e666c54f396e528ec3131f27a5d5b71f76', + 'kinetis_k32l'], 'hw/mcu/nxp/mcux-devices-lpc': ['https://github.com/nxp-mcuxpresso/mcux-devices-lpc', '8096b783ec09d0d1c8629025a5f9d8e7df26e520', 'lpc51 lpc55'], @@ -267,7 +270,7 @@ deps_optional = { 'hpmicro'], 'lib/CMSIS_5': ['https://github.com/ARM-software/CMSIS_5.git', '2b7495b8535bdcb306dac29b9ded4cfb679d7e5c', - 'kinetis_k kinetis_k32l2 kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x ' + 'kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x ' 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' @@ -275,7 +278,7 @@ deps_optional = { 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', - 'imxrt ra stm32n6 lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From 7ce1e7820451319227b2c1120a2b5e4a63ebf0a9 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Mar 2026 18:11:59 +0700 Subject: actual build make/cmake for ft9xx --- docs/reference/boards.rst | 2 +- docs/reference/dependencies.rst | 2 +- .../device/audio_4_channel_mic_freertos/skip.txt | 1 + examples/device/audio_test_freertos/skip.txt | 1 + examples/device/cdc_msc_freertos/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 1 + examples/device/midi_test_freertos/skip.txt | 1 + examples/host/cdc_msc_hid_freertos/skip.txt | 1 + hw/bsp/brtmm90x/boards/mm900evxb/board.h | 87 ------- hw/bsp/brtmm90x/family.c | 260 --------------------- hw/bsp/brtmm90x/family.mk | 66 ------ hw/bsp/family_support.cmake | 15 ++ hw/bsp/ft9xx/boards/mm900evxb/board.cmake | 5 + hw/bsp/ft9xx/boards/mm900evxb/board.h | 87 +++++++ hw/bsp/ft9xx/boards/mm900evxb/board.mk | 1 + hw/bsp/ft9xx/family.c | 260 +++++++++++++++++++++ hw/bsp/ft9xx/family.cmake | 74 ++++++ hw/bsp/ft9xx/family.mk | 75 ++++++ tools/get_deps.py | 4 +- 19 files changed, 527 insertions(+), 417 deletions(-) delete mode 100644 hw/bsp/brtmm90x/boards/mm900evxb/board.h delete mode 100644 hw/bsp/brtmm90x/family.c delete mode 100644 hw/bsp/brtmm90x/family.mk create mode 100644 hw/bsp/ft9xx/boards/mm900evxb/board.cmake create mode 100644 hw/bsp/ft9xx/boards/mm900evxb/board.h create mode 100644 hw/bsp/ft9xx/boards/mm900evxb/board.mk create mode 100644 hw/bsp/ft9xx/family.c create mode 100644 hw/bsp/ft9xx/family.cmake create mode 100644 hw/bsp/ft9xx/family.mk (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index eaef078d3..e01ea9d23 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -55,7 +55,7 @@ Bridgetek ========= ========= ======== ===================================== ====== Board Name Family URL Note ========= ========= ======== ===================================== ====== -mm900evxb MM900EVxB brtmm90x https://brtchip.com/product/mm900ev1b +mm900evxb MM900EVxB ft9xx https://brtchip.com/product/mm900ev1b ========= ========= ======== ===================================== ====== Espressif diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 9b61e10a8..16a43f479 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -17,7 +17,7 @@ hw/mcu/artery/at32f423 https://github.com/ArteryTek/AT32F423_ hw/mcu/artery/at32f425 https://github.com/ArteryTek/AT32F425_Firmware_Library.git 620233e1357d5c1b7e2bde6b9dd5196822b91817 at32f425 hw/mcu/artery/at32f435_437 https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git 25439cc6650a8ae0345934e8707a5f38c7ae41f8 at32f435_437 hw/mcu/artery/at32f45x https://github.com/ArteryTek/AT32F45x_Firmware_Library.git 3d4a1b38be8ebac292e2350ca53bc4bfa4430233 at32f45x -hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 brtmm90x +hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 ft9xx hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index ded5ee4bc..be44cb2c0 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -8,6 +8,7 @@ mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx +mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index be1912a31..007fece53 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -8,6 +8,7 @@ mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx +mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 199cd8ac6..31d808d8e 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -8,6 +8,7 @@ mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx +mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index 62f4a3795..8ae238584 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -8,6 +8,7 @@ mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx +mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI diff --git a/examples/device/midi_test_freertos/skip.txt b/examples/device/midi_test_freertos/skip.txt index 62f4a3795..8ae238584 100644 --- a/examples/device/midi_test_freertos/skip.txt +++ b/examples/device/midi_test_freertos/skip.txt @@ -8,6 +8,7 @@ mcu:GD32VF103 mcu:MCXA15 mcu:MKL25ZXX mcu:MSP430x5xx +mcu:FT90X mcu:RP2040 mcu:SAMD11 mcu:VALENTYUSB_EPTRI diff --git a/examples/host/cdc_msc_hid_freertos/skip.txt b/examples/host/cdc_msc_hid_freertos/skip.txt index 74ee436cb..bb62547a6 100644 --- a/examples/host/cdc_msc_hid_freertos/skip.txt +++ b/examples/host/cdc_msc_hid_freertos/skip.txt @@ -1,3 +1,4 @@ mcu:CH32F20X mcu:RP2040 board:lpcxpresso54114 +mcu:FT90X diff --git a/hw/bsp/brtmm90x/boards/mm900evxb/board.h b/hw/bsp/brtmm90x/boards/mm900evxb/board.h deleted file mode 100644 index 623033c2c..000000000 --- a/hw/bsp/brtmm90x/boards/mm900evxb/board.h +++ /dev/null @@ -1,87 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright 2021 Bridgetek Pte Ltd - * - * 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. - */ - -/* metadata: - name: MM900EVxB - url: https://brtchip.com/product/mm900ev1b -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -// Note: This definition file covers all MM900EV1B, MM900EV2B, MM900EV3B, -// MM900EV-Lite boards. -// Each of these boards has an FT900 device. - -#ifdef __cplusplus - extern "C" { -#endif - -// UART to use on this board. -#ifndef BOARD_UART -#define BOARD_UART UART0 -#endif - -// UART is on connector CN1. -#ifndef BOARD_GPIO_UART0_TX -#define BOARD_GPIO_UART0_TX 48 // Pin 4 of CN1. -#endif -#ifndef BOARD_GPIO_UART0_RX -#define BOARD_GPIO_UART0_RX 49 // Pin 6 of CN1. -#endif - -// LED is connected to pins 17 (signal) and 15 (GND) of CN1. -#ifndef BOARD_GPIO_LED -#define BOARD_GPIO_LED 35 -#endif -#ifndef BOARD_GPIO_LED_STATE_ON -#define BOARD_GPIO_LED_STATE_ON 1 -#endif -// Button is connected to pins 13 (signal) and 15 (GND) of CN1. -#ifndef BOARD_GPIO_BUTTON -#define BOARD_GPIO_BUTTON 56 -#endif -// Button is pulled up and grounded for active. -#ifndef BOARD_GPIO_BUTTON_STATE_ACTIVE -#define BOARD_GPIO_BUTTON_STATE_ACTIVE 0 -#endif - -// Enable the Remote Wakeup signalling. -// Remote wakeup is wired to pin 40 of CN1. -#ifndef BOARD_GPIO_REMOTE_WAKEUP -#define BOARD_GPIO_REMOTE_WAKEUP 18 -#endif - -// USB VBus signal is connected directly to the FT900. -#ifndef BOARD_USBD_VBUS_DTC_PIN -#define BOARD_USBD_VBUS_DTC_PIN 3 -#endif - -#ifdef __cplusplus - } -#endif - -#endif diff --git a/hw/bsp/brtmm90x/family.c b/hw/bsp/brtmm90x/family.c deleted file mode 100644 index ff24cfe89..000000000 --- a/hw/bsp/brtmm90x/family.c +++ /dev/null @@ -1,260 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright 2021 Bridgetek Pte Ltd - * - * 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. - */ - -/* metadata: - manufacturer: Bridgetek -*/ - -#include "bsp/board_api.h" -#include "board.h" - -#include -#include - -#if CFG_TUD_ENABLED -int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detection for USB device. -extern void ft9xx_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management -#endif - -#ifdef BOARD_GPIO_REMOTE_WAKEUP -void gpio_ISR(void); -#endif -void timer_ISR(void); -volatile unsigned int timer_ms = 0; -void board_pm_ISR(void); - -#define WELCOME_MSG "\x1B[2J\x1B[H" \ - "MM900EVxB board\r\n" - -// Initialize on-board peripherals : led, button, uart and USB -void board_init(void) -{ - sys_reset_all(); - - // Enable the UART Device. - sys_enable(sys_device_uart0); - // Set BOARD_UART GPIO function pins for TXD and RXD. -#ifdef BOARD_GPIO_UART_TX - gpio_function(BOARD_GPIO_UART_TX, pad_uart0_txd); /* UART0 TXD */ -#endif -#ifdef BOARD_GPIO_UART_RX - gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */ -#endif - uart_open(BOARD_UART, /* Device */ - 1, /* Prescaler = 1 */ - UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ - uart_data_bits_8, /* No. Data Bits */ - uart_parity_none, /* Parity */ - uart_stop_bits_1); /* No. Stop Bits */ - // Print out a welcome message. - // Use sizeof to avoid pulling in strlen unnecessarily. - board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); - -#ifdef BOARD_GPIO_LED - gpio_function(BOARD_GPIO_LED, pad_func_0); - gpio_idrive(BOARD_GPIO_LED, pad_drive_12mA); - gpio_dir(BOARD_GPIO_LED, pad_dir_output); -#endif - -#ifdef BOARD_GPIO_BUTTON - gpio_function(BOARD_GPIO_BUTTON, pad_func_0); - // Pull up if active low. Down if active high. - gpio_pull(BOARD_GPIO_BUTTON, (BOARD_GPIO_BUTTON_STATE_ACTIVE == 0)?pad_pull_pullup:pad_pull_pulldown); - gpio_dir(BOARD_GPIO_BUTTON, pad_dir_input); -#endif - - sys_enable(sys_device_timer_wdt); - /* Timer A = 1ms */ - timer_prescaler(timer_select_a, 1000); - timer_init(timer_select_a, 100, timer_direction_down, timer_prescaler_select_on, timer_mode_continuous); - timer_enable_interrupt(timer_select_a); - timer_start(timer_select_a); - interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); - - // Setup VBUS detect GPIO. If the device is connected then this - // will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG. - gpio_interrupt_disable(BOARD_USBD_VBUS_DTC_PIN); - gpio_function(BOARD_USBD_VBUS_DTC_PIN, pad_vbus_dtc); - gpio_pull(BOARD_USBD_VBUS_DTC_PIN, pad_pull_pulldown); - gpio_dir(BOARD_USBD_VBUS_DTC_PIN, pad_dir_input); - - interrupt_attach(interrupt_0, (int8_t)interrupt_0, board_pm_ISR); - -#ifdef BOARD_GPIO_REMOTE_WAKEUP - // Configuring GPIO pin to wakeup. - // Set up the wakeup pin. - gpio_dir(BOARD_GPIO_REMOTE_WAKEUP, pad_dir_input); - gpio_pull(BOARD_GPIO_REMOTE_WAKEUP, pad_pull_pullup); - - // Attach an interrupt handler. - interrupt_attach(interrupt_gpio, (uint8_t)interrupt_gpio, gpio_ISR); - gpio_interrupt_enable(BOARD_GPIO_REMOTE_WAKEUP, gpio_int_edge_falling); -#endif - - uart_disable_interrupt(BOARD_UART, uart_interrupt_tx); - uart_disable_interrupt(BOARD_UART, uart_interrupt_rx); - - // Enable all peripheral interrupts. - interrupt_enable_globally(); - - TU_LOG1("MM900EV1B board setup complete\r\n"); -}; - -void timer_ISR(void) -{ - if (timer_is_interrupted(timer_select_a)) - { - timer_ms++; - } -} - -#ifdef BOARD_GPIO_REMOTE_WAKEUP -void gpio_ISR(void) -{ - if (gpio_is_interrupted(BOARD_GPIO_REMOTE_WAKEUP)) - { - } -} -#endif - -/* Power management ISR */ -void board_pm_ISR(void) -{ - uint16_t pmcfg = SYS->PMCFG_H; - -#if defined(__FT930__) - if (pmcfg & MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND) - { - // Clear d2xx hw engine wakeup. - SYS->PMCFG_H = MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND; - } -#endif - if (pmcfg & MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND) - { - // Clear GPIO wakeup pending. - SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; - } - -#if defined(__FT900__) - // USB device power management interrupts. - if (pmcfg & (MASK_SYS_PMCFG_DEV_CONN_DEV | - MASK_SYS_PMCFG_DEV_DIS_DEV | - MASK_SYS_PMCFG_HOST_RST_DEV | - MASK_SYS_PMCFG_HOST_RESUME_DEV) - ) - { -#if CFG_TUD_ENABLED - ft9xx_usbd_pm_ISR(pmcfg); -#endif - } -#endif -} - -#if CFG_TUD_ENABLED -int8_t board_ft9xx_vbus(void) -{ - return gpio_read(BOARD_USBD_VBUS_DTC_PIN); -} -#endif - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -// Turn LED on or off -void board_led_write(bool state) -{ -#ifdef BOARD_GPIO_LED - gpio_write(BOARD_GPIO_LED, (state == 0)?(BOARD_GPIO_LED_STATE_ON?0:1):BOARD_GPIO_LED_STATE_ON); -#endif -} - -// Get the current state of button -// a '1' means active (pressed), a '0' means inactive. -uint32_t board_button_read(void) -{ - uint32_t state = 0; -#ifdef BOARD_GPIO_BUTTON - state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0; -#endif - return state; -} - -// Get characters from UART -int board_uart_read(uint8_t *buf, int len) -{ - int r = 0; - -#ifdef BOARD_UART - if (uart_rx_has_data(BOARD_UART)) - { - r = uart_readn(BOARD_UART, (uint8_t *)buf, len); - } -#endif - - return r; -} - -// Send characters to UART -int board_uart_write(void const *buf, int len) -{ - int r = 0; - -#ifdef BOARD_UART -#pragma GCC diagnostic push -#pragma GCC diagnostic ignored "-Wcast-qual" // uart_writen does not have const for buffer parameter. - r = uart_writen(BOARD_UART, (uint8_t *)((const void *)buf), len); -#pragma GCC diagnostic pop -#endif - - return r; -} - -// Get current milliseconds -uint32_t tusb_time_millis_api(void) -{ - uint32_t safe_ms; - - CRITICAL_SECTION_BEGIN - safe_ms = timer_ms; - CRITICAL_SECTION_END - - return safe_ms; -} - -// Restart the program -// Called in the event of a watchdog timeout -void chip_reboot(void) -{ - // SOFT reset - __asm__("call 0"); - #if 0 - // HARD reset - // Initiates data transfer from Flash Memory to Data Memory (DBG_CMDF2D3) - // followed by a system reboot - dbg_memory_copy(0xfe, 0, 0, 255); -#endif -} diff --git a/hw/bsp/brtmm90x/family.mk b/hw/bsp/brtmm90x/family.mk deleted file mode 100644 index 2de4dc760..000000000 --- a/hw/bsp/brtmm90x/family.mk +++ /dev/null @@ -1,66 +0,0 @@ -# GCC prefix for FT90X compile tools. -CROSS_COMPILE = ft32-elf- -SKIP_NANOLIB = 1 - -# Set to use FT90X prebuilt libraries. -FT9XX_PREBUILT_LIBS = 0 -ifeq ($(FT9XX_PREBUILT_LIBS),1) -# If the FT90X toolchain is installed on Windows systems then the SDK -# include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware -FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware -INC += "$(FT9XX_SDK)/include" -else -# The submodule BRTSG-FOSS/ft90x-sdk contains header files and source -# code for the Bridgetek SDK. This can be used instead of the prebuilt -# library. -# The SDK can be used to load specific files from the Bridgetek SDK. -FT9XX_SDK = hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source -INC += "$(TOP)/$(FT9XX_SDK)/include" -endif - -# Add include files which are within the TinyUSB directory structure. -INC += \ - $(TOP)/$(BOARD_PATH) - -# Add required C Compiler flags for FT90X. -CFLAGS += \ - -D__FT900__ \ - -fvar-tracking \ - -fvar-tracking-assignments \ - -fmessage-length=0 \ - -ffunction-sections \ - -DCFG_TUSB_MCU=OPT_MCU_FT90X - -# Maximum USB device speed supported by the board -CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED - -# lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration -CFLAGS += -Wno-error=shadow - -# Set Linker flags. -LD_FILE = hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld -LDFLAGS += $(addprefix -L,$(LDINC)) \ - -Xlinker --entry=_start \ - -Wl,-lc - -# Additional Source files for FT90X. -SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c - -# Linker library. -ifneq ($(FT9XX_PREBUILT_LIBS),1) -# Optionally add in files from the Bridgetek SDK instead of the prebuilt -# library. These are the minimum required. -SRC_C += $(FT9XX_SDK)/src/sys.c -SRC_C += $(FT9XX_SDK)/src/interrupt.c -SRC_C += $(FT9XX_SDK)/src/delay.c -SRC_C += $(FT9XX_SDK)/src/timers.c -SRC_C += $(FT9XX_SDK)/src/uart_simple.c -SRC_C += $(FT9XX_SDK)/src/gpio.c -else -# Or if using the prebuilt libraries add them. -LDFLAGS += -L"$(FT9XX_SDK)/lib" -LIBS += -lft900 -endif - -# Not required crt0 file for FT90X. Use compiler built-in file. -#SRC_S += hw/mcu/bridgetek/ft9xx/scripts/crt0.S diff --git a/hw/bsp/family_support.cmake b/hw/bsp/family_support.cmake index 8cc2af190..96d6993e6 100644 --- a/hw/bsp/family_support.cmake +++ b/hw/bsp/family_support.cmake @@ -881,6 +881,21 @@ function(family_flash_uniflash TARGET) set_property(TARGET ${TARGET}-uniflash PROPERTY FOLDER ${TARGET}-group) endfunction() +# Add flash ft9xx target need to remove kernal's ftdi_sio and bind D2XX drivers +# sudo rmmod ftdi_sio && for i in 0 1 2 3; do sudo sh -c "echo 3-3.4:1.$i > /sys/bus/usb/drivers/ftdi_sio/unbind" 2>/dev/null; done +function(family_flash_ft9xx TARGET) + if (NOT DEFINED FT9XXPROG) + set(FT9XXPROG FT9xxProg) + endif () + + add_custom_target(${TARGET}-ft9xx + DEPENDS ${TARGET} + COMMAND ${FT9XXPROG} -f $/${TARGET}.bin + ) + + set_property(TARGET ${TARGET}-ft9xx PROPERTY FOLDER ${TARGET}-group) +endfunction() + #---------------------------------- # Family specific #---------------------------------- diff --git a/hw/bsp/ft9xx/boards/mm900evxb/board.cmake b/hw/bsp/ft9xx/boards/mm900evxb/board.cmake new file mode 100644 index 000000000..49b779de4 --- /dev/null +++ b/hw/bsp/ft9xx/boards/mm900evxb/board.cmake @@ -0,0 +1,5 @@ +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + __FT900__ + ) +endfunction() diff --git a/hw/bsp/ft9xx/boards/mm900evxb/board.h b/hw/bsp/ft9xx/boards/mm900evxb/board.h new file mode 100644 index 000000000..623033c2c --- /dev/null +++ b/hw/bsp/ft9xx/boards/mm900evxb/board.h @@ -0,0 +1,87 @@ +/* + * The MIT License (MIT) + * + * Copyright 2021 Bridgetek Pte Ltd + * + * 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. + */ + +/* metadata: + name: MM900EVxB + url: https://brtchip.com/product/mm900ev1b +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +// Note: This definition file covers all MM900EV1B, MM900EV2B, MM900EV3B, +// MM900EV-Lite boards. +// Each of these boards has an FT900 device. + +#ifdef __cplusplus + extern "C" { +#endif + +// UART to use on this board. +#ifndef BOARD_UART +#define BOARD_UART UART0 +#endif + +// UART is on connector CN1. +#ifndef BOARD_GPIO_UART0_TX +#define BOARD_GPIO_UART0_TX 48 // Pin 4 of CN1. +#endif +#ifndef BOARD_GPIO_UART0_RX +#define BOARD_GPIO_UART0_RX 49 // Pin 6 of CN1. +#endif + +// LED is connected to pins 17 (signal) and 15 (GND) of CN1. +#ifndef BOARD_GPIO_LED +#define BOARD_GPIO_LED 35 +#endif +#ifndef BOARD_GPIO_LED_STATE_ON +#define BOARD_GPIO_LED_STATE_ON 1 +#endif +// Button is connected to pins 13 (signal) and 15 (GND) of CN1. +#ifndef BOARD_GPIO_BUTTON +#define BOARD_GPIO_BUTTON 56 +#endif +// Button is pulled up and grounded for active. +#ifndef BOARD_GPIO_BUTTON_STATE_ACTIVE +#define BOARD_GPIO_BUTTON_STATE_ACTIVE 0 +#endif + +// Enable the Remote Wakeup signalling. +// Remote wakeup is wired to pin 40 of CN1. +#ifndef BOARD_GPIO_REMOTE_WAKEUP +#define BOARD_GPIO_REMOTE_WAKEUP 18 +#endif + +// USB VBus signal is connected directly to the FT900. +#ifndef BOARD_USBD_VBUS_DTC_PIN +#define BOARD_USBD_VBUS_DTC_PIN 3 +#endif + +#ifdef __cplusplus + } +#endif + +#endif diff --git a/hw/bsp/ft9xx/boards/mm900evxb/board.mk b/hw/bsp/ft9xx/boards/mm900evxb/board.mk new file mode 100644 index 000000000..4e22ff2e6 --- /dev/null +++ b/hw/bsp/ft9xx/boards/mm900evxb/board.mk @@ -0,0 +1 @@ +CFLAGS += -D__FT900__ diff --git a/hw/bsp/ft9xx/family.c b/hw/bsp/ft9xx/family.c new file mode 100644 index 000000000..ff24cfe89 --- /dev/null +++ b/hw/bsp/ft9xx/family.c @@ -0,0 +1,260 @@ +/* + * The MIT License (MIT) + * + * Copyright 2021 Bridgetek Pte Ltd + * + * 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. + */ + +/* metadata: + manufacturer: Bridgetek +*/ + +#include "bsp/board_api.h" +#include "board.h" + +#include +#include + +#if CFG_TUD_ENABLED +int8_t board_ft9xx_vbus(void); // Board specific implementation of VBUS detection for USB device. +extern void ft9xx_usbd_pm_ISR(uint16_t pmcfg); // Interrupt handler for USB device power management +#endif + +#ifdef BOARD_GPIO_REMOTE_WAKEUP +void gpio_ISR(void); +#endif +void timer_ISR(void); +volatile unsigned int timer_ms = 0; +void board_pm_ISR(void); + +#define WELCOME_MSG "\x1B[2J\x1B[H" \ + "MM900EVxB board\r\n" + +// Initialize on-board peripherals : led, button, uart and USB +void board_init(void) +{ + sys_reset_all(); + + // Enable the UART Device. + sys_enable(sys_device_uart0); + // Set BOARD_UART GPIO function pins for TXD and RXD. +#ifdef BOARD_GPIO_UART_TX + gpio_function(BOARD_GPIO_UART_TX, pad_uart0_txd); /* UART0 TXD */ +#endif +#ifdef BOARD_GPIO_UART_RX + gpio_function(BOARD_GPIO_UART_RX, pad_uart0_rxd); /* UART0 RXD */ +#endif + uart_open(BOARD_UART, /* Device */ + 1, /* Prescaler = 1 */ + UART_DIVIDER_19200_BAUD, /* Divider = 1302 */ + uart_data_bits_8, /* No. Data Bits */ + uart_parity_none, /* Parity */ + uart_stop_bits_1); /* No. Stop Bits */ + // Print out a welcome message. + // Use sizeof to avoid pulling in strlen unnecessarily. + board_uart_write(WELCOME_MSG, sizeof(WELCOME_MSG)); + +#ifdef BOARD_GPIO_LED + gpio_function(BOARD_GPIO_LED, pad_func_0); + gpio_idrive(BOARD_GPIO_LED, pad_drive_12mA); + gpio_dir(BOARD_GPIO_LED, pad_dir_output); +#endif + +#ifdef BOARD_GPIO_BUTTON + gpio_function(BOARD_GPIO_BUTTON, pad_func_0); + // Pull up if active low. Down if active high. + gpio_pull(BOARD_GPIO_BUTTON, (BOARD_GPIO_BUTTON_STATE_ACTIVE == 0)?pad_pull_pullup:pad_pull_pulldown); + gpio_dir(BOARD_GPIO_BUTTON, pad_dir_input); +#endif + + sys_enable(sys_device_timer_wdt); + /* Timer A = 1ms */ + timer_prescaler(timer_select_a, 1000); + timer_init(timer_select_a, 100, timer_direction_down, timer_prescaler_select_on, timer_mode_continuous); + timer_enable_interrupt(timer_select_a); + timer_start(timer_select_a); + interrupt_attach(interrupt_timers, (int8_t)interrupt_timers, timer_ISR); + + // Setup VBUS detect GPIO. If the device is connected then this + // will set the MASK_SYS_PMCFG_DEV_DETECT_EN bit in PMCFG. + gpio_interrupt_disable(BOARD_USBD_VBUS_DTC_PIN); + gpio_function(BOARD_USBD_VBUS_DTC_PIN, pad_vbus_dtc); + gpio_pull(BOARD_USBD_VBUS_DTC_PIN, pad_pull_pulldown); + gpio_dir(BOARD_USBD_VBUS_DTC_PIN, pad_dir_input); + + interrupt_attach(interrupt_0, (int8_t)interrupt_0, board_pm_ISR); + +#ifdef BOARD_GPIO_REMOTE_WAKEUP + // Configuring GPIO pin to wakeup. + // Set up the wakeup pin. + gpio_dir(BOARD_GPIO_REMOTE_WAKEUP, pad_dir_input); + gpio_pull(BOARD_GPIO_REMOTE_WAKEUP, pad_pull_pullup); + + // Attach an interrupt handler. + interrupt_attach(interrupt_gpio, (uint8_t)interrupt_gpio, gpio_ISR); + gpio_interrupt_enable(BOARD_GPIO_REMOTE_WAKEUP, gpio_int_edge_falling); +#endif + + uart_disable_interrupt(BOARD_UART, uart_interrupt_tx); + uart_disable_interrupt(BOARD_UART, uart_interrupt_rx); + + // Enable all peripheral interrupts. + interrupt_enable_globally(); + + TU_LOG1("MM900EV1B board setup complete\r\n"); +}; + +void timer_ISR(void) +{ + if (timer_is_interrupted(timer_select_a)) + { + timer_ms++; + } +} + +#ifdef BOARD_GPIO_REMOTE_WAKEUP +void gpio_ISR(void) +{ + if (gpio_is_interrupted(BOARD_GPIO_REMOTE_WAKEUP)) + { + } +} +#endif + +/* Power management ISR */ +void board_pm_ISR(void) +{ + uint16_t pmcfg = SYS->PMCFG_H; + +#if defined(__FT930__) + if (pmcfg & MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND) + { + // Clear d2xx hw engine wakeup. + SYS->PMCFG_H = MASK_SYS_PMCFG_SLAVE_PERI_IRQ_PEND; + } +#endif + if (pmcfg & MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND) + { + // Clear GPIO wakeup pending. + SYS->PMCFG_H = MASK_SYS_PMCFG_PM_GPIO_IRQ_PEND; + } + +#if defined(__FT900__) + // USB device power management interrupts. + if (pmcfg & (MASK_SYS_PMCFG_DEV_CONN_DEV | + MASK_SYS_PMCFG_DEV_DIS_DEV | + MASK_SYS_PMCFG_HOST_RST_DEV | + MASK_SYS_PMCFG_HOST_RESUME_DEV) + ) + { +#if CFG_TUD_ENABLED + ft9xx_usbd_pm_ISR(pmcfg); +#endif + } +#endif +} + +#if CFG_TUD_ENABLED +int8_t board_ft9xx_vbus(void) +{ + return gpio_read(BOARD_USBD_VBUS_DTC_PIN); +} +#endif + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +// Turn LED on or off +void board_led_write(bool state) +{ +#ifdef BOARD_GPIO_LED + gpio_write(BOARD_GPIO_LED, (state == 0)?(BOARD_GPIO_LED_STATE_ON?0:1):BOARD_GPIO_LED_STATE_ON); +#endif +} + +// Get the current state of button +// a '1' means active (pressed), a '0' means inactive. +uint32_t board_button_read(void) +{ + uint32_t state = 0; +#ifdef BOARD_GPIO_BUTTON + state = (gpio_read(BOARD_GPIO_BUTTON) == BOARD_GPIO_BUTTON_STATE_ACTIVE)?1:0; +#endif + return state; +} + +// Get characters from UART +int board_uart_read(uint8_t *buf, int len) +{ + int r = 0; + +#ifdef BOARD_UART + if (uart_rx_has_data(BOARD_UART)) + { + r = uart_readn(BOARD_UART, (uint8_t *)buf, len); + } +#endif + + return r; +} + +// Send characters to UART +int board_uart_write(void const *buf, int len) +{ + int r = 0; + +#ifdef BOARD_UART +#pragma GCC diagnostic push +#pragma GCC diagnostic ignored "-Wcast-qual" // uart_writen does not have const for buffer parameter. + r = uart_writen(BOARD_UART, (uint8_t *)((const void *)buf), len); +#pragma GCC diagnostic pop +#endif + + return r; +} + +// Get current milliseconds +uint32_t tusb_time_millis_api(void) +{ + uint32_t safe_ms; + + CRITICAL_SECTION_BEGIN + safe_ms = timer_ms; + CRITICAL_SECTION_END + + return safe_ms; +} + +// Restart the program +// Called in the event of a watchdog timeout +void chip_reboot(void) +{ + // SOFT reset + __asm__("call 0"); + #if 0 + // HARD reset + // Initiates data transfer from Flash Memory to Data Memory (DBG_CMDF2D3) + // followed by a system reboot + dbg_memory_copy(0xfe, 0, 0, 255); +#endif +} diff --git a/hw/bsp/ft9xx/family.cmake b/hw/bsp/ft9xx/family.cmake new file mode 100644 index 000000000..31efb3c10 --- /dev/null +++ b/hw/bsp/ft9xx/family.cmake @@ -0,0 +1,74 @@ +include_guard() + +set(FT9XX_SDK ${TOP}/hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU ft32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/ft32_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS FT90X CACHE INTERNAL "") + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${FT9XX_SDK}/src/sys.c + ${FT9XX_SDK}/src/interrupt.c + ${FT9XX_SDK}/src/delay.c + ${FT9XX_SDK}/src/timers.c + ${FT9XX_SDK}/src/uart_simple.c + ${FT9XX_SDK}/src/gpio.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${FT9XX_SDK}/include + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + BOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + ) + target_compile_options(${BOARD_TARGET} PUBLIC + -fmessage-length=0 + ) + + update_board(${BOARD_TARGET}) +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_FT90X) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${TOP}/src/portable/bridgetek/ft9xx/dcd_ft9xx.c + ${FT9XX_SDK}/src/bootstrap.c + ) + set_source_files_properties(${FT9XX_SDK}/src/bootstrap.c PROPERTIES + COMPILE_OPTIONS "-w") + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + target_compile_options(${TARGET} PUBLIC + -Wno-error=shadow + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${TOP}/hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld" + "LINKER:--entry=_start" + ) + endif () + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_ft9xx(${TARGET}) +endfunction() diff --git a/hw/bsp/ft9xx/family.mk b/hw/bsp/ft9xx/family.mk new file mode 100644 index 000000000..9d71bf321 --- /dev/null +++ b/hw/bsp/ft9xx/family.mk @@ -0,0 +1,75 @@ +# GCC prefix for FT90X compile tools. +CROSS_COMPILE = ft32-elf- +SKIP_NANOLIB = 1 + +# Set to use FT90X prebuilt libraries. +FT9XX_PREBUILT_LIBS = 0 +ifeq ($(FT9XX_PREBUILT_LIBS),1) +# If the FT90X toolchain is installed on Windows systems then the SDK +# include files and prebuilt libraries are at: %FT90X_TOOLCHAIN%/hardware +FT9XX_SDK = $(FT90X_TOOLCHAIN)/hardware +INC += "$(FT9XX_SDK)/include" +else +# The submodule BRTSG-FOSS/ft90x-sdk contains header files and source +# code for the Bridgetek SDK. This can be used instead of the prebuilt +# library. +# The SDK can be used to load specific files from the Bridgetek SDK. +FT9XX_SDK = hw/mcu/bridgetek/ft9xx/ft90x-sdk/Source +INC += "$(TOP)/$(FT9XX_SDK)/include" +endif + +include $(TOP)/$(BOARD_PATH)/board.mk + +# Add include files which are within the TinyUSB directory structure. +INC += \ + $(TOP)/$(BOARD_PATH) + +# Add required C Compiler flags for FT9XX. +CFLAGS += \ + -fvar-tracking \ + -fvar-tracking-assignments \ + -fmessage-length=0 \ + -ffunction-sections \ + -DCFG_TUSB_MCU=OPT_MCU_FT90X + +# Maximum USB device speed supported by the board +CFLAGS += -DBOARD_TUD_MAX_SPEED=OPT_MODE_HIGH_SPEED + +# lwip/src/core/raw.c:334:43: error: declaration of 'recv' shadows a global declaration +CFLAGS += -Wno-error=shadow + +# Set Linker flags. +LD_FILE = hw/mcu/bridgetek/ft9xx/scripts/ldscript.ld +LDFLAGS += $(addprefix -L,$(LDINC)) \ + -Xlinker --entry=_start \ + -Wl,-lc + +# Additional Source files for FT90X. +SRC_C += src/portable/bridgetek/ft9xx/dcd_ft9xx.c + +# Linker library. +ifneq ($(FT9XX_PREBUILT_LIBS),1) +# Optionally add in files from the Bridgetek SDK instead of the prebuilt +# library. These are the minimum required. +SRC_C += $(FT9XX_SDK)/src/bootstrap.c +SRC_C += $(FT9XX_SDK)/src/sys.c +SRC_C += $(FT9XX_SDK)/src/interrupt.c +SRC_C += $(FT9XX_SDK)/src/delay.c +SRC_C += $(FT9XX_SDK)/src/timers.c +SRC_C += $(FT9XX_SDK)/src/uart_simple.c +SRC_C += $(FT9XX_SDK)/src/gpio.c +else +# Or if using the prebuilt libraries add them. +LDFLAGS += -L"$(FT9XX_SDK)/lib" +LIBS += -lft900 +endif + +# Not required crt0 file for FT90X. Use compiler built-in file. +#SRC_S += hw/mcu/bridgetek/ft9xx/scripts/crt0.S + +# Flash using FT9xxProg, need to remove kernal's ftdi_sio and bind D2XX drivers +# sudo rmmod ftdi_sio && for i in 0 1 2 3; do sudo sh -c "echo 3-3.4:1.$i > /sys/bus/usb/drivers/ftdi_sio/unbind" 2>/dev/null; done +FT9XXPROG ?= FT9xxProg +flash: flash-ft9xx +flash-ft9xx: $(BUILD)/$(PROJECT).bin + $(FT9XXPROG) -f $< diff --git a/tools/get_deps.py b/tools/get_deps.py index 77c3a593a..c4ec5454e 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -35,8 +35,8 @@ deps_optional = { 'b20b398d3e5e2007594e54a74ba3d2a2e50ddd75', 'maxim'], 'hw/mcu/bridgetek/ft9xx/ft90x-sdk': ['https://github.com/BRTSG-FOSS/ft90x-sdk.git', - '91060164afe239fcb394122e8bf9eb24d3194eb1', - 'brtmm90x'], + '03f74eac84645178fdde7f2e5ca9acdcb7bd9dcd', + 'ft9xx'], 'hw/mcu/broadcom': ['https://github.com/adafruit/broadcom-peripherals.git', '08370086080759ed54ac1136d62d2ad24c6fa267', 'broadcom_32bit broadcom_64bit'], -- cgit v1.3.1 From e2ead60107ce2e1324c7578fcee98efb8f0c5975 Mon Sep 17 00:00:00 2001 From: hathach Date: Fri, 13 Mar 2026 23:07:46 +0700 Subject: add ft9xx-gcc toolchain support to CI --- docs/reference/boards.rst | 95 ++++++++++++---------- docs/reference/dependencies.rst | 28 ++++--- examples/build_system/cmake/cpu/ft32.cmake | 13 +++ examples/build_system/cmake/cpu/rx610.cmake | 12 +++ examples/build_system/cmake/cpu/rx64m.cmake | 12 +++ .../build_system/cmake/toolchain/ft32_gcc.cmake | 22 +++++ examples/build_system/cmake/toolchain/rx_gcc.cmake | 26 ++++++ hw/bsp/hpmicro/boards/hpm6750evk2/board.h | 5 ++ 8 files changed, 160 insertions(+), 53 deletions(-) create mode 100644 examples/build_system/cmake/cpu/ft32.cmake create mode 100644 examples/build_system/cmake/cpu/rx610.cmake create mode 100644 examples/build_system/cmake/cpu/rx64m.cmake create mode 100644 examples/build_system/cmake/toolchain/ft32_gcc.cmake create mode 100644 examples/build_system/cmake/toolchain/rx_gcc.cmake (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index e01ea9d23..ef53c66c1 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -90,6 +90,15 @@ Board Name Family URL sipeed_longan_nano Sipeed Longan Nano gd32vf103 https://longan.sipeed.com/en/ ================== ================== ========= ============================= ====== +HPMicro +------- + +=========== =========== ======== ========================================================================== ====== +Board Name Family URL Note +=========== =========== ======== ========================================================================== ====== +hpm6750evk2 HPM6750EVK2 hpmicro https://hpm-sdk.readthedocs.io/en/v1.6.0/boards/hpm6750evk2/README_en.html +=========== =========== ======== ========================================================================== ====== + Infineon -------- @@ -149,51 +158,51 @@ mm32f327x_pitaya_lite DshanMCU Pitaya Lite with MM32F3273G8P mm32 https:/ NXP --- -================== ========================================= ============= ========================================================================================================================================================================= ====== -Board Name Family URL Note -================== ========================================= ============= ========================================================================================================================================================================= ====== -metro_m7_1011 Adafruit Metro M7 1011 imxrt https://www.adafruit.com/product/5600 -metro_m7_1011_sd Adafruit Metro M7 1011 SD imxrt https://www.adafruit.com/product/5600 -mimxrt1010_evk i.MX RT1010 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1010-evaluation-kit:MIMXRT1010-EVK -mimxrt1015_evk i.MX RT1015 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1015-EVK -mimxrt1020_evk i.MX RT1020 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1020-EVK -mimxrt1024_evk i.MX RT1024 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1024-evaluation-kit:MIMXRT1024-EVK -mimxrt1050_evkb i.MX RT1050 Evaluation Kit revB imxrt https://www.nxp.com/part/IMXRT1050-EVKB -mimxrt1060_evk i.MX RT1060 Evaluation Kit revB imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1060-EVKB -mimxrt1064_evk i.MX RT1064 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1064-EVK -mimxrt1170_evkb i.MX RT1070 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1170-evaluation-kit:MIMXRT1170-EVKB -teensy_40 Teensy 4.0 imxrt https://www.pjrc.com/store/teensy40.html -teensy_41 Teensy 4.1 imxrt https://www.pjrc.com/store/teensy41.html -frdm_k64f Freedom K64F kinetis_k https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F -teensy_35 Teensy 3.5 kinetis_k https://www.pjrc.com/store/teensy35.html +================== ========================================= ============ ========================================================================================================================================================================= ====== +Board Name Family URL Note +================== ========================================= ============ ========================================================================================================================================================================= ====== +metro_m7_1011 Adafruit Metro M7 1011 imxrt https://www.adafruit.com/product/5600 +mimxrt1010_evk i.MX RT1010 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1010-evaluation-kit:MIMXRT1010-EVK +mimxrt1015_evk i.MX RT1015 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1015-EVK +mimxrt1020_evk i.MX RT1020 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1020-EVK +mimxrt1024_evk i.MX RT1024 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1024-evaluation-kit:MIMXRT1024-EVK +mimxrt1050_evkb i.MX RT1050 Evaluation Kit revB imxrt https://www.nxp.com/part/IMXRT1050-EVKB +mimxrt1060_evk i.MX RT1060 Evaluation Kit revB imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1060-EVKB +mimxrt1064_evk i.MX RT1064 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/MIMXRT1064-EVK +mimxrt1170_evkb i.MX RT1070 Evaluation Kit imxrt https://www.nxp.com/design/design-center/development-boards-and-designs/i-mx-evaluation-and-development-boards/i-mx-rt1170-evaluation-kit:MIMXRT1170-EVKB +teensy_40 Teensy 4.0 imxrt https://www.pjrc.com/store/teensy40.html +teensy_41 Teensy 4.1 imxrt https://www.pjrc.com/store/teensy41.html +frdm_k64f Freedom K64F kinetis_k https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-k64-k63-and-k24-mcus:FRDM-K64F +teensy_35 Teensy 3.5 kinetis_k https://www.pjrc.com/store/teensy35.html frdm_k32l2a4s Freedom K32L2A4S kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-K32L2A4S frdm_k32l2b Freedom K32L2B3 kinetis_k32l https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/nxp-freedom-development-platform-for-k32-l2b-mcus:FRDM-K32L2B3 kuiic Kuiic kinetis_k32l https://github.com/nxf58843/kuiic -frdm_kl25z fomu kinetis_kl https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z -lpcxpresso11u37 LPCXpresso11U37 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13074 -lpcxpresso11u68 LPCXpresso11U68 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 -lpcxpresso1347 LPCXpresso1347 lpc13 https://www.nxp.com/products/no-longer-manufactured/lpcxpresso-board-for-lpc1347:OM13045 -lpcxpresso1549 LPCXpresso1549 lpc15 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13056 -lpcxpresso1769 LPCXpresso1769 lpc17 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13000 -mbed1768 mbed 1768 lpc17 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1700-arm-cortex-m3/arm-mbed-lpc1768-board:OM11043 -lpcxpresso18s37 LPCXpresso18s37 lpc18 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso18s37-development-board:OM13076 -mcb1800 Keil MCB1800 lpc18 https://www.keil.com/arm/mcb1800/ -ea4088_quickstart Embedded Artists LPC4088 QuickStart Board lpc40 https://www.embeddedartists.com/products/lpc4088-quickstart-board/ -ea4357 Embedded Artists LPC4357 Development Kit lpc43 https://www.embeddedartists.com/products/lpc4357-developers-kit/ -lpcxpresso43s67 LPCXpresso43S67 lpc43 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso43s67-development-board:OM13084 -lpcxpresso51u68 LPCXpresso51u68 lpc51 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpcxpresso51u68-for-the-lpc51u68-mcus:OM40005 -lpcxpresso54114 LPCXpresso54114 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54114-board:OM13089 -lpcxpresso54608 LPCXpresso54608 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-development-board-for-lpc5460x-mcus:OM13092 -lpcxpresso54628 LPCXpresso54628 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54628-development-board:OM13098 -double_m33_express Double M33 Express lpc55 https://www.crowdsupply.com/steiert-solutions/double-m33-express -lpcxpresso55s28 LPCXpresso55s28 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s28-development-board:LPC55S28-EVK -lpcxpresso55s69 LPCXpresso55s69 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s69-development-board:LPC55S69-EVK -mcu_link MCU Link lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcu-link-debug-probe:MCU-LINK -frdm_mcxa153 Freedom MCXA153 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA153 -frdm_mcxa156 Freedom MCXA156 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA156 -frdm_mcxn947 Freedom MCXN947 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXN947 -mcxn947brk MCXN947 Breakout mcx n/a -================== ========================================= ============= ========================================================================================================================================================================= ====== +frdm_kl25z fomu kinetis_kl https://www.nxp.com/design/design-center/development-boards-and-designs/general-purpose-mcus/freedom-development-platform-for-kinetis-kl14-kl15-kl24-kl25-mcus:FRDM-KL25Z +lpcxpresso11u37 LPCXpresso11U37 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13074 +lpcxpresso11u68 LPCXpresso11U68 lpc11 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13058 +lpcxpresso1347 LPCXpresso1347 lpc13 https://www.nxp.com/products/no-longer-manufactured/lpcxpresso-board-for-lpc1347:OM13045 +lpcxpresso1549 LPCXpresso1549 lpc15 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13056 +lpcxpresso1769 LPCXpresso1769 lpc17 https://www.nxp.com/design/design-center/development-boards-and-designs/OM13000 +mbed1768 mbed 1768 lpc17 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc1700-arm-cortex-m3/arm-mbed-lpc1768-board:OM11043 +lpcxpresso18s37 LPCXpresso18s37 lpc18 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso18s37-development-board:OM13076 +mcb1800 Keil MCB1800 lpc18 https://www.keil.com/arm/mcb1800/ +ea4088_quickstart Embedded Artists LPC4088 QuickStart Board lpc40 https://www.embeddedartists.com/products/lpc4088-quickstart-board/ +ea4357 Embedded Artists LPC4357 Development Kit lpc43 https://www.embeddedartists.com/products/lpc4357-developers-kit/ +lpcxpresso43s67 LPCXpresso43S67 lpc43 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso43s67-development-board:OM13084 +lpcxpresso51u68 LPCXpresso51u68 lpc51 https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpcxpresso51u68-for-the-lpc51u68-mcus:OM40005 +lpcxpresso54114 LPCXpresso54114 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54114-board:OM13089 +lpcxpresso54608 LPCXpresso54608 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-development-board-for-lpc5460x-mcus:OM13092 +lpcxpresso54628 LPCXpresso54628 lpc54 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso54628-development-board:OM13098 +double_m33_express Double M33 Express lpc55 https://www.crowdsupply.com/steiert-solutions/double-m33-express +lpcxpresso55s28 LPCXpresso55s28 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s28-development-board:LPC55S28-EVK +lpcxpresso55s69 LPCXpresso55s69 lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/lpcxpresso-boards/lpcxpresso55s69-development-board:LPC55S69-EVK +mcu_link MCU Link lpc55 https://www.nxp.com/design/design-center/software/development-software/mcuxpresso-software-and-tools-/mcu-link-debug-probe:MCU-LINK +frdm_mcxa153 Freedom MCXA153 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA153 +frdm_mcxa156 Freedom MCXA156 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXA156 +frdm_mcxn947 Freedom MCXN947 mcx https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-MCXN947 +mcxn947brk MCXN947 Breakout mcx n/a +frdm_rw612 FRDM-RW612 rw61x https://www.nxp.com/design/design-center/development-boards-and-designs/FRDM-RW612 +================== ========================================= ============ ========================================================================================================================================================================= ====== Nordic Semiconductor -------------------- @@ -292,7 +301,7 @@ stm32h723nucleo STM32 H723 Nucleo stm32h7 https://www.s stm32h743eval STM32 H743 Eval stm32h7 https://www.st.com/en/evaluation-tools/stm32h743i-eval.html stm32h743nucleo STM32 H743 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h743zi.html stm32h745disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html -stm32h747disco STM32 H747 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h747i-disco.html +stm32h747disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html stm32h750_weact STM32 H750 WeAct stm32h7 https://www.adafruit.com/product/5032 stm32h750bdk STM32 H750b Discovery Kit stm32h7 https://www.st.com/en/evaluation-tools/stm32h750b-dk.html waveshare_openh743i Waveshare Open H743i stm32h7 https://www.waveshare.com/openh743i-c-standard.htm diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 16a43f479..450ec6a25 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral drivers and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -17,16 +17,22 @@ hw/mcu/artery/at32f423 https://github.com/ArteryTek/AT32F423_ hw/mcu/artery/at32f425 https://github.com/ArteryTek/AT32F425_Firmware_Library.git 620233e1357d5c1b7e2bde6b9dd5196822b91817 at32f425 hw/mcu/artery/at32f435_437 https://github.com/ArteryTek/AT32F435_437_Firmware_Library.git 25439cc6650a8ae0345934e8707a5f38c7ae41f8 at32f435_437 hw/mcu/artery/at32f45x https://github.com/ArteryTek/AT32F45x_Firmware_Library.git 3d4a1b38be8ebac292e2350ca53bc4bfa4430233 at32f45x -hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 91060164afe239fcb394122e8bf9eb24d3194eb1 ft9xx +hw/mcu/bridgetek/ft9xx/ft90x-sdk https://github.com/BRTSG-FOSS/ft90x-sdk.git 03f74eac84645178fdde7f2e5ca9acdcb7bd9dcd ft9xx hw/mcu/broadcom https://github.com/adafruit/broadcom-peripherals.git 08370086080759ed54ac1136d62d2ad24c6fa267 broadcom_32bit broadcom_64bit hw/mcu/gd/nuclei-sdk https://github.com/Nuclei-Software/nuclei-sdk.git 7eb7bfa9ea4fbeacfafe1d5f77d5a0e6ed3922e7 gd32vf103 +hw/mcu/hpmicro/hpm_sdk https://github.com/hpmicro/hpm_sdk 8d2af741ecc4aaa82d7ee395dc1ce25d7070c3ff hpmicro hw/mcu/infineon/mtb-xmclib-cat3 https://github.com/Infineon/mtb-xmclib-cat3.git daf5500d03cba23e68c2f241c30af79cd9d63880 xmc4000 -hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg +hw/mcu/microchip https://github.com/hathach/microchip_driver.git 9e8b37e307d8404033bb881623a113931e1edf27 sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg hw/mcu/mindmotion/mm32sdk https://github.com/hathach/mm32sdk.git b93e856211060ae825216c6a1d6aa347ec758843 mm32 hw/mcu/nordic/nrfx https://github.com/NordicSemiconductor/nrfx.git 11f57e578c7feea13f21c79ea0efab2630ac68c7 nrf hw/mcu/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc100_120 nuc121_125 nuc126 nuc505 hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git b41cf930e65c734d8ec6de04f1d57d46787c76ae lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 -hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx imxrt +hw/mcu/nxp/mcux-devices-kinetis https://github.com/nxp-mcuxpresso/mcux-devices-kinetis 98a155e666c54f396e528ec3131f27a5d5b71f76 kinetis_k32l +hw/mcu/nxp/mcux-devices-lpc https://github.com/nxp-mcuxpresso/mcux-devices-lpc 8096b783ec09d0d1c8629025a5f9d8e7df26e520 lpc51 lpc55 +hw/mcu/nxp/mcux-devices-mcx https://github.com/nxp-mcuxpresso/mcux-devices-mcx ada1c97c761123ec0c179bb9bb9f744bf9a11475 mcx +hw/mcu/nxp/mcux-devices-rt https://github.com/nxp-mcuxpresso/mcux-devices-rt dba2b523c9df61f3330bd186242f8210a8e47c45 imxrt +hw/mcu/nxp/mcux-sdk https://github.com/nxp-mcuxpresso/mcux-sdk a1bdae309a14ec95a4f64a96d3315a4f89c397c6 kinetis_k kinetis_kl lpc54 rw61x +hw/mcu/nxp/mcuxsdk-core https://github.com/nxp-mcuxpresso/mcuxsdk-core 0c5c6b16deb211110e06bde896cdff59ab213e16 imxrt kinetis_k32l lpc51 lpc55 mcx hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git 675543bcc9baa8170f868ab7ba316d418dbcf41f rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git edcc97d684b6f716728a60d7a6fea049d9870bd6 ra hw/mcu/renesas/rx https://github.com/kkitayam/rx_device.git 706b4e0cf485605c32351e2f90f5698267996023 rx @@ -54,7 +60,7 @@ hw/mcu/st/cmsis_device_n6 https://github.com/STMicroelectronics/ hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 6e67187dec98035893692ab2923914cb5f4e0117 stm32u5 hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git cda2cb9fc4a5232ab18efece0bb06b0b60910083 stm32wb hw/mcu/st/stm32-mfxstm32l152 https://github.com/STMicroelectronics/stm32-mfxstm32l152.git 7f4389efee9c6a655b55e5df3fceef5586b35f9b stm32h7 -hw/mcu/st/stm32-tcpp0203 https://github.com/STMicroelectronics/stm32-tcpp0203.git 9918655bff176ac3046ccf378b5c7bbbc6a38d15 stm32h7rs stm32n6 +hw/mcu/st/stm32-tcpp0203 https://github.com/STMicroelectronics/stm32-tcpp0203.git 9918655bff176ac3046ccf378b5c7bbbc6a38d15 stm32h5 stm32h7rs stm32n6 hw/mcu/st/stm32c0xx_hal_driver https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git c283b143bef6bdaacf64240ee6f15eb61dad6125 stm32c0 hw/mcu/st/stm32f0xx_hal_driver https://github.com/STMicroelectronics/stm32f0xx_hal_driver.git 94399697cb5eeaf8511b81b7f50dc62f0a5a3f6c stm32f0 hw/mcu/st/stm32f1xx_hal_driver https://github.com/STMicroelectronics/stm32f1xx_hal_driver.git 18074e3e5ecad0b380a5cf5a9131fe4b5ed1b2b7 stm32f1 @@ -76,15 +82,17 @@ hw/mcu/st/stm32u0xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2c5e2568fbdb1900a13ca3b2901fdd302cac3444 stm32u5 hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb -hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c +hw/mcu/ti https://github.com/hathach/ti_driver.git 083944907e7d08fcb1f614b47598ce45935b8da1 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c imxrt kinetis_k32l kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf saml2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wbasam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samg tm4c -lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 ra stm32n6 +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg tm4c +lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 +lib/threadx https://github.com/eclipse-threadx/threadx.git 4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae all +tools/linkermap https://github.com/hathach/linkermap.git 8e1f440fa15c567aceb5aa0d14f6d18c329cc67f all tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== ============================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== diff --git a/examples/build_system/cmake/cpu/ft32.cmake b/examples/build_system/cmake/cpu/ft32.cmake new file mode 100644 index 000000000..13153e555 --- /dev/null +++ b/examples/build_system/cmake/cpu/ft32.cmake @@ -0,0 +1,13 @@ +if (TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -fvar-tracking + -fvar-tracking-assignments + ) + +elseif (TOOLCHAIN STREQUAL "clang") + message(FATAL_ERROR "Clang is not supported for this target") + +elseif (TOOLCHAIN STREQUAL "iar") + message(FATAL_ERROR "IAR is not supported for this target") + +endif () diff --git a/examples/build_system/cmake/cpu/rx610.cmake b/examples/build_system/cmake/cpu/rx610.cmake new file mode 100644 index 000000000..6f535275d --- /dev/null +++ b/examples/build_system/cmake/cpu/rx610.cmake @@ -0,0 +1,12 @@ +if (NOT DEFINED TOOLCHAIN OR TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=rx610 + -misa=v1 + -mlittle-endian-data + -fshort-enums + ) + set(FREERTOS_PORT GCC_RX600 CACHE INTERNAL "") + +else () + message(FATAL_ERROR "Toolchain ${TOOLCHAIN} is not supported for RX") +endif () diff --git a/examples/build_system/cmake/cpu/rx64m.cmake b/examples/build_system/cmake/cpu/rx64m.cmake new file mode 100644 index 000000000..2b106ea00 --- /dev/null +++ b/examples/build_system/cmake/cpu/rx64m.cmake @@ -0,0 +1,12 @@ +if (NOT DEFINED TOOLCHAIN OR TOOLCHAIN STREQUAL "gcc") + set(TOOLCHAIN_COMMON_FLAGS + -mcpu=rx64m + -misa=v2 + -mlittle-endian-data + -fshort-enums + ) + set(FREERTOS_PORT GCC_RX600 CACHE INTERNAL "") + +else () + message(FATAL_ERROR "Toolchain ${TOOLCHAIN} is not supported for RX") +endif () diff --git a/examples/build_system/cmake/toolchain/ft32_gcc.cmake b/examples/build_system/cmake/toolchain/ft32_gcc.cmake new file mode 100644 index 000000000..edf8048ab --- /dev/null +++ b/examples/build_system/cmake/toolchain/ft32_gcc.cmake @@ -0,0 +1,22 @@ +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER "ft32-elf-gcc") +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER "ft32-elf-g++") +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) + +find_program(CMAKE_SIZE ft32-elf-size) +find_program(CMAKE_OBJCOPY ft32-elf-objcopy) +find_program(CMAKE_OBJDUMP ft32-elf-objdump) + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/examples/build_system/cmake/toolchain/rx_gcc.cmake b/examples/build_system/cmake/toolchain/rx_gcc.cmake new file mode 100644 index 000000000..3f8e3662e --- /dev/null +++ b/examples/build_system/cmake/toolchain/rx_gcc.cmake @@ -0,0 +1,26 @@ +# Cross Compiler for RX +if (NOT DEFINED CROSS_COMPILE) + set(CROSS_COMPILE "rx-elf-") +endif () + +if (NOT DEFINED CMAKE_C_COMPILER) + set(CMAKE_C_COMPILER ${CROSS_COMPILE}gcc) +endif () + +if (NOT DEFINED CMAKE_CXX_COMPILER) + set(CMAKE_CXX_COMPILER ${CROSS_COMPILE}g++) +endif () + +set(CMAKE_ASM_COMPILER ${CMAKE_C_COMPILER}) +find_program(CMAKE_SIZE ${CROSS_COMPILE}size) +find_program(CMAKE_OBJCOPY ${CROSS_COMPILE}objcopy) +find_program(CMAKE_OBJDUMP ${CROSS_COMPILE}objdump) + +include(${CMAKE_CURRENT_LIST_DIR}/common.cmake) + +get_property(IS_IN_TRY_COMPILE GLOBAL PROPERTY IN_TRY_COMPILE) +if (IS_IN_TRY_COMPILE) + set(CMAKE_C_LINK_FLAGS "${CMAKE_C_LINK_FLAGS} -nostdlib") + set(CMAKE_CXX_LINK_FLAGS "${CMAKE_CXX_LINK_FLAGS} -nostdlib") + cmake_print_variables(CMAKE_C_LINK_FLAGS) +endif () diff --git a/hw/bsp/hpmicro/boards/hpm6750evk2/board.h b/hw/bsp/hpmicro/boards/hpm6750evk2/board.h index 0636a4722..929e11c0d 100644 --- a/hw/bsp/hpmicro/boards/hpm6750evk2/board.h +++ b/hw/bsp/hpmicro/boards/hpm6750evk2/board.h @@ -5,6 +5,11 @@ * */ +/* metadata: + name: HPM6750EVK2 + url: https://hpm-sdk.readthedocs.io/en/v1.6.0/boards/hpm6750evk2/README_en.html +*/ + #ifndef _HPM_BOARD_H #define _HPM_BOARD_H -- cgit v1.3.1 From c5e3098c37cf165ffde9a304238558294e328e73 Mon Sep 17 00:00:00 2001 From: hathach Date: Sat, 14 Mar 2026 11:08:52 +0700 Subject: update rx65n_target: correct pin configuration and remove unused USB interrupt definitions --- .github/workflows/ci_set_matrix.py | 1 + docs/reference/boards.rst | 2 +- docs/reference/dependencies.rst | 8 ++++---- hw/bsp/rx/boards/rx65n_target/board.cmake | 5 ----- hw/bsp/rx/boards/rx65n_target/rx65n_target.c | 2 +- hw/bsp/stm32h7/boards/stm32h747disco/board.h | 4 ++-- tools/get_deps.py | 2 +- 7 files changed, 10 insertions(+), 14 deletions(-) (limited to 'docs') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 98d15c8f9..1d35f15dd 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -26,6 +26,7 @@ family_list = { "at32f45x": ["arm-gcc"], "broadcom_32bit": ["arm-gcc"], "broadcom_64bit": ["aarch64-gcc"], + "ch32f20x": ["arm-gcc"], "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index ef53c66c1..ec91b343e 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -301,7 +301,7 @@ stm32h723nucleo STM32 H723 Nucleo stm32h7 https://www.s stm32h743eval STM32 H743 Eval stm32h7 https://www.st.com/en/evaluation-tools/stm32h743i-eval.html stm32h743nucleo STM32 H743 Nucleo stm32h7 https://www.st.com/en/evaluation-tools/nucleo-h743zi.html stm32h745disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html -stm32h747disco STM32 H745 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h745i-disco.html +stm32h747disco STM32 H747 Discovery stm32h7 https://www.st.com/en/evaluation-tools/stm32h747i-disco.html stm32h750_weact STM32 H750 WeAct stm32h7 https://www.adafruit.com/product/5032 stm32h750bdk STM32 H750b Discovery Kit stm32h7 https://www.st.com/en/evaluation-tools/stm32h750b-dk.html waveshare_openh743i Waveshare Open H743i stm32h7 https://www.waveshare.com/openh743i-c-standard.htm diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index 450ec6a25..c5b755577 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -4,9 +4,9 @@ Dependencies MCU low-level peripheral drivers and external libraries for building TinyUSB examples -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== Local Path Repo Commit Required by -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s hw/mcu/analog/msdk https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 maxim hw/mcu/artery/at32f402_405 https://github.com/ArteryTek/AT32F402_405_Firmware_Library.git 4424515c2663e82438654e0947695295df2abdfe at32f402_405 @@ -87,7 +87,7 @@ hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.gi hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x -lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg tm4c +lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samg tm4c lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all @@ -95,4 +95,4 @@ lib/sct_neopixel https://github.com/gsteiert/sct_neopix lib/threadx https://github.com/eclipse-threadx/threadx.git 4b6e8100d932a3a67b34c6eb17f84f3bffb9e2ae all tools/linkermap https://github.com/hathach/linkermap.git 8e1f440fa15c567aceb5aa0d14f6d18c329cc67f all tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all -======================================== ================================================================ ======================================== =================================================================================================================================================================================================================================================================================================================================================== +======================================== ================================================================ ======================================== ======================================================================================================================================================================================================================================================================================================================================== diff --git a/hw/bsp/rx/boards/rx65n_target/board.cmake b/hw/bsp/rx/boards/rx65n_target/board.cmake index e365fe8ad..c8b9286bc 100644 --- a/hw/bsp/rx/boards/rx65n_target/board.cmake +++ b/hw/bsp/rx/boards/rx65n_target/board.cmake @@ -19,9 +19,4 @@ function(update_board TARGET) target_include_directories(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR} ) - target_compile_definitions(${TARGET} PUBLIC - IR_USB0_USBI0=IR_PERIB_INTB185 - IER_USB0_USBI0=IER_PERIB_INTB185 - IEN_USB0_USBI0=IEN_PERIB_INTB185 - ) endfunction() diff --git a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c index dbaa9d6fe..318cd1b6d 100644 --- a/hw/bsp/rx/boards/rx65n_target/rx65n_target.c +++ b/hw/bsp/rx/boards/rx65n_target/rx65n_target.c @@ -116,7 +116,7 @@ void board_pin_init(void) PORTA.PCR.BIT.B4 = 1U; MPC.PA4PFS.BYTE = 0b01010; PORTA.PMR.BIT.B3 = 1U; - MPC.PA5PFS.BYTE = 0b01010; + MPC.PA3PFS.BYTE = 0b01010; /* USB VBUS -> P16 */ PORT1.PMR.BIT.B6 = 1U; diff --git a/hw/bsp/stm32h7/boards/stm32h747disco/board.h b/hw/bsp/stm32h7/boards/stm32h747disco/board.h index 0a25c89dc..1793338f8 100644 --- a/hw/bsp/stm32h7/boards/stm32h747disco/board.h +++ b/hw/bsp/stm32h7/boards/stm32h747disco/board.h @@ -25,8 +25,8 @@ */ /* metadata: - name: STM32 H745 Discovery - url: https://www.st.com/en/evaluation-tools/stm32h745i-disco.html + name: STM32 H747 Discovery + url: https://www.st.com/en/evaluation-tools/stm32h747i-disco.html */ #ifndef BOARD_H_ diff --git a/tools/get_deps.py b/tools/get_deps.py index c4ec5454e..25b85ac3b 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -274,7 +274,7 @@ deps_optional = { 'lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 ' 'stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 ' 'stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba ' - 'sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samd2x_l2x samg ' + 'sam3x samd11 samd21 samd2x_l2x samd51 samd5x_e5x same5x same7x samg ' 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', -- cgit v1.3.1 From b4e92f63c6b653101320cbb9e8ca3f76fbc81509 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Sat, 14 Mar 2026 09:19:24 +0100 Subject: fix windows build Signed-off-by: HiFiPhile --- docs/conf.py | 4 ++-- 1 file changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/conf.py b/docs/conf.py index cd0338413..9e9784fb7 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -52,11 +52,11 @@ def preprocess_readme(): src = Path(__file__).parent.parent / "README.rst" tgt = Path(__file__).parent.parent / "README_processed.rst" if src.exists(): - content = src.read_text() + content = src.read_text(encoding='utf-8') content = re.sub(r"docs/", r"", content) content = re.sub(r"\.rst\b", r".html", content) if not content.endswith("\n"): content += "\n" - tgt.write_text(content) + tgt.write_text(content, encoding='utf-8') preprocess_readme() -- cgit v1.3.1 From 20fdaeef6ca8853002087927e460c0b6339049cd Mon Sep 17 00:00:00 2001 From: alt-0191 <2223147307@qq.com> Date: Thu, 26 Feb 2026 21:10:04 +0800 Subject: ch58x: fix MCU macro naming and add get_deps/boards entries --- docs/reference/boards.rst | 1 + hw/bsp/ch58x/family.cmake | 2 +- hw/bsp/ch58x/family.mk | 2 +- src/common/tusb_mcu.h | 4 ++-- src/tusb_option.h | 4 +++- tools/get_deps.py | 3 +++ 6 files changed, 11 insertions(+), 5 deletions(-) (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index ec91b343e..517c479fe 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -368,4 +368,5 @@ ch32v203g_r0_1v0 CH32V203G-R0-1v0 ch32v20x https://github.com/openwch/ch32v20 nanoch32v203 nanoCH32V203 ch32v20x https://github.com/wuxx/nanoCH32V203 ch32v307v_r1_1v0 CH32V307V-R1-1v0 ch32v30x https://github.com/openwch/ch32v307/tree/main/SCHPCB/CH32V307V-R1-1v0 nanoch32v305 nanoCH32V305 ch32v30x https://github.com/wuxx/nanoCH32V305 +yd-ch582m yd-ch582m ch58x http://vcc-gnd.com ================ ================ ======== ===================================================================== ====== diff --git a/hw/bsp/ch58x/family.cmake b/hw/bsp/ch58x/family.cmake index 9ad158662..64b534eb1 100644 --- a/hw/bsp/ch58x/family.cmake +++ b/hw/bsp/ch58x/family.cmake @@ -64,7 +64,7 @@ endfunction() #------------------------------------ function(family_configure_example TARGET RTOS) family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_CH582) + family_add_tinyusb(${TARGET} OPT_MCU_CH58X) target_sources(${TARGET} PUBLIC ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c diff --git a/hw/bsp/ch58x/family.mk b/hw/bsp/ch58x/family.mk index 41eb36c84..566842f93 100644 --- a/hw/bsp/ch58x/family.mk +++ b/hw/bsp/ch58x/family.mk @@ -13,7 +13,7 @@ CFLAGS += \ -mno-save-restore \ -fmessage-length=0 \ -fsigned-char \ - -DCFG_TUSB_MCU=OPT_MCU_CH582 \ + -DCFG_TUSB_MCU=OPT_MCU_CH58X \ -DCFG_TUD_WCH_USBIP_USBFS=1 \ -DFREQ_SYS=60000000 \ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index 02364d580..dfeae3fbb 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -629,8 +629,8 @@ #define TUP_DCD_EDPT_CLOSE_API #endif -#elif TU_CHECK_MCU(OPT_MCU_CH582) - // CH58x has 2 independent USBFS controllers with merged EP registers, FS only. +#elif TU_CHECK_MCU(OPT_MCU_CH58X) + // CH582/583 has 2 independent USBFS controllers with merged EP registers, FS only. #define TUP_USBIP_WCH_CH58X #ifndef CFG_TUD_WCH_USBIP_USBFS diff --git a/src/tusb_option.h b/src/tusb_option.h index 50998613a..699e3d44d 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -193,7 +193,9 @@ #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X #define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 -#define OPT_MCU_CH58X 2240 ///< WCH CH582/CH583 +#define OPT_MCU_CH58X 2240 ///< WCH CH58x series (CH582/CH583) +#define OPT_MCU_CH582 OPT_MCU_CH58X ///< alias +#define OPT_MCU_CH583 OPT_MCU_CH58X ///< alias // NXP LPC MCX #define OPT_MCU_MCXN9 2300 ///< NXP MCX N9 Series diff --git a/tools/get_deps.py b/tools/get_deps.py index 25b85ac3b..eb239bf34 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -241,6 +241,9 @@ deps_optional = { 'hw/mcu/wch/ch32f20x': ['https://github.com/openwch/ch32f20x.git', '77c4095087e5ed2c548ec9058e655d0b8757663b', 'ch32f20x'], + 'hw/mcu/wch/ch58x': ['https://github.com/openwch/ch583.git', + 'bd508ad7ceed48377619837051412a651952857f', + 'ch58x'], 'hw/mcu/artery/at32f403a_407': ['https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git', 'f2cb360c3d28fada76b374308b8c4c61d37a090b', 'at32f403a_407'], -- cgit v1.3.1 From ebd18f5efaef402a2f71afa153ff8bbf81272c22 Mon Sep 17 00:00:00 2001 From: Cédric Berger Date: Sun, 22 Mar 2026 14:20:37 +0100 Subject: Update documentation --- docs/reference/architecture.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst index 70ea17ed4..523e1d615 100644 --- a/docs/reference/architecture.rst +++ b/docs/reference/architecture.rst @@ -189,13 +189,13 @@ Class Driver Interface See ``usbd.c``. **Required Functions**: -- ``init()``: Initialize class driver - ``reset()``: Reset class state - ``open()``: Configure class endpoints - ``control_xfer_cb()``: Handle control requests - ``xfer_cb()``: Handle data transfer completion **Optional Functions**: +- ``init()``: Initialize class driver - ``close()``: Clean up class resources - ``deinit()``: Deinitialize class driver - ``sof()``: Start-of-frame processing -- cgit v1.3.1 From d8994a3018118136837e18895955e6ddbb89a5ec Mon Sep 17 00:00:00 2001 From: Ha Thach Date: Mon, 23 Mar 2026 11:46:16 +0700 Subject: Revert "Make driver init() function optional" --- docs/reference/architecture.rst | 2 +- src/device/usbd.c | 7 +++---- src/host/usbh.c | 2 +- 3 files changed, 5 insertions(+), 6 deletions(-) (limited to 'docs') diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst index 523e1d615..70ea17ed4 100644 --- a/docs/reference/architecture.rst +++ b/docs/reference/architecture.rst @@ -189,13 +189,13 @@ Class Driver Interface See ``usbd.c``. **Required Functions**: +- ``init()``: Initialize class driver - ``reset()``: Reset class state - ``open()``: Configure class endpoints - ``control_xfer_cb()``: Handle control requests - ``xfer_cb()``: Handle data transfer completion **Optional Functions**: -- ``init()``: Initialize class driver - ``close()``: Clean up class resources - ``deinit()``: Deinitialize class driver - ``sof()``: Start-of-frame processing diff --git a/src/device/usbd.c b/src/device/usbd.c index c7f511eac..42903576c 100644 --- a/src/device/usbd.c +++ b/src/device/usbd.c @@ -572,10 +572,9 @@ bool tud_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Init class drivers for (uint8_t i = 0; i < TOTAL_DRIVER_COUNT; i++) { usbd_class_driver_t const* driver = get_driver(i); - if (driver && driver->init) { - TU_LOG_USBD("%s init\r\n", driver->name); - driver->init(); - } + TU_ASSERT(driver && driver->init); + TU_LOG_USBD("%s init\r\n", driver->name); + driver->init(); } _usbd_rhport = rhport; diff --git a/src/host/usbh.c b/src/host/usbh.c index f65a3a427..75df6bf60 100644 --- a/src/host/usbh.c +++ b/src/host/usbh.c @@ -544,7 +544,7 @@ bool tuh_rhport_init(uint8_t rhport, const tusb_rhport_init_t* rh_init) { // Class drivers for (uint8_t drv_id = 0; drv_id < TOTAL_DRIVER_COUNT; drv_id++) { usbh_class_driver_t const* driver = get_driver(drv_id); - if (driver && driver->init) { + if (driver != NULL) { TU_LOG_USBH("%s init\r\n", driver->name); driver->init(); } -- cgit v1.3.1 From ec2d1d7cff21a1654cf9f2ebee16536fe75b5835 Mon Sep 17 00:00:00 2001 From: Valentyn Korniienko <25596072+ValentiWorkLearning@users.noreply.github.com> Date: Tue, 31 Mar 2026 12:39:16 +0300 Subject: Removed readme and modified the getting started doc --- docs/getting_started.rst | 2 ++ hw/bsp/stm32h7/boards/stm32h743_weact/README.md | 7 ------- 2 files changed, 2 insertions(+), 7 deletions(-) delete mode 100644 hw/bsp/stm32h7/boards/stm32h743_weact/README.md (limited to 'docs') diff --git a/docs/getting_started.rst b/docs/getting_started.rst index 8442305d4..7fcc2f5d1 100644 --- a/docs/getting_started.rst +++ b/docs/getting_started.rst @@ -38,6 +38,8 @@ Get the Code * **rp2040**: Requires `pico-sdk `_ * **Espressif (esp32)**: Requires `esp-idf `_. Only a few examples support the ESP-IDF build system. Look for ones with `src/CMakeLists.txt` that contain `idf_component_register()`, such as `cdc_msc_freertos`. +.. note:: + For MacOS native build with arm-none-eabi-gcc toolchain it's better to install it via brew install --cask gcc-arm-embedded Simple Device Example --------------------- diff --git a/hw/bsp/stm32h7/boards/stm32h743_weact/README.md b/hw/bsp/stm32h7/boards/stm32h743_weact/README.md deleted file mode 100644 index 2bf463fef..000000000 --- a/hw/bsp/stm32h7/boards/stm32h743_weact/README.md +++ /dev/null @@ -1,7 +0,0 @@ -## How to quick setup - -1. python tools/get_deps.py -b stm32h743_weact -2. cd examples/device/cdc_msc -3. brew install --cask gcc-arm-embedded -3. cmake -DBOARD=stm32h743_weact -B build -DCMAKE_BUILD_TYPE=Debug -4. cmake --build build --parallel \ No newline at end of file -- cgit v1.3.1 From a39e9cdf2c82401eb61b99dd35e73531bcd76cf1 Mon Sep 17 00:00:00 2001 From: gab-k Date: Fri, 27 Mar 2026 18:34:04 +0100 Subject: Add initial board support for nRF54LM20 DK --- docs/reference/boards.rst | 1 + hw/bsp/BoardPresets.json | 22 +++++++ hw/bsp/nrf/boards/nrf54lm20dk/board.cmake | 11 ++++ hw/bsp/nrf/boards/nrf54lm20dk/board.h | 58 ++++++++++++++++++ hw/bsp/nrf/boards/nrf54lm20dk/board.mk | 6 ++ hw/bsp/nrf/family.c | 69 ++++++++++++++++++++-- hw/bsp/nrf/family.cmake | 28 ++++++--- hw/bsp/nrf/family.mk | 15 ++++- .../nrf/linker/nrf54lm20a_enga_xxaa_application.ld | 13 ++++ hw/bsp/nrf/nrfx_config/nrfx_config_common.h | 3 + src/common/tusb_mcu.h | 1 + src/portable/synopsys/dwc2/dwc2_nrf.h | 27 ++++++++- 12 files changed, 238 insertions(+), 16 deletions(-) create mode 100644 hw/bsp/nrf/boards/nrf54lm20dk/board.cmake create mode 100644 hw/bsp/nrf/boards/nrf54lm20dk/board.h create mode 100644 hw/bsp/nrf/boards/nrf54lm20dk/board.mk create mode 100644 hw/bsp/nrf/linker/nrf54lm20a_enga_xxaa_application.ld (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index ec91b343e..dbb5942ca 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -221,6 +221,7 @@ nrf52840dk Nordic nRF52840DK nrf ht nrf52840dongle Nordic nRF52840 Dongle nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF52840-Dongle nrf5340dk Nordic nRF5340 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK nrf54h20dk Nordic nRF54H20 DK nrf https://www.nordicsemi.com/Software-and-Tools/Development-Kits/nRF5340-DK +nrf54lm20dk Nordic nRF54LM20 DK nrf https://www.nordicsemi.com/Products/Development-hardware/nRF54LM20-DK =========================== ===================================== ======== ============================================================================== ====== Raspberry Pi diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 5c3aaf2b4..86609d075 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -470,6 +470,10 @@ "name": "nrf54h20dk", "inherits": "default" }, + { + "name": "nrf54lm20dk", + "inherits": "default" + }, { "name": "nutiny_nuc126v", "inherits": "default" @@ -1563,6 +1567,11 @@ "description": "Build preset for the nrf54h20dk board", "configurePreset": "nrf54h20dk" }, + { + "name": "nrf54lm20dk", + "description": "Build preset for the nrf54lm20dk board", + "configurePreset": "nrf54lm20dk" + }, { "name": "nutiny_nuc126v", "description": "Build preset for the nutiny_nuc126v board", @@ -3711,6 +3720,19 @@ } ] }, + { + "name": "nrf54lm20dk", + "steps": [ + { + "type": "configure", + "name": "nrf54lm20dk" + }, + { + "type": "build", + "name": "nrf54lm20dk" + } + ] + }, { "name": "nutiny_nuc126v", "steps": [ diff --git a/hw/bsp/nrf/boards/nrf54lm20dk/board.cmake b/hw/bsp/nrf/boards/nrf54lm20dk/board.cmake new file mode 100644 index 000000000..fb0ccdfdf --- /dev/null +++ b/hw/bsp/nrf/boards/nrf54lm20dk/board.cmake @@ -0,0 +1,11 @@ +set(MCU_VARIANT nrf54lm20a_enga) +set(JLINK_DEVICE NRF54LM20A_M33) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + CFG_EXAMPLE_VIDEO_READONLY + ) + target_sources(${TARGET} PRIVATE +# ${NRFX_PATH}/drivers/src/nrfx_usbreg.c + ) +endfunction() diff --git a/hw/bsp/nrf/boards/nrf54lm20dk/board.h b/hw/bsp/nrf/boards/nrf54lm20dk/board.h new file mode 100644 index 000000000..6bf5da891 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf54lm20dk/board.h @@ -0,0 +1,58 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2020, Ha Thach (tinyusb.org) + * Copyright (c) 2026, Gabriel Koppenstein + * + * 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. + */ + +/* metadata: + name: Nordic nRF54LM20 DK + url: https://www.nordicsemi.com/Products/Development-hardware/nRF54LM20-DK +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus + extern "C" { +#endif + +#define _PINNUM(port, pin) ((port)*32 + (pin)) + +// LED0 active high (MOSFET-driven) +#define LED_PIN _PINNUM(1, 22) +#define LED_STATE_ON 1 + +// Button0 active low +#define BUTTON_PIN _PINNUM(1, 26) +#define BUTTON_STATE_ACTIVE 0 + +// UART20 (VCOM via debugger) +#define UART_TX_PIN _PINNUM(1, 16) +#define UART_RX_PIN _PINNUM(1, 17) + +#ifdef __cplusplus + } +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/nrf/boards/nrf54lm20dk/board.mk b/hw/bsp/nrf/boards/nrf54lm20dk/board.mk new file mode 100644 index 000000000..ad0177b40 --- /dev/null +++ b/hw/bsp/nrf/boards/nrf54lm20dk/board.mk @@ -0,0 +1,6 @@ +MCU_VARIANT = nrf54lm20a_enga +CFLAGS += -DNRF54LM20A_ENGA_XXAA + +# flash using jlink +JLINK_DEVICE = NRF54LM20A_M33 +flash: flash-jlink diff --git a/hw/bsp/nrf/family.c b/hw/bsp/nrf/family.c index f1e8b829c..10f0fc460 100644 --- a/hw/bsp/nrf/family.c +++ b/hw/bsp/nrf/family.c @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2019 Ha Thach (tinyusb.org) + * Copyright (c) 2026, Gabriel Koppenstein * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -45,7 +46,7 @@ #include "nrfx.h" #include "hal/nrf_gpio.h" #include "nrfx_gpiote.h" -#if !defined(NRF54H20_XXAA) +#if !defined(NRF54H20_XXAA) && !defined(NRF54LM20A_ENGA_XXAA) #include "nrfx_power.h" #endif #include "nrfx_uarte.h" @@ -79,13 +80,17 @@ enum { }; // Forward USB interrupt events to TinyUSB IRQ Handler -#if defined(NRF54H20_XXAA) +#if defined(NRF54H20_XXAA) || defined(NRF54LM20A_ENGA_XXAA) #define USBD_IRQn USBHS_IRQn void USBHS_IRQHandler(void) { tusb_int_handler(0, true); } +#if defined(NRF54LM20A_ENGA_XXAA) +static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(20); +#else static nrfx_uarte_t _uart_id = NRFX_UARTE_INSTANCE(120); +#endif #else @@ -114,7 +119,7 @@ void USBD_IRQHandler(void) { // We must call it within SD's SOC event handler, or set it as power event handler if SD is not enabled. extern void tusb_hal_nrf_power_event(uint32_t event); -#if !defined(NRF54H20_XXAA) +#if !defined(NRF54H20_XXAA) && !defined(NRF54LM20A_ENGA_XXAA) // nrf power callback, could be unused if SD is enabled or usb is disabled (board_test example) TU_ATTR_UNUSED static void power_event_handler(nrfx_power_usb_evt_t event) { tusb_hal_nrf_power_event((uint32_t) event); @@ -133,7 +138,7 @@ static nrfx_gpiote_t _gpiote = NRFX_GPIOTE_INSTANCE(0); //--------------------------------------------------------------------+ void board_init(void) { -#if !defined(NRF54H20_XXAA) +#if !defined(NRF54H20_XXAA) && !defined(NRF54LM20A_ENGA_XXAA) // stop LF clock just in case we jump from application without reset NRF_CLOCK->TASKS_LFCLKSTOP = 1UL; @@ -186,11 +191,63 @@ void board_init(void) { //------------- USB -------------// #if CFG_TUD_ENABLED + +#if defined(NRF54LM20A_ENGA_XXAA) + // Start the USB voltage regulator + NRF_VREGUSB->TASKS_START = VREGUSB_TASKS_START_TASKS_START_Trigger; + + // Request HFXO crystal clock for PCLK24M (required by USBHS core) + NRF_CLOCK->TASKS_XO24MSTART = CLOCK_TASKS_XO24MSTART_TASKS_XO24MSTART_Trigger; + while (!NRF_CLOCK->EVENTS_XO24MSTARTED) {} + NRF_CLOCK->EVENTS_XO24MSTARTED = 0; +#endif + +#if defined(NRF54H20_XXAA) + // Enable the USBHS wrapper (core + PHY) before any DWC2 register access + NRF_USBHS->ENABLE = (USBHS_ENABLE_PHY_Enabled << USBHS_ENABLE_PHY_Pos) | + (USBHS_ENABLE_CORE_Enabled << USBHS_ENABLE_CORE_Pos); + NRF_USBHS->TASKS_START = USBHS_TASKS_START_TASKS_START_Trigger; + // Brief delay for PHY PLL lock and core power-up + for (volatile int i = 0; i < 1000; i++) {} +#endif + +#if defined(NRF54LM20A_ENGA_XXAA) + // Based on Zephyr usbhs_enable_core() in drivers/usb/udc/udc_dwc2_vendor_quirks.h + // Step 1: Power up core only (PHY not yet) + NRF_USBHS->ENABLE = USBHS_ENABLE_CORE_Msk; + + // Step 2: Override ID=Device (bit 31), and temporarily override VBUSVALID + NRF_USBHS->PHY.OVERRIDEVALUES = (USBHS_PHY_OVERRIDEVALUES_ID_Device << USBHS_PHY_OVERRIDEVALUES_ID_Pos); + NRF_USBHS->PHY.INPUTOVERRIDE = USBHS_PHY_INPUTOVERRIDE_ID_Msk | USBHS_PHY_INPUTOVERRIDE_VBUSVALID_Msk; + + // Step 3: Release PHY power-on reset by enabling PHY + NRF_USBHS->ENABLE = USBHS_ENABLE_PHY_Msk | USBHS_ENABLE_CORE_Msk; + + // Step 4: Wait 45us for PHY clock to start + NRFX_DELAY_US(45); + + // Step 5: Release DWC2 reset + NRF_USBHS->TASKS_START = USBHS_TASKS_START_TASKS_START_Trigger; + + // Step 6: Wait for clock to start to avoid hang on too early register read + NRFX_DELAY_US(2); + + // Step 7: Clear VBUSVALID override (keep ID=Device override) + // DWC2 is now in Non-Driving opmode; D+ pull-up will activate when DWC2 clears DCTL SftDiscon + NRF_USBHS->PHY.INPUTOVERRIDE = USBHS_PHY_INPUTOVERRIDE_ID_Msk; + + // Barrier: USBHS wrapper (0x5005A000) and USBHSCORE (0x50020000) are separate + // peripheral blocks. Ensure the ENABLE/TASKS_START writes have propagated from + // the Cortex-M33 write buffer to hardware before anyone reads DWC2 core regs. + __DSB(); + +#endif + // Priorities 0, 1, 4 (nRF52) are reserved for SoftDevice // 2 is highest for application NVIC_SetPriority(USBD_IRQn, 2); -#if !defined(NRF54H20_XXAA) +#if !defined(NRF54H20_XXAA) && !defined(NRF54LM20A_ENGA_XXAA) // USB power may already be ready at this time -> no event generated // We need to invoke the handler based on the status initially uint32_t usb_reg; @@ -258,7 +315,7 @@ size_t board_get_unique_id(uint8_t id[], size_t max_len) { #if defined(NRF54H20_XXAA) uintptr_t did_addr = (uintptr_t) NRF_FICR->BLE.ADDR; -#elif defined(NRF5340_XXAA) +#elif defined(NRF54LM20A_ENGA_XXAA) || defined(NRF5340_XXAA) uintptr_t did_addr = (uintptr_t) NRF_FICR->INFO.DEVICEID; #else uintptr_t did_addr = (uintptr_t) NRF_FICR->DEVICEID; diff --git a/hw/bsp/nrf/family.cmake b/hw/bsp/nrf/family.cmake index 3a6e7cc8b..fba5e6e69 100644 --- a/hw/bsp/nrf/family.cmake +++ b/hw/bsp/nrf/family.cmake @@ -10,15 +10,19 @@ if (NOT board_cmake_included) endif () # toolchain set up -if (MCU_VARIANT STREQUAL nrf5340 OR MCU_VARIANT STREQUAL nrf54h20) +if (MCU_VARIANT STREQUAL nrf5340 OR MCU_VARIANT STREQUAL nrf54h20 OR MCU_VARIANT STREQUAL nrf54lm20a_enga) set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") - set(JLINK_DEVICE ${MCU_VARIANT}_xxaa_app) + if (NOT DEFINED JLINK_DEVICE) + set(JLINK_DEVICE ${MCU_VARIANT}_xxaa_app) + endif () else () set(CMAKE_SYSTEM_CPU cortex-m4 CACHE INTERNAL "System Processor") - set(JLINK_DEVICE ${MCU_VARIANT}_xxaa) + if (NOT DEFINED JLINK_DEVICE) + set(JLINK_DEVICE ${MCU_VARIANT}_xxaa) + endif () endif () -if (MCU_VARIANT STREQUAL "nrf54h20") +if (MCU_VARIANT STREQUAL "nrf54h20" OR MCU_VARIANT STREQUAL "nrf54lm20a_enga") set(FAMILY_MCUS NRF54 CACHE INTERNAL "") else () set(FAMILY_MCUS NRF5X CACHE INTERNAL "") @@ -29,7 +33,10 @@ set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOL #------------------------------------ # Startup & Linker script #------------------------------------ -if (MCU_VARIANT STREQUAL nrf54h20) +if (MCU_VARIANT STREQUAL nrf54lm20a_enga) + set(LD_FILE_GNU_DEFAULT ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_xxaa_application.ld) + set(STARTUP_FILE_GNU ${NRFX_PATH}/mdk/gcc_startup_${MCU_VARIANT}_application.S) +elseif (MCU_VARIANT STREQUAL nrf54h20) set(LD_FILE_GNU_DEFAULT ${CMAKE_CURRENT_LIST_DIR}/linker/${MCU_VARIANT}_xxaa_application.ld) set(STARTUP_FILE_GNU ${NRFX_PATH}/mdk/gcc_startup_${MCU_VARIANT}_application.S) elseif (MCU_VARIANT STREQUAL nrf5340) @@ -52,13 +59,20 @@ function(family_add_board BOARD_TARGET) add_library(${BOARD_TARGET} STATIC ${NRFX_PATH}/helpers/nrfx_flag32_allocator.c ${NRFX_PATH}/drivers/src/nrfx_gpiote.c - ${NRFX_PATH}/drivers/src/nrfx_power.c ${NRFX_PATH}/drivers/src/nrfx_spim.c ${NRFX_PATH}/drivers/src/nrfx_uarte.c ${NRFX_PATH}/soc/nrfx_atomic.c ) - if (MCU_VARIANT STREQUAL nrf54h20) + if (NOT FAMILY_MCUS STREQUAL "NRF54") + target_sources(${BOARD_TARGET} PRIVATE ${NRFX_PATH}/drivers/src/nrfx_power.c) + endif () + + if (MCU_VARIANT STREQUAL nrf54lm20a_enga) + target_sources(${BOARD_TARGET} PRIVATE + ${NRFX_PATH}/mdk/system_nrf54l.c + ) + elseif (MCU_VARIANT STREQUAL nrf54h20) target_sources(${BOARD_TARGET} PRIVATE ${NRFX_PATH}/mdk/system_nrf54h.c ) diff --git a/hw/bsp/nrf/family.mk b/hw/bsp/nrf/family.mk index e7e9e7d0a..0cc3c81ef 100644 --- a/hw/bsp/nrf/family.mk +++ b/hw/bsp/nrf/family.mk @@ -4,6 +4,15 @@ NRFX_PATH = hw/mcu/nordic/nrfx include $(TOP)/$(BOARD_PATH)/board.mk +ifeq (${MCU_VARIANT},nrf54lm20a_enga) + CPU_CORE = cortex-m33 + CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF54 + LD_FILE_DEFAULT = ${FAMILY_PATH}/linker/${MCU_VARIANT}_xxaa_application.ld + SRC_C += ${NRFX_PATH}/mdk/system_nrf54l.c + SRC_S += ${NRFX_PATH}/mdk/gcc_startup_$(MCU_VARIANT)_application.S + JLINK_DEVICE ?= $(MCU_VARIANT)_xxaa_app + +else ifeq (${MCU_VARIANT},nrf54h20) CPU_CORE = cortex-m33 CFLAGS += -DCFG_TUSB_MCU=OPT_MCU_NRF54 @@ -32,6 +41,7 @@ else JLINK_DEVICE ?= $(MCU_VARIANT)_xxaa endif endif +endif CFLAGS += \ -DNRF_APPLICATION \ @@ -70,11 +80,14 @@ SRC_C += \ src/portable/synopsys/dwc2/hcd_dwc2.c \ ${NRFX_PATH}/helpers/nrfx_flag32_allocator.c \ ${NRFX_PATH}/drivers/src/nrfx_gpiote.c \ - ${NRFX_PATH}/drivers/src/nrfx_power.c \ ${NRFX_PATH}/drivers/src/nrfx_spim.c \ ${NRFX_PATH}/drivers/src/nrfx_uarte.c \ ${NRFX_PATH}/soc/nrfx_atomic.c +ifeq (,$(findstring OPT_MCU_NRF54,$(CFLAGS))) +SRC_C += ${NRFX_PATH}/drivers/src/nrfx_power.c +endif + INC += \ $(TOP)/$(BOARD_PATH) \ $(TOP)/$(FAMILY_PATH)/nrfx_config \ diff --git a/hw/bsp/nrf/linker/nrf54lm20a_enga_xxaa_application.ld b/hw/bsp/nrf/linker/nrf54lm20a_enga_xxaa_application.ld new file mode 100644 index 000000000..367cf6a89 --- /dev/null +++ b/hw/bsp/nrf/linker/nrf54lm20a_enga_xxaa_application.ld @@ -0,0 +1,13 @@ +/* Linker script to configure memory regions. */ + +SEARCH_DIR(.) +/*GROUP(-lgcc -lc) not compatible with clang*/ + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = 0x1FD000 /* Inside global RRAM0 */ + RAM (rwx) : ORIGIN = 0x20000000, LENGTH = 0x40000 + RAM1 (rwx) : ORIGIN = 0x20040000, LENGTH = 0x40000 +} + +INCLUDE "nrf_common.ld" diff --git a/hw/bsp/nrf/nrfx_config/nrfx_config_common.h b/hw/bsp/nrf/nrfx_config/nrfx_config_common.h index a5a29bb8e..02b7390e2 100644 --- a/hw/bsp/nrf/nrfx_config/nrfx_config_common.h +++ b/hw/bsp/nrf/nrfx_config/nrfx_config_common.h @@ -62,6 +62,9 @@ #if defined(NRF54H20_XXAA) #define NRFX_UARTE120_ENABLED 1 +#elif defined(NRF54LM20A_ENGA_XXAA) +#define NRFX_UARTE20_ENABLED 1 + #else #define NRFX_POWER_ENABLED 1 diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index b12a3177e..77a0bbf1d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -166,6 +166,7 @@ #define TUP_USBIP_DWC2 #define TUP_USBIP_DWC2_NRF #define TUP_DCD_ENDPOINT_MAX 16 + #define TUP_RHPORT_HIGHSPEED 1 #define CFG_TUH_DWC2_DMA_ENABLE_DEFAULT 0 //--------------------------------------------------------------------+ diff --git a/src/portable/synopsys/dwc2/dwc2_nrf.h b/src/portable/synopsys/dwc2/dwc2_nrf.h index 51f2d684f..067bf39cc 100644 --- a/src/portable/synopsys/dwc2/dwc2_nrf.h +++ b/src/portable/synopsys/dwc2/dwc2_nrf.h @@ -2,6 +2,7 @@ * The MIT License (MIT) * * Copyright (c) 2025 Ha Thach (tinyusb.org) + * Copyright (c) 2026, Gabriel Koppenstein * * Permission is hereby granted, free of charge, to any person obtaining a copy * of this software and associated documentation files (the "Software"), to deal @@ -30,14 +31,25 @@ #define DWC2_EP_MAX 16 +// Use the auto-resolving peripheral pointer (respects TrustZone secure/non-secure mapping) +#if defined(NRF54LM20A_ENGA_XXAA) + #define _DWC2_NRF_REG_BASE ((uintptr_t) NRF_USBHSCORE) +#else + #define _DWC2_NRF_REG_BASE ((uintptr_t) NRF_USBHSCORE0) +#endif + static const dwc2_controller_t _dwc2_controller[] = { - { .reg_base = NRF_USBHSCORE0_NS_BASE, .irqnum = USBHS_IRQn, .ep_count = 16, .ep_fifo_size = 12288 }, + { .reg_base = _DWC2_NRF_REG_BASE, .irqnum = USBHS_IRQn, .ep_count = 16, .ep_fifo_size = 12160 }, }; TU_ATTR_ALWAYS_INLINE static inline void dwc2_int_set(uint8_t rhport, tusb_role_t role, bool enabled) { (void) rhport; (void) role; - (void) enabled; + if (enabled) { + NVIC_EnableIRQ(USBHS_IRQn); + } else { + NVIC_DisableIRQ(USBHS_IRQn); + } } #define dwc2_dcd_int_enable(_rhport) dwc2_int_set(_rhport, TUSB_ROLE_DEVICE, true) @@ -64,4 +76,15 @@ TU_ATTR_ALWAYS_INLINE static inline void dwc2_phy_update(dwc2_regs_t* dwc2, uint (void)hs_phy_type; } +// nRF54 Cortex-M33 has no D-cache, provide no-op stubs for DMA mode +TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean(const void* addr, uint32_t data_size) { + (void)addr; (void)data_size; return true; +} +TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_invalidate(const void* addr, uint32_t data_size) { + (void)addr; (void)data_size; return true; +} +TU_ATTR_ALWAYS_INLINE static inline bool dwc2_dcache_clean_invalidate(const void* addr, uint32_t data_size) { + (void)addr; (void)data_size; return true; +} + #endif -- cgit v1.3.1 From c1e6b2635f9b89313dca86b31287176949c68380 Mon Sep 17 00:00:00 2001 From: StefanOroel <=> Date: Thu, 16 Apr 2026 10:40:42 +0200 Subject: fix(docs): update URL for STM32C071 Nucleo board documentation --- docs/reference/boards.rst | 2 +- hw/bsp/stm32c0/boards/stm32c071nucleo/board.h | 2 +- 2 files changed, 2 insertions(+), 2 deletions(-) (limited to 'docs') diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index dbb5942ca..e61c4f98b 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -265,7 +265,7 @@ STMicroelectronics =================== ================================= ========= ================================================================= ====== Board Name Family URL Note =================== ================================= ========= ================================================================= ====== -stm32c071nucleo STM32C071 Nucleo stm32c0 https://www.st.com/en/evaluation-tools/nucleo-g071rb.html +stm32c071nucleo STM32C071 Nucleo stm32c0 https://www.st.com/en/evaluation-tools/nucleo-c071rb.html stm32f070rbnucleo STM32 F070 Nucleo stm32f0 https://www.st.com/en/evaluation-tools/nucleo-f070rb.html stm32f072disco STM32 F072 Discovery stm32f0 https://www.st.com/en/evaluation-tools/32f072bdiscovery.html stm32f072eval STM32 F072 Eval stm32f0 https://www.st.com/en/evaluation-tools/stm32072b-eval.html diff --git a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h index 085d0d721..b62fc3a2a 100644 --- a/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h +++ b/hw/bsp/stm32c0/boards/stm32c071nucleo/board.h @@ -27,7 +27,7 @@ /* metadata: name: STM32C071 Nucleo - url: https://www.st.com/en/evaluation-tools/nucleo-g071rb.html + url: https://www.st.com/en/evaluation-tools/nucleo-c071rb.html */ #ifndef BOARD_H_ -- cgit v1.3.1 From 5ea1979e290ed80430a5b65b56534373ecbdd56f Mon Sep 17 00:00:00 2001 From: HiFiPHile Date: Sun, 10 May 2026 01:47:21 +0200 Subject: add stm32c5 support Signed-off-by: HiFiPHile --- .github/workflows/ci_set_matrix.py | 1 + README.rst | 2 +- docs/reference/boards.rst | 1 + docs/reference/dependencies.rst | 4 +- .../device/cdc_msc_throughput/CMakePresets.json | 6 + examples/device/printer_to_cdc/CMakePresets.json | 6 + examples/dual/dynamic_switch/only.txt | 1 + examples/host/bare_api/only.txt | 1 + examples/host/cdc_msc_hid/only.txt | 1 + examples/host/cdc_msc_hid_freertos/only.txt | 1 + examples/host/device_info/only.txt | 1 + examples/host/midi_rx/only.txt | 1 + examples/host/msc_file_explorer/only.txt | 1 + hw/bsp/BoardPresets.json | 22 + hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h | 165 +++++ hw/bsp/stm32c5/boards/stm32c542nucleo/board.cmake | 13 + hw/bsp/stm32c5/boards/stm32c542nucleo/board.h | 83 +++ hw/bsp/stm32c5/boards/stm32c542nucleo/board.mk | 13 + hw/bsp/stm32c5/family.c | 237 +++++++ hw/bsp/stm32c5/family.cmake | 111 ++++ hw/bsp/stm32c5/family.mk | 52 ++ hw/bsp/stm32c5/stm32c5xx_hal_conf.h | 684 +++++++++++++++++++++ src/common/tusb_mcu.h | 6 + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c | 1 + src/portable/st/stm32_fsdev/fsdev_stm32.h | 8 +- src/tusb_option.h | 1 + tools/get_deps.py | 8 +- 27 files changed, 1427 insertions(+), 4 deletions(-) create mode 100644 examples/device/cdc_msc_throughput/CMakePresets.json create mode 100644 examples/device/printer_to_cdc/CMakePresets.json create mode 100644 hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.cmake create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.h create mode 100644 hw/bsp/stm32c5/boards/stm32c542nucleo/board.mk create mode 100644 hw/bsp/stm32c5/family.c create mode 100644 hw/bsp/stm32c5/family.cmake create mode 100644 hw/bsp/stm32c5/family.mk create mode 100644 hw/bsp/stm32c5/stm32c5xx_hal_conf.h (limited to 'docs') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 1d35f15dd..f4d25fd37 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -68,6 +68,7 @@ family_list = { "samd5x_e5x": ["arm-gcc", "arm-clang"], "samg": ["arm-gcc", "arm-clang"], "stm32c0": ["arm-gcc", "arm-clang", "arm-iar"], + "stm32c5": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f0": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f1": ["arm-gcc", "arm-clang", "arm-iar"], "stm32f2": ["arm-gcc", "arm-clang", "arm-iar"], diff --git a/README.rst b/README.rst index 04998abaa..1c56a6ba0 100644 --- a/README.rst +++ b/README.rst @@ -238,7 +238,7 @@ Supported CPUs | +----+------------------------+--------+------+-----------+------------------------+--------------------+ | | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | +| | C0, C5, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | | +-----------------------------+--------+------+-----------+------------------------+--------------------+ | | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | | +----+------------------------+--------+------+-----------+------------------------+--------------------+ diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index e61c4f98b..b0e8bffaa 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -266,6 +266,7 @@ STMicroelectronics Board Name Family URL Note =================== ================================= ========= ================================================================= ====== stm32c071nucleo STM32C071 Nucleo stm32c0 https://www.st.com/en/evaluation-tools/nucleo-c071rb.html +stm32c542nucleo STM32C542 Nucleo stm32c5 https://www.st.com/en/evaluation-tools/nucleo-c542rc.html stm32f070rbnucleo STM32 F070 Nucleo stm32f0 https://www.st.com/en/evaluation-tools/nucleo-f070rb.html stm32f072disco STM32 F072 Discovery stm32f0 https://www.st.com/en/evaluation-tools/32f072bdiscovery.html stm32f072eval STM32 F072 Eval stm32f0 https://www.st.com/en/evaluation-tools/stm32072b-eval.html diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index c5b755577..d281e912a 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -59,6 +59,7 @@ hw/mcu/st/cmsis_device_l5 https://github.com/STMicroelectronics/ hw/mcu/st/cmsis_device_n6 https://github.com/STMicroelectronics/cmsis-device-n6.git 7bcdc944fbf7cf5928d3c1d14054ca13261d33ec stm32n6 hw/mcu/st/cmsis_device_u5 https://github.com/STMicroelectronics/cmsis_device_u5.git 6e67187dec98035893692ab2923914cb5f4e0117 stm32u5 hw/mcu/st/cmsis_device_wb https://github.com/STMicroelectronics/cmsis_device_wb.git cda2cb9fc4a5232ab18efece0bb06b0b60910083 stm32wb +hw/mcu/st/stm32c5xx-dfp https://github.com/STMicroelectronics/stm32c5xx-dfp.git 6d0940882511d9430f83af9bd3da6bcb77f79239 stm32c5 hw/mcu/st/stm32-mfxstm32l152 https://github.com/STMicroelectronics/stm32-mfxstm32l152.git 7f4389efee9c6a655b55e5df3fceef5586b35f9b stm32h7 hw/mcu/st/stm32-tcpp0203 https://github.com/STMicroelectronics/stm32-tcpp0203.git 9918655bff176ac3046ccf378b5c7bbbc6a38d15 stm32h5 stm32h7rs stm32n6 hw/mcu/st/stm32c0xx_hal_driver https://github.com/STMicroelectronics/stm32c0xx_hal_driver.git c283b143bef6bdaacf64240ee6f15eb61dad6125 stm32c0 @@ -82,13 +83,14 @@ hw/mcu/st/stm32u0xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/stm32u5xx_hal_driver.git 2c5e2568fbdb1900a13ca3b2901fdd302cac3444 stm32u5 hw/mcu/st/stm32wbaxx_hal_driver https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git 9442fbb71f855ff2e64fbf662b7726beba511a24 stm32wba hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git d60dd46996876506f1d2e9abd6b1cc110c8004cd stm32wb +hw/mcu/st/stm32c5xx-drivers https://github.com/STMicroelectronics/stm32c5xx-drivers.git 79b901285a7efeaf87c4c25db81d24cb5d8c9465 stm32c5 hw/mcu/ti https://github.com/hathach/ti_driver.git 083944907e7d08fcb1f614b47598ce45935b8da1 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x hw/mcu/wch/ch32v103 https://github.com/openwch/ch32v103.git 7578cae0b21f86dd053a1f781b2fc6ab99d0ec17 ch32v10x hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git c4c38f507e258a4e69b059ccc2dc27dde33cea1b ch32v20x hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 184f21b852cb95eed58e86e901837bc9fff68775 ch32v30x lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 2b7495b8535bdcb306dac29b9ded4cfb679d7e5c kinetis_k kinetis_kl lpc54 rw61x mm32 msp432e4 nrf samd2x_l2x lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 stm32c0 stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5 stm32h7 stm32h7rs stm32l0 stm32l1 stm32l4 stm32l5 stm32u0 stm32u5 stm32wb stm32wba sam3x samd11 samd21 samd51 samd5x_e5x same5x same7x samg tm4c -lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx +lib/CMSIS_6 https://github.com/ARM-software/CMSIS_6.git 6f0a58d01aa9bd2feba212097f9afe7acd991d52 imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx stm32c5 lib/FreeRTOS-Kernel https://github.com/FreeRTOS/FreeRTOS-Kernel.git cc0e0707c0c748713485b870bb980852b210877f all lib/lwip https://github.com/lwip-tcpip/lwip.git 159e31b689577dbf69cf0683bbaffbd71fa5ee10 all lib/sct_neopixel https://github.com/gsteiert/sct_neopixel.git e73e04ca63495672d955f9268e003cffe168fcd8 lpc55 diff --git a/examples/device/cdc_msc_throughput/CMakePresets.json b/examples/device/cdc_msc_throughput/CMakePresets.json new file mode 100644 index 000000000..5cd8971e9 --- /dev/null +++ b/examples/device/cdc_msc_throughput/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 6, + "include": [ + "../../../hw/bsp/BoardPresets.json" + ] +} diff --git a/examples/device/printer_to_cdc/CMakePresets.json b/examples/device/printer_to_cdc/CMakePresets.json new file mode 100644 index 000000000..5cd8971e9 --- /dev/null +++ b/examples/device/printer_to_cdc/CMakePresets.json @@ -0,0 +1,6 @@ +{ + "version": 6, + "include": [ + "../../../hw/bsp/BoardPresets.json" + ] +} diff --git a/examples/dual/dynamic_switch/only.txt b/examples/dual/dynamic_switch/only.txt index 70be49b28..e1038f9d4 100644 --- a/examples/dual/dynamic_switch/only.txt +++ b/examples/dual/dynamic_switch/only.txt @@ -2,6 +2,7 @@ family:espressif mcu:LPC43XX mcu:MIMXRT1XXX mcu:STM32C0 +mcu:STM32C5 mcu:STM32G0 mcu:STM32H5 mcu:STM32F2 diff --git a/examples/host/bare_api/only.txt b/examples/host/bare_api/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/bare_api/only.txt +++ b/examples/host/bare_api/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/cdc_msc_hid/only.txt b/examples/host/cdc_msc_hid/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/cdc_msc_hid/only.txt +++ b/examples/host/cdc_msc_hid/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/cdc_msc_hid_freertos/only.txt b/examples/host/cdc_msc_hid_freertos/only.txt index 753fa7cd3..4ab8a906e 100644 --- a/examples/host/cdc_msc_hid_freertos/only.txt +++ b/examples/host/cdc_msc_hid_freertos/only.txt @@ -16,6 +16,7 @@ mcu:MSP432E4 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/device_info/only.txt b/examples/host/device_info/only.txt index 742935dcf..4c2cb0f35 100644 --- a/examples/host/device_info/only.txt +++ b/examples/host/device_info/only.txt @@ -21,6 +21,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/midi_rx/only.txt b/examples/host/midi_rx/only.txt index c71aacd87..65ef8fac9 100644 --- a/examples/host/midi_rx/only.txt +++ b/examples/host/midi_rx/only.txt @@ -23,6 +23,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/examples/host/msc_file_explorer/only.txt b/examples/host/msc_file_explorer/only.txt index 1ddfc2b5c..a2ff93be5 100644 --- a/examples/host/msc_file_explorer/only.txt +++ b/examples/host/msc_file_explorer/only.txt @@ -20,6 +20,7 @@ mcu:RP2040 mcu:RW61X mcu:RX65X mcu:STM32C0 +mcu:STM32C5 mcu:STM32F4 mcu:STM32F7 mcu:STM32G0 diff --git a/hw/bsp/BoardPresets.json b/hw/bsp/BoardPresets.json index 86609d075..1ff29f99d 100644 --- a/hw/bsp/BoardPresets.json +++ b/hw/bsp/BoardPresets.json @@ -626,6 +626,10 @@ "name": "stm32c071nucleo", "inherits": "default" }, + { + "name": "stm32c542nucleo", + "inherits": "default" + }, { "name": "stm32f070rbnucleo", "inherits": "default" @@ -1762,6 +1766,11 @@ "description": "Build preset for the stm32c071nucleo board", "configurePreset": "stm32c071nucleo" }, + { + "name": "stm32c542nucleo", + "description": "Build preset for the stm32c542nucleo board", + "configurePreset": "stm32c542nucleo" + }, { "name": "stm32f070rbnucleo", "description": "Build preset for the stm32f070rbnucleo board", @@ -4227,6 +4236,19 @@ } ] }, + { + "name": "stm32c542nucleo", + "steps": [ + { + "type": "configure", + "name": "stm32c542nucleo" + }, + { + "type": "build", + "name": "stm32c542nucleo" + } + ] + }, { "name": "stm32f070rbnucleo", "steps": [ diff --git a/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h b/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h new file mode 100644 index 000000000..732d9a5cf --- /dev/null +++ b/hw/bsp/stm32c5/FreeRTOSConfig/FreeRTOSConfig.h @@ -0,0 +1,165 @@ +/* + * FreeRTOS Kernel V10.0.0 + * Copyright (C) 2017 Amazon.com, Inc. or its affiliates. All Rights Reserved. + * + * 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. If you wish to use our Amazon + * FreeRTOS name, please do so in a fair use way that does not cause confusion. + * + * 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. + * + * http://www.FreeRTOS.org + * http://aws.amazon.com/freertos + * + * 1 tab == 4 spaces! + */ + + +#ifndef FREERTOS_CONFIG_H +#define FREERTOS_CONFIG_H + +/*----------------------------------------------------------- + * Application specific definitions. + * + * These definitions should be adjusted for your particular hardware and + * application requirements. + * + * THESE PARAMETERS ARE DESCRIBED WITHIN THE 'CONFIGURATION' SECTION OF THE + * FreeRTOS API DOCUMENTATION AVAILABLE ON THE FreeRTOS.org WEB SITE. + * + * See http://www.freertos.org/a00110.html. + *----------------------------------------------------------*/ + +// skip if included from IAR assembler +#ifndef __IASMARM__ + #include "stm32c5xx.h" +#endif + +/* Cortex M23/M33 port configuration. */ +#define configENABLE_MPU 0 +#define configENABLE_FPU 1 +#define configENABLE_TRUSTZONE 0 +#define configMINIMAL_SECURE_STACK_SIZE (1024) + +#define configUSE_PREEMPTION 1 +#define configUSE_PORT_OPTIMISED_TASK_SELECTION 0 +#define configCPU_CLOCK_HZ SystemCoreClock +#define configTICK_RATE_HZ ( 1000 ) +#define configMAX_PRIORITIES ( 5 ) +#define configMINIMAL_STACK_SIZE ( 200 ) +#define configTOTAL_HEAP_SIZE ( configSUPPORT_DYNAMIC_ALLOCATION*4*1024 ) +#define configMAX_TASK_NAME_LEN 16 +#define configUSE_16_BIT_TICKS 0 +#define configIDLE_SHOULD_YIELD 1 +#define configUSE_MUTEXES 1 +#define configUSE_RECURSIVE_MUTEXES 1 +#define configUSE_COUNTING_SEMAPHORES 1 +#define configQUEUE_REGISTRY_SIZE 4 +#define configUSE_QUEUE_SETS 0 +#define configUSE_TIME_SLICING 0 +#define configUSE_NEWLIB_REENTRANT 0 +#define configENABLE_BACKWARD_COMPATIBILITY 1 +#define configSTACK_ALLOCATION_FROM_SEPARATE_HEAP 0 + +#define configSUPPORT_STATIC_ALLOCATION 1 +#define configSUPPORT_DYNAMIC_ALLOCATION 0 + +/* Hook function related definitions. */ +#define configUSE_IDLE_HOOK 0 +#define configUSE_TICK_HOOK 0 +#define configUSE_MALLOC_FAILED_HOOK 0 // cause nested extern warning +#define configCHECK_FOR_STACK_OVERFLOW 2 +#define configCHECK_HANDLER_INSTALLATION 0 + +/* Run time and task stats gathering related definitions. */ +#define configGENERATE_RUN_TIME_STATS 0 +#define configRECORD_STACK_HIGH_ADDRESS 1 +#define configUSE_TRACE_FACILITY 1 // legacy trace +#define configUSE_STATS_FORMATTING_FUNCTIONS 0 + +/* Co-routine definitions. */ +#define configUSE_CO_ROUTINES 0 +#define configMAX_CO_ROUTINE_PRIORITIES 2 + +/* Software timer related definitions. */ +#define configUSE_TIMERS 1 +#define configTIMER_TASK_PRIORITY (configMAX_PRIORITIES-2) +#define configTIMER_QUEUE_LENGTH 32 +#define configTIMER_TASK_STACK_DEPTH configMINIMAL_STACK_SIZE + +/* Optional functions - most linkers will remove unused functions anyway. */ +#define INCLUDE_vTaskPrioritySet 0 +#define INCLUDE_uxTaskPriorityGet 0 +#define INCLUDE_vTaskDelete 0 +#define INCLUDE_vTaskSuspend 1 // required for queue, semaphore, mutex to be blocked indefinitely with portMAX_DELAY +#define INCLUDE_xResumeFromISR 0 +#define INCLUDE_vTaskDelayUntil 1 +#define INCLUDE_vTaskDelay 1 +#define INCLUDE_xTaskGetSchedulerState 0 +#define INCLUDE_xTaskGetCurrentTaskHandle 1 +#define INCLUDE_uxTaskGetStackHighWaterMark 0 +#define INCLUDE_xTaskGetIdleTaskHandle 0 +#define INCLUDE_xTimerGetTimerDaemonTaskHandle 0 +#define INCLUDE_pcTaskGetTaskName 0 +#define INCLUDE_eTaskGetState 0 +#define INCLUDE_xEventGroupSetBitFromISR 0 +#define INCLUDE_xTimerPendFunctionCall 0 + +/* Define to trap errors during development. */ +// Halt CPU (breakpoint) when hitting error, only apply for Cortex M3, M4, M7 +#if defined(__ARM_ARCH_7M__) || defined (__ARM_ARCH_7EM__) || defined(__ARM_ARCH_8M_MAIN__) || defined(__ARM_ARCH_8_1M_MAIN__) || \ + defined(__ARM7M__) || defined (__ARM7EM__) || defined(__ARM8M_MAINLINE__) || defined(__ARM8EM_MAINLINE__) + #define configASSERT(_exp) \ + do {\ + if ( !(_exp) ) { \ + volatile uint32_t* ARM_CM_DHCSR = ((volatile uint32_t*) 0xE000EDF0UL); /* Cortex M CoreDebug->DHCSR */ \ + if ( (*ARM_CM_DHCSR) & 1UL ) { /* Only halt mcu if debugger is attached */ \ + taskDISABLE_INTERRUPTS(); \ + __asm("BKPT #0\n"); \ + }\ + }\ + } while(0) +#endif + +/* FreeRTOS hooks to NVIC vectors */ +#define xPortPendSVHandler PendSV_Handler +#define xPortSysTickHandler SysTick_Handler +#define vPortSVCHandler SVC_Handler + +//--------------------------------------------------------------------+ +// Interrupt nesting behavior configuration. +//--------------------------------------------------------------------+ + +// For Cortex-M specific: __NVIC_PRIO_BITS is defined in mcu header +#define configPRIO_BITS 4 + +/* The lowest interrupt priority that can be used in a call to a "set priority" function. */ +#define configLIBRARY_LOWEST_INTERRUPT_PRIORITY ((1<instance)) +#endif + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ +void USB_DRD_FS_IRQHandler(void) { + tusb_int_handler(0, true); +} + +//--------------------------------------------------------------------+ +// MACRO TYPEDEF CONSTANT ENUM +//--------------------------------------------------------------------+ +#ifdef UART_ID +static hal_uart_handle_t hUSART; +#endif + +void board_init(void) { + HAL_Init(); + board_clock_init(); + + // Enable peripheral clocks. + HAL_RCC_GPIOA_EnableClock(); + HAL_RCC_GPIOB_EnableClock(); + HAL_RCC_GPIOC_EnableClock(); + HAL_RCC_GPIOD_EnableClock(); + HAL_RCC_USB_EnableClock(); + +#if CFG_TUSB_OS == OPT_OS_NONE + // 1ms tick timer + SysTick_Config(SystemCoreClock / 1000); +#elif CFG_TUSB_OS == OPT_OS_FREERTOS + // Explicitly disable systick to prevent its ISR from running before scheduler start + SysTick->CTRL &= ~1U; + + // If freeRTOS is used, IRQ priority is limit by max syscall ( smaller is higher ) + NVIC_SetPriority(USB_DRD_FS_IRQn, configLIBRARY_MAX_SYSCALL_INTERRUPT_PRIORITY); +#endif + + // LED + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_OUTPUT; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.pull = HAL_GPIO_PULL_NO; + gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL; + gpio_config.init_state = HAL_GPIO_PIN_RESET; + + HAL_GPIO_Init(LED_PORT, LED_PIN, &gpio_config); + } + + // Button + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_INPUT; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.pull = BUTTON_STATE_ACTIVE ? HAL_GPIO_PULL_DOWN : HAL_GPIO_PULL_UP; + HAL_GPIO_Init(BUTTON_PORT, BUTTON_PIN, &gpio_config); + } + +#ifdef UART_ID + UARTn_CLK_ENABLE(); + // UART + { + hal_gpio_config_t gpio_config; + gpio_config.mode = HAL_GPIO_MODE_ALTERNATE; + gpio_config.output_type = HAL_GPIO_OUTPUT_PUSHPULL; + gpio_config.pull = HAL_GPIO_PULL_NO; + gpio_config.speed = HAL_GPIO_SPEED_FREQ_LOW; + gpio_config.alternate = UART_GPIO_AF; + HAL_GPIO_Init(UART_GPIO_PORT, UART_TX_PIN | UART_RX_PIN, &gpio_config); + } + + hal_uart_config_t uart_config; + HAL_UART_Init(&hUSART, UARTn); + uart_config.baud_rate = 115200; + uart_config.clock_prescaler = HAL_UART_PRESCALER_DIV1; + uart_config.word_length = HAL_UART_WORD_LENGTH_8_BIT; + uart_config.stop_bits = HAL_UART_STOP_BIT_1; + uart_config.parity = HAL_UART_PARITY_NONE; + uart_config.direction = HAL_UART_DIRECTION_TX_RX; + uart_config.hw_flow_ctl = HAL_UART_HW_CONTROL_NONE; + uart_config.oversampling = HAL_UART_OVERSAMPLING_16; + uart_config.one_bit_sampling = HAL_UART_ONE_BIT_SAMPLE_DISABLE; + + HAL_UART_SetConfig(&hUSART, &uart_config); + + /* Fifo configuration */ + HAL_UART_SetTxFifoThreshold(&hUSART, HAL_UART_FIFO_THRESHOLD_1_8); + HAL_UART_SetRxFifoThreshold(&hUSART, HAL_UART_FIFO_THRESHOLD_1_8); + HAL_UART_EnableFifoMode(&hUSART); + + LL_USART_Enable(UART_GET_INSTANCE(&hUSART)); +#endif +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { + hal_gpio_pin_state_t pin_state = state ? HAL_GPIO_PIN_SET : HAL_GPIO_PIN_RESET; + HAL_GPIO_WritePin(LED_PORT, LED_PIN, pin_state); +} + +uint32_t board_button_read(void) { + return BUTTON_STATE_ACTIVE == HAL_GPIO_ReadPin(BUTTON_PORT, BUTTON_PIN); +} + +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + (void) max_len; + volatile uint32_t * stm32_uuid = (volatile uint32_t *) UID_BASE; + uint32_t* id32 = (uint32_t*) (uintptr_t) id; + uint8_t const len = 12; + + id32[0] = stm32_uuid[0]; + id32[1] = stm32_uuid[1]; + id32[2] = stm32_uuid[2]; + + return len; +} + +int board_uart_read(uint8_t *buf, int len) { +#ifdef UART_ID + int count = 0; + while (count < len) { + if (LL_USART_IsActiveFlag_RXNE_RXFNE(UART_GET_INSTANCE(&hUSART))) { + buf[count] = (uint8_t) UART_GET_INSTANCE(&hUSART)->RDR; + count++; + } else { + break; + } + } + return count; +#else + (void) buf; (void) len; + return -1; +#endif +} + +int board_uart_write(void const *buf, int len) { +#ifdef UART_ID + const uint8_t *p = (const uint8_t *) buf; + int count = 0; + while (count < len) { + if (LL_USART_IsActiveFlag_TXE_TXFNF(UART_GET_INSTANCE(&hUSART))) { + UART_GET_INSTANCE(&hUSART)->TDR = p[count]; + count++; + } else { + break; + } + } + return count; +#else + (void) buf; (void) len; + return 0; +#endif +} + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +void SysTick_Handler(void) { + system_ticks++; + HAL_IncTick(); +} + +uint32_t tusb_time_millis_api(void) { + return system_ticks; +} +#endif + +void HardFault_Handler(void) { + __asm("BKPT #0\n"); +} + +#ifndef __ICCARM__ +// Implement _start() since we use linker flag '-nostartfiles'. +extern int main(void); +TU_ATTR_UNUSED void _start(void) { + // called by startup code + main(); + while (1) {} +} +#endif + +// Required by __libc_init_array in startup code if we are compiling using +// -nostdlib/-nostartfiles. +void _init(void) { + +} diff --git a/hw/bsp/stm32c5/family.cmake b/hw/bsp/stm32c5/family.cmake new file mode 100644 index 000000000..5b63b1ce4 --- /dev/null +++ b/hw/bsp/stm32c5/family.cmake @@ -0,0 +1,111 @@ +include_guard() + +set(ST_FAMILY c5) +set(ST_PREFIX stm32${ST_FAMILY}xx) + +set(ST_DRIVER ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx-drivers) +set(ST_CMSIS ${TOP}/hw/mcu/st/stm32${ST_FAMILY}xx-dfp) +set(CMSIS_6 ${TOP}/lib/CMSIS_6) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU cortex-m33 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/arm_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS STM32C5 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f interface/stlink.cfg -f target/stm32c5x.cfg") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +set(STARTUP_FILE ${ST_CMSIS}/Source/startup_${MCU_VARIANT}.c) +set(LD_FILE_Clang ${LD_FILE_GNU}) + +#------------------------------------ +# BOARD_TARGET +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${ST_CMSIS}/Source/Templates/system_${ST_PREFIX}.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_cortex.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_flash_itf.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_pwr.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_rcc.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_gpio.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_uart.c + ${ST_DRIVER}/hal/${ST_PREFIX}_hal_dma.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMSIS_6}/CMSIS/Core/Include + ${ST_CMSIS}/Include + ${ST_DRIVER}/hal + ${ST_DRIVER}/ll + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_options(${BOARD_TARGET} PUBLIC -Wno-redundant-decls) + endif () + + if(CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_compile_definitions(${BOARD_TARGET} PUBLIC + __STACK_LIMIT=__StackLimit + __INITIAL_SP=__StackTop + ) + endif () + + update_board(${BOARD_TARGET}) +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_STM32C5) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${TOP}/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c + ${TOP}/src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c + ${TOP}/src/portable/st/stm32_fsdev/fsdev_common.c + ${STARTUP_FILE} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_GNU}" + -nostartfiles + --specs=nosys.specs --specs=nano.specs + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + target_link_options(${TARGET} PUBLIC + "LINKER:--script=${LD_FILE_Clang}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "IAR") + target_link_options(${TARGET} PUBLIC + "LINKER:--config=${LD_FILE_IAR}" + ) + endif () + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU" OR CMAKE_C_COMPILER_ID STREQUAL "Clang") + set_source_files_properties(${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c PROPERTIES COMPILE_FLAGS "-Wno-missing-prototypes") + endif () + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_jlink(${TARGET}) + family_flash_stlink(${TARGET}) + #family_flash_openocd(${TARGET}) +endfunction() diff --git a/hw/bsp/stm32c5/family.mk b/hw/bsp/stm32c5/family.mk new file mode 100644 index 000000000..165ad4ad5 --- /dev/null +++ b/hw/bsp/stm32c5/family.mk @@ -0,0 +1,52 @@ +ST_FAMILY = c5 +ST_CMSIS = hw/mcu/st/stm32$(ST_FAMILY)xx-dfp +ST_DRIVER = hw/mcu/st/stm32$(ST_FAMILY)xx-drivers + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= cortex-m33 + +# -------------- +# Compiler Flags +# -------------- +CFLAGS += \ + -DCFG_TUSB_MCU=OPT_MCU_STM32C5 \ + +# GCC Flags +CFLAGS += \ + -flto \ + +# suppress warnings caused by vendor mcu driver +CFLAGS += -Wno-error=cast-align -Wno-error=unused-parameter -Wno-error=redundant-decls + +LDFLAGS += \ + -nostdlib -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +# ----------------- +# Sources & Include +# ----------------- + +SRC_C += \ + src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c \ + src/portable/st/stm32_fsdev/hcd_stm32_fsdev.c \ + src/portable/st/stm32_fsdev/fsdev_common.c \ + $(ST_CMSIS)/Source/Templates/system_stm32$(ST_FAMILY)xx.c \ + $(ST_CMSIS)/Source/startup_$(MCU_VARIANT).c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_cortex.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_flash_itf.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_pwr.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_rcc.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_gpio.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_uart.c \ + $(ST_DRIVER)/hal/stm32$(ST_FAMILY)xx_hal_dma.c + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/lib/CMSIS_6/CMSIS/Core/Include \ + $(TOP)/$(ST_CMSIS)/Include \ + $(TOP)/$(ST_DRIVER)/hal \ + $(TOP)/$(ST_DRIVER)/ll + +# flash target using on-board stlink +flash: flash-stlink diff --git a/hw/bsp/stm32c5/stm32c5xx_hal_conf.h b/hw/bsp/stm32c5/stm32c5xx_hal_conf.h new file mode 100644 index 000000000..0833fa3dd --- /dev/null +++ b/hw/bsp/stm32c5/stm32c5xx_hal_conf.h @@ -0,0 +1,684 @@ +/** + ****************************************************************************** + * @file stm32c5xx_hal_conf.h + * @brief HAL configuration file. + ****************************************************************************** + * @attention + * + * Copyright (c) 2026 STMicroelectronics. + * All rights reserved. + * + * This software is licensed under terms that can be found in the mx_stm32c5xx_hal_drivers_license.md file + * in the same directory as the generated code. + * If no mx_stm32c5xx_hal_drivers_license.md file comes with this software, it is provided AS-IS. + * + ****************************************************************************** + */ + +/* Define to prevent recursive inclusion -------------------------------------*/ +#ifndef STM32C5XX_HAL_CONF_H +#define STM32C5XX_HAL_CONF_H + +#ifdef __cplusplus +extern "C" { +#endif /* __cplusplus */ + +/* Exported types ------------------------------------------------------------*/ +/* Exported constants --------------------------------------------------------*/ + +/** @defgroup HAL_Conf_How_To_Use HAL Conf How to Use + * @{ + - The STM32 HAL configuration file, stm32tnxx_hal_conf.h, is designed to customize the behaviour of the HAL modules. + - The users can utilize the provided file as-is, where all HAL modules are enabled with their default settings. + - Alternatively, users have the flexibility to customize the file based on their application's requirements. + - For example, they can enable only the necessary HAL modules or modify the predefined settings to achieve + the desired functionality. + */ + +/** + * @} + */ + +/** @defgroup HAL_Conf_Exported_Constants HAL Conf Constants + * @{ + */ + +/** @defgroup HAL_System_Configuration HAL System Configuration + * @{ + */ + +/* ########################### System Configuration ############################# */ +/** + * @brief This is the HAL system configuration section + */ +#define USE_HAL_TICK_INT_PRIORITY 15U /*!< tick interrupt priority */ +#define USE_HAL_FLASH_PREFETCH 1U /*!< Enable FLASH prefetch */ +/** + * @} + */ + +/** @defgroup HAL_MUTEX_Usage_Activation HAL MUTEX Usage Activation + * @{ + */ +/* ########################## HAL MUTEX usage activation ####################### */ +/** + * @brief Used by the HAL PPP Acquire/Release APIs when the define USE_HAL_MUTEX is set to 1 + */ +#define USE_HAL_MUTEX 0U +/** + * @} + */ + +/** @defgroup HAL_API_Parameters_Check HAL API Parameters Check + * @{ + */ +/* ########################## HAL API parameters check ##################### */ +/** + * @brief Run time parameter check activation + */ +#define USE_HAL_CHECK_PARAM 0U +#define USE_HAL_SECURE_CHECK_PARAM 0U +/** + * @} + */ + +/** @defgroup HAL_State_Transition HAL State Transition + * @{ + */ +/* ########################## State transition ################################ */ +/** + * @brief Enable protection of state transition in thread safe + */ +#define USE_HAL_CHECK_PROCESS_STATE 0U +/** + * @} + */ + +/* ########################## Peripheral configuration ######################### */ + +/** @defgroup HAL_ADC_Config HAL ADC Configuration + * @{ + */ +/* ########################## HAL_ADC Config #################################### */ +#define USE_HAL_ADC_MODULE 0U +#define USE_HAL_ADC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_ADC_REGISTER_CALLBACKS 0U +#define USE_HAL_ADC_USER_DATA 0U +#define USE_HAL_ADC_GET_LAST_ERRORS 0U +#define USE_HAL_ADC_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_AES_Config HAL AES Configuration + * @{ + */ +/* ########################## HAL_AES Config #################################### */ +#define USE_HAL_AES_MODULE 0U +#define USE_HAL_AES_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_AES_REGISTER_CALLBACKS 0U +#define USE_HAL_AES_USER_DATA 0U +#define USE_HAL_AES_GET_LAST_ERRORS 0U +#define USE_HAL_AES_DMA 0U +#define USE_HAL_AES_ECB_CBC_ALGO 0U +#define USE_HAL_AES_CTR_ALGO 0U +#define USE_HAL_AES_GCM_GMAC_ALGO 0U +#define USE_HAL_AES_CCM_ALGO 0U +#define USE_HAL_AES_SUSPEND_RESUME 0U +/** + * @} + */ + +/** @defgroup HAL_CCB_Config HAL CCB Configuration + * @{ + */ +/* ########################## HAL_CCB Config #################################### */ +#define USE_HAL_CCB_MODULE 0U +#define USE_HAL_CCB_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CCB_USER_DATA 0U +#define USE_HAL_CCB_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_COMP_Config HAL COMP Configuration + * @{ + */ +/* ########################## HAL_COMP Config ################################### */ +#define USE_HAL_COMP_MODULE 0U +#define USE_HAL_COMP_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_COMP_REGISTER_CALLBACKS 0U +#define USE_HAL_COMP_USER_DATA 0U +/* Use comparator with EXTI (needed to generate system wake-up event and CPU event) */ +#define USE_HAL_COMP_EXTI 0U +/* Use comparators window mode feature */ +#define USE_HAL_COMP_WINDOW_MODE 0U +/** + * @} + */ + +/** @defgroup HAL_CORDIC_Config HAL CORDIC Configuration + * @{ + */ +/* ########################## HAL_CORDIC Config ################################# */ +#define USE_HAL_CORDIC_MODULE 0U +#define USE_HAL_CORDIC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CORDIC_REGISTER_CALLBACKS 0U +#define USE_HAL_CORDIC_USER_DATA 0U +#define USE_HAL_CORDIC_GET_LAST_ERRORS 0U +#define USE_HAL_CORDIC_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_CORTEX_Config HAL CORTEX Configuration + * @{ + */ +/* ########################## HAL_CORTEX Config ################################# */ +#define USE_HAL_CORTEX_MODULE 1U +/** + * @} + */ + +/** @defgroup HAL_CRC_Config HAL CRC Configuration + * @{ + */ +/* ########################## HAL_CRC Config #################################### */ +#define USE_HAL_CRC_MODULE 0U +#define USE_HAL_CRC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CRC_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_CRS_Config HAL CRS Configuration + * @{ + */ +/* ########################## HAL_CRS Config #################################### */ +#define USE_HAL_CRS_MODULE 0U +#define USE_HAL_CRS_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_CRS_REGISTER_CALLBACKS 0U +#define USE_HAL_CRS_USER_DATA 0U +#define USE_HAL_CRS_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_DAC_Config HAL DAC Configuration + * @{ + */ +/* ########################## HAL_DAC Config #################################### */ +#define USE_HAL_DAC_MODULE 0U +#define USE_HAL_DAC_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_DAC_REGISTER_CALLBACKS 0U +#define USE_HAL_DAC_USER_DATA 0U +#define USE_HAL_DAC_GET_LAST_ERRORS 0U +#define USE_HAL_DAC_DMA 0U +#define USE_HAL_DAC_DUAL_CHANNEL 0U +/** + * @} + */ + +/** @defgroup HAL_DBGMCU_Config HAL DBGMCU Configuration + * @{ + */ +/* ########################## HAL_DBGMCU Config ################################# */ +#define USE_HAL_DBGMCU_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_DMA_Config HAL DMA Configuration + * @{ + */ +/* ########################## HAL_DMA Config #################################### */ +#define USE_HAL_DMA_MODULE 1U +#define USE_HAL_DMA_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_DMA_USER_DATA 0U +#define USE_HAL_DMA_GET_LAST_ERRORS 0U +#define USE_HAL_DMA_LINKEDLIST 0U +/** + * @} + */ + +/** @defgroup HAL_ETH_Config HAL ETH Configuration + * @{ + */ +/* ########################## HAL_ETH Config #################################### */ +#define USE_HAL_ETH_MODULE 0U +#define USE_HAL_ETH_REGISTER_CALLBACKS 0U +#define USE_HAL_ETH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_ETH_USER_DATA 0U +#define USE_HAL_ETH_GET_LAST_ERRORS 0U +#define USE_HAL_ETH_ATOMIC_CHANNEL_LOCK 0U +#define USE_HAL_ETH_MAX_TX_CH_NB 1U +#define USE_HAL_ETH_MAX_RX_CH_NB 1U +/** + * @} + */ + +/** @defgroup HAL_EXTI_Config HAL EXTI Configuration + * @{ + */ +/* ########################## HAL_EXTI Config ################################### */ +#define USE_HAL_EXTI_MODULE 0U +#define USE_HAL_EXTI_REGISTER_CALLBACKS 0U +#define USE_HAL_EXTI_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_FDCAN_Config HAL FDCAN Configuration + * @{ + */ +/* ########################## HAL_FDCAN Config ################################## */ +#define USE_HAL_FDCAN_MODULE 0U +#define USE_HAL_FDCAN_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_FDCAN_REGISTER_CALLBACKS 0U +#define USE_HAL_FDCAN_USER_DATA 0U +#define USE_HAL_FDCAN_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_FLASH_Config HAL FLASH Configuration + * @{ + */ +/* ########################## HAL_FLASH Config ################################## */ +#define USE_HAL_FLASH_MODULE 1U +#define USE_HAL_FLASH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_FLASH_REGISTER_CALLBACKS 0U +#define USE_HAL_FLASH_USER_DATA 0U +#define USE_HAL_FLASH_GET_LAST_ERRORS 0U +/* Use the FLASH program by address feature */ +#define USE_HAL_FLASH_PROGRAM_BY_ADDR 0U +/* Use the FLASH erase by address feature */ +#define USE_HAL_FLASH_ERASE_BY_ADDR 0U +/* Use the FLASH erase by PAGE feature */ +#define USE_HAL_FLASH_ERASE_PAGE 0U +/* Use the FLASH bank erase feature */ +#define USE_HAL_FLASH_ERASE_BANK 0U +/* Use the FLASH mass erase feature */ +#define USE_HAL_FLASH_MASS_ERASE 0U +/* Use ECC errors handling APIs */ +#define USE_HAL_FLASH_ECC 0U +/* Use FLASH HAL API for EDATA */ +#define USE_HAL_FLASH_OB_EDATA 0U +/** + * @} + */ + +/** @defgroup HAL_GPIO_Config HAL GPIO Configuration + * @{ + */ +/* ########################## HAL_GPIO Config ################################### */ +#define USE_HAL_GPIO_MODULE 1U +#define USE_HAL_GPIO_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +/** + * @} + */ + +/** @defgroup HAL_HASH_Config HAL HASH Configuration + * @{ + */ +/* ########################## HAL_HASH Config ################################### */ +#define USE_HAL_HASH_MODULE 0U +#define USE_HAL_HASH_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_HASH_REGISTER_CALLBACKS 0U +#define USE_HAL_HASH_USER_DATA 0U +#define USE_HAL_HASH_GET_LAST_ERRORS 0U +#define USE_HAL_HASH_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_HCD_Config HAL HCD Configuration + * @{ + */ +/* ########################## HAL_HCD Config #################################### */ +#define USE_HAL_HCD_MODULE 0U +#define USE_HAL_HCD_REGISTER_CALLBACKS 0U +#define USE_HAL_HCD_USER_DATA 0U +#define USE_HAL_HCD_GET_LAST_ERRORS 0U +#define USE_HAL_HCD_USB_DOUBLE_BUFFER 0U +#define USE_HAL_HCD_USB_EP_TYPE_ISOC 0U +#define USE_HAL_HCD_MAX_CHANNEL_NB 16U +/** + * @} + */ + +/** @defgroup HAL_I2C_Config HAL I2C Configuration + * @{ + */ +/* ########################## HAL_I2C Config #################################### */ +#define USE_HAL_I2C_MODULE 0U +#define USE_HAL_I2C_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I2C_REGISTER_CALLBACKS 0U +#define USE_HAL_I2C_USER_DATA 0U +#define USE_HAL_I2C_GET_LAST_ERRORS 0U +#define USE_HAL_I2C_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_I3C_Config HAL I3C Configuration + * @{ + */ +/* ########################## HAL_I3C Config #################################### */ +#define USE_HAL_I3C_MODULE 0U +#define USE_HAL_I3C_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I3C_REGISTER_CALLBACKS 0U +#define USE_HAL_I3C_USER_DATA 0U +#define USE_HAL_I3C_GET_LAST_ERRORS 0U +#define USE_HAL_I3C_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_I2S_Config HAL I2S Configuration + * @{ + */ +/* ########################## HAL_I2S Config #################################### */ +#define USE_HAL_I2S_MODULE 0U +#define USE_HAL_I2S_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_I2S_REGISTER_CALLBACKS 0U +#define USE_HAL_I2S_USER_DATA 0U +#define USE_HAL_I2S_GET_LAST_ERRORS 0U +#define USE_HAL_I2S_OVR_UDR_ERRORS 0U +#define USE_HAL_I2S_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_ICACHE_Config HAL ICACHE Configuration + * @{ + */ +/* ########################## HAL_ICACHE Config ################################# */ +#define USE_HAL_ICACHE_MODULE 1U +#define USE_HAL_ICACHE_REGISTER_CALLBACKS 0U +#define USE_HAL_ICACHE_USER_DATA 0U +#define USE_HAL_ICACHE_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_IWDG_Config HAL IWDG Configuration + * @{ + */ +/* ########################## HAL_IWDG Config ################################### */ +#define USE_HAL_IWDG_MODULE 0U +#define USE_HAL_IWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_IWDG_USER_DATA 0U +/* IWDG time unit configuration */ +#define USE_HAL_IWDG_TIME_UNIT HAL_IWDG_TIME_UNIT_MS +/* IWDG hardware start configuration + warning: In case of starting IWDG in Hardware mode, make sure that + USE_HAL_IWDG_HARDWARE_START is aligned with OB activated set for IWDG */ +#define USE_HAL_IWDG_HARDWARE_START 0U +/* User can choose the value of the LSI frequency with the USE_HAL_IWDG_LSI_FREQ define: + - 0U : Dynamic LSI to be computed and set by the user. + - LSI_VALUE : LSI value of 32KHz. + - (LSI_VALUE / 128U): LSI value of 250Hz */ +#define USE_HAL_IWDG_LSI_FREQ LSI_VALUE +/** + * @} + */ + +/** @defgroup HAL_LPTIM_Config HAL LPTIM Configuration + * @{ + */ +/* ########################## HAL_LPTIM Config ################################## */ +#define USE_HAL_LPTIM_MODULE 0U +#define USE_HAL_LPTIM_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U +#define USE_HAL_LPTIM_USER_DATA 0U +#define USE_HAL_LPTIM_GET_LAST_ERRORS 0U +#define USE_HAL_LPTIM_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_OPAMP_Config HAL OPAMP Configuration + * @{ + */ +/* ########################## HAL_OPAMP Config ################################## */ +#define USE_HAL_OPAMP_MODULE 0U +#define USE_HAL_OPAMP_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_OPAMP_USER_DATA 0U +/** + * @} + */ + +/** @defgroup HAL_PCD_Config HAL PCD Configuration + * @{ + */ +/* ########################## HAL_PCD Config #################################### */ +#define USE_HAL_PCD_MODULE 1U +#define USE_HAL_PCD_REGISTER_CALLBACKS 0U +#define USE_HAL_PCD_USER_DATA 0U +#define USE_HAL_PCD_GET_LAST_ERRORS 0U +#define USE_HAL_PCD_USB_DOUBLE_BUFFER 0U +#define USE_HAL_PCD_USB_LPM 0U +#define USE_HAL_PCD_USB_BCD 0U +#define USE_HAL_PCD_USB_EP_TYPE_ISOC 0U +#define USE_HAL_PCD_MAX_ENDPOINT_NB 8U +/** + * @} + */ + +/** @defgroup HAL_PKA_Config HAL PKA Configuration + * @{ + */ +/* ########################## HAL_PKA Config #################################### */ +#define USE_HAL_PKA_MODULE 0U +#define USE_HAL_PKA_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_PKA_REGISTER_CALLBACKS 0U +#define USE_HAL_PKA_USER_DATA 0U +#define USE_HAL_PKA_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_PWR_Config HAL PWR Configuration + * @{ + */ +/* ########################## HAL_PWR Config #################################### */ +#define USE_HAL_PWR_MODULE 1U +/** + * @} + */ + +/** @defgroup HAL_RAMCFG_Config HAL RAMCFG Configuration + * @{ + */ +/* ########################## HAL_RAMCFG Config ################################# */ +#define USE_HAL_RAMCFG_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_RCC_Config HAL RCC Configuration + * @{ + */ +/* ########################## HAL_RCC Config #################################### */ +#define USE_HAL_RCC_MODULE 1U +/* Use RCC HAL API for Reset function */ +#define USE_HAL_RCC_RESET_PERIPH_CLOCK_MANAGEMENT 0U +#define USE_HAL_RCC_RESET_RTC_DOMAIN 0U +/** + * @} + */ + +/** @defgroup HAL_RNG_Config HAL RNG Configuration + * @{ + */ +/* ########################## HAL_RNG Config #################################### */ +#define USE_HAL_RNG_MODULE 0U +#define USE_HAL_RNG_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_RNG_REGISTER_CALLBACKS 0U +#define USE_HAL_RNG_USER_DATA 0U +#define USE_HAL_RNG_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_RTC_Config HAL RTC Configuration + * @{ + */ +/* ########################## HAL_RTC Config #################################### */ +#define USE_HAL_RTC_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_SBS_Config HAL SBS Configuration + * @{ + */ +/* ########################## HAL_SBS Config #################################### */ +#define USE_HAL_SBS_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_SMARTCARD_Config HAL SMARTCARD Configuration + * @{ + */ +/* ########################## HAL_SMARTCARD Config ############################## */ +#define USE_HAL_SMARTCARD_MODULE 0U +#define USE_HAL_SMARTCARD_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U +#define USE_HAL_SMARTCARD_USER_DATA 0U +#define USE_HAL_SMARTCARD_GET_LAST_ERRORS 0U +#define USE_HAL_SMARTCARD_DMA 0U +/* #################### SMARTCARD FIFO configuration ######################## */ +#define USE_HAL_SMARTCARD_FIFO 0U +/** + * @} + */ + +/** @defgroup HAL_SMBUS_Config HAL SMBUS Configuration + * @{ + */ +/* ########################## HAL_SMBUS Config ################################## */ +#define USE_HAL_SMBUS_MODULE 0U +#define USE_HAL_SMBUS_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U +#define USE_HAL_SMBUS_USER_DATA 0U +#define USE_HAL_SMBUS_GET_LAST_ERRORS 0U +/** + * @} + */ + +/** @defgroup HAL_SPI_Config HAL SPI Configuration + * @{ + */ +/* ########################## HAL_SPI Config #################################### */ +#define USE_HAL_SPI_MODULE 0U +#define USE_HAL_SPI_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_SPI_REGISTER_CALLBACKS 0U +#define USE_HAL_SPI_USER_DATA 0U +#define USE_HAL_SPI_GET_LAST_ERRORS 0U +#define USE_HAL_SPI_DMA 0U +/* 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_HAL_SPI_CRC 0U +/** + * @} + */ + +/** @defgroup HAL_TAMP_Config HAL TAMP Configuration + * @{ + */ +/* ########################## HAL_TAMP Config ################################### */ +#define USE_HAL_TAMP_MODULE 0U +/** + * @} + */ + +/** @defgroup HAL_TIM_Config HAL TIM Configuration + * @{ + */ +/* ########################## HAL_TIM Config #################################### */ +#define USE_HAL_TIM_MODULE 0U +#define USE_HAL_TIM_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_TIM_REGISTER_CALLBACKS 0U +#define USE_HAL_TIM_USER_DATA 0U +#define USE_HAL_TIM_GET_LAST_ERRORS 0U +#define USE_HAL_TIM_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_UART_Config HAL UART Configuration + * @{ + */ +/* ########################## HAL_UART Config ################################### */ +#define USE_HAL_UART_MODULE 1U +#define USE_HAL_UART_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_UART_REGISTER_CALLBACKS 0U +#define USE_HAL_UART_USER_DATA 0U +#define USE_HAL_UART_GET_LAST_ERRORS 0U +#define USE_HAL_UART_DMA 0U +/** + * @} + */ + +/** @defgroup HAL_USART_Config HAL USART Configuration + * @{ + */ +/* ########################## HAL_USART Config ################################## */ +#define USE_HAL_USART_MODULE 0U +#define USE_HAL_USART_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_USART_REGISTER_CALLBACKS 0U +#define USE_HAL_USART_USER_DATA 0U +#define USE_HAL_USART_GET_LAST_ERRORS 0U +#define USE_HAL_USART_DMA 0U +#define USE_HAL_USART_FIFO 0U +/** + * @} + */ + +/** @defgroup HAL_WWDG_Config HAL WWDG Configuration + * @{ + */ +/* ########################## HAL_WWDG Config ################################### */ +#define USE_HAL_WWDG_MODULE 0U +#define USE_HAL_WWDG_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U +#define USE_HAL_WWDG_USER_DATA 0U +/* WWDG time unit configuration */ +#define USE_HAL_WWDG_TIME_UNIT HAL_WWDG_TIME_UNIT_MS +/* WWDG hardware start configuration + warning: In case of starting WWDG in Hardware mode, make sure that + USE_HAL_WWDG_HARDWARE_START is aligned with OB activated set for WWDG */ +#define USE_HAL_WWDG_HARDWARE_START 0U +/** + * @} + */ + +/** @defgroup HAL_XSPI_Config HAL XSPI Configuration + * @{ + */ +/* ########################## HAL_XSPI Config ################################### */ +#define USE_HAL_XSPI_MODULE 0U +#define USE_HAL_XSPI_CLK_ENABLE_MODEL HAL_CLK_ENABLE_NO +#define USE_HAL_XSPI_REGISTER_CALLBACKS 0U +#define USE_HAL_XSPI_USER_DATA 0U +#define USE_HAL_XSPI_GET_LAST_ERRORS 0U +#define USE_HAL_XSPI_DMA 0U +#define USE_HAL_XSPI_HYPERBUS 0U +/** + * @} + */ + +/** + * @} + */ + +#ifdef __cplusplus +} +#endif /* __cplusplus */ + +#endif /* STM32C5XX_HAL_CONF_H */ diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index c85ade4d0..cd9b3dc27 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -206,6 +206,12 @@ #define TUP_USBIP_FSDEV_DRD #define CFG_TUSB_FSDEV_PMA_SIZE 2048u +#elif TU_CHECK_MCU(OPT_MCU_STM32C5) + #define TUP_USBIP_FSDEV + #define TUP_USBIP_FSDEV_STM32 + #define TUP_USBIP_FSDEV_DRD + #define CFG_TUSB_FSDEV_PMA_SIZE 2048u + #elif TU_CHECK_MCU(OPT_MCU_STM32F0) #define TUP_USBIP_FSDEV #define TUP_USBIP_FSDEV_STM32 diff --git a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c index 41da3ddd0..4dfd04fb4 100644 --- a/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c +++ b/src/portable/st/stm32_fsdev/dcd_stm32_fsdev.c @@ -41,6 +41,7 @@ * F302xB/C, F303xB/C, F373 512 byte buffer; no internal D+ pull-up * F302x6/8, F302xD/E2, F303xD/E 1024 byte buffer; no internal D+ pull-up * C0 2048 byte buffer; 32-bit bus; host mode + * C5 2048 byte buffer; 32-bit bus; host mode * G0 2048 byte buffer; 32-bit bus; host mode * G4 1024 byte buffer * H5 2048 byte buffer; 32-bit bus; host mode diff --git a/src/portable/st/stm32_fsdev/fsdev_stm32.h b/src/portable/st/stm32_fsdev/fsdev_stm32.h index 070aa00ec..74cc9d0a4 100644 --- a/src/portable/st/stm32_fsdev/fsdev_stm32.h +++ b/src/portable/st/stm32_fsdev/fsdev_stm32.h @@ -36,6 +36,10 @@ #include "stm32c0xx.h" #define FSDEV_HAS_SBUF_ISO 1 +#elif CFG_TUSB_MCU == OPT_MCU_STM32C5 + #include "stm32c5xx.h" + #define FSDEV_HAS_SBUF_ISO 1 + #elif CFG_TUSB_MCU == OPT_MCU_STM32F0 #include "stm32f0xx.h" #define FSDEV_HAS_SBUF_ISO 0 @@ -177,7 +181,7 @@ static const IRQn_Type fsdev_irq[] = { USB_IRQn, #elif TU_CHECK_MCU(OPT_MCU_STM32L5, OPT_MCU_STM32U3) USB_FS_IRQn, - #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32H5, OPT_MCU_STM32U0) + #elif TU_CHECK_MCU(OPT_MCU_STM32C0, OPT_MCU_STM32C5, OPT_MCU_STM32H5, OPT_MCU_STM32U0) USB_DRD_FS_IRQn, #elif CFG_TUSB_MCU == OPT_MCU_STM32G0 #ifdef STM32G0B0xx @@ -276,6 +280,8 @@ TU_ATTR_ALWAYS_INLINE static inline void fsdev_int_disable(uint8_t rhport) { #define FSDEV_STM32_CPU_MHZ 64U #elif CFG_TUSB_MCU == OPT_MCU_STM32C0 #define FSDEV_STM32_CPU_MHZ 48U +#elif CFG_TUSB_MCU == OPT_MCU_STM32C5 + #define FSDEV_STM32_CPU_MHZ 144U #endif #ifndef CFG_TUSB_FSDEV_BTABLE_FS_DELAY_COUNT diff --git a/src/tusb_option.h b/src/tusb_option.h index 154f8e2a4..83b6d3e51 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -98,6 +98,7 @@ #define OPT_MCU_STM32N6 319 ///< ST N6 #define OPT_MCU_STM32WBA 320 ///< ST WBA #define OPT_MCU_STM32U3 321 ///< ST U3 +#define OPT_MCU_STM32C5 322 ///< ST C5 // Sony #define OPT_MCU_CXD56 400 ///< SONY CXD56 diff --git a/tools/get_deps.py b/tools/get_deps.py index eb87abf6e..50497fc71 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -163,6 +163,9 @@ deps_optional = { 'hw/mcu/st/cmsis-device-wba': ['https://github.com/STMicroelectronics/cmsis-device-wba.git', '647d8522e5fd15049e9a1cc30ed19d85e5911eaf', 'stm32wba'], + 'hw/mcu/st/stm32c5xx-dfp': ['https://github.com/STMicroelectronics/stm32c5xx-dfp.git', + '6d0940882511d9430f83af9bd3da6bcb77f79239', + 'stm32c5'], 'hw/mcu/st/stm32-mfxstm32l152': ['https://github.com/STMicroelectronics/stm32-mfxstm32l152.git', '7f4389efee9c6a655b55e5df3fceef5586b35f9b', 'stm32h7'], @@ -232,6 +235,9 @@ deps_optional = { 'hw/mcu/st/stm32wbaxx_hal_driver': ['https://github.com/STMicroelectronics/stm32wbaxx_hal_driver.git', '9442fbb71f855ff2e64fbf662b7726beba511a24', 'stm32wba'], + 'hw/mcu/st/stm32c5xx-drivers': ['https://github.com/STMicroelectronics/stm32c5xx-drivers.git', + '79b901285a7efeaf87c4c25db81d24cb5d8c9465', + 'stm32c5'], 'hw/mcu/ti': ['https://github.com/hathach/ti_driver.git', '083944907e7d08fcb1f614b47598ce45935b8da1', 'msp430 msp432e4 tm4c'], @@ -284,7 +290,7 @@ deps_optional = { 'tm4c '], 'lib/CMSIS_6': ['https://github.com/ARM-software/CMSIS_6.git', '6f0a58d01aa9bd2feba212097f9afe7acd991d52', - 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx'], + 'imxrt kinetis_k32l ra stm32n6 lpc51 lpc55 mcx stm32c5'], 'lib/sct_neopixel': ['https://github.com/gsteiert/sct_neopixel.git', 'e73e04ca63495672d955f9268e003cffe168fcd8', 'lpc55'], -- cgit v1.3.1 From 77cef83304c92402a133fc936c44d182fc99ecf0 Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Tue, 24 Mar 2026 23:38:14 -0300 Subject: test: add MIDI 2.0 Device and Host unit tests Add unit tests for MIDI 2.0 drivers: - Device: UMP word count (all 16 message types), descriptor macro validation (length, byte layout, alt settings, endpoints), CS endpoint subtypes, traversal integrity - Host: UMP word count, callback struct validation, CS endpoint subtypes Also add Sphinx documentation for MIDI 2.0 class drivers (Device and Host API reference, lifecycle, configuration, examples). Tests: 60/60 PASS (FIFO 26/26, USBD 5/5, MIDI2 Device 18/18, MIDI2 Host 6/6, USBD internal 5/5) --- docs/reference/class_drivers.rst | 316 +++++++++++++++++++++ docs/reference/index.rst | 1 + .../test/device/midi2/test_midi2_device.c | 263 +++++++++++++++++ test/unit-test/test/host/midi2/test_midi2_host.c | 101 +++++++ 4 files changed, 681 insertions(+) create mode 100644 docs/reference/class_drivers.rst create mode 100644 test/unit-test/test/device/midi2/test_midi2_device.c create mode 100644 test/unit-test/test/host/midi2/test_midi2_host.c (limited to 'docs') diff --git a/docs/reference/class_drivers.rst b/docs/reference/class_drivers.rst new file mode 100644 index 000000000..9ed332acb --- /dev/null +++ b/docs/reference/class_drivers.rst @@ -0,0 +1,316 @@ +*************** +Class Drivers +*************** + +USB Class Drivers implement specific USB device classes (CDC, HID, MSC, MIDI, Audio, etc.) and are the main interface between the USB core and application code. + +MIDI 2.0 Device Driver +======================= + +Overview +-------- + +The MIDI 2.0 Device driver enables TinyUSB to act as a USB MIDI 2.0 device. It implements both Alt Setting 0 (MIDI 1.0 fallback) and Alt Setting 1 (native UMP) as required by the USB-MIDI 2.0 specification. + +**Key Features:** + +- **Dual Alt Settings**: Alt 0 (MIDI 1.0) and Alt 1 (UMP native) per USB-MIDI 2.0 spec +- **Protocol Negotiation**: Endpoint Discovery, Config Request/Notify, Function Block Discovery +- **Group Terminal Block**: Served via GET_DESCRIPTOR automatically +- **Atomic UMP Framing**: Read/write with correct message boundaries +- **Memory Safe**: No dynamic allocation, static instances + +Configuration +------------- + +Enable MIDI 2.0 Device support in ``tusb_config.h``: + +.. code-block:: c + + #define CFG_TUD_ENABLED 1 + #define CFG_TUD_MIDI2 1 + +Optional configuration: + +.. code-block:: c + + #define CFG_TUD_MIDI2_TX_BUFSIZE 256 + #define CFG_TUD_MIDI2_RX_BUFSIZE 256 + #define CFG_TUD_MIDI2_TX_EPSIZE 64 + #define CFG_TUD_MIDI2_RX_EPSIZE 64 + #define CFG_TUD_MIDI2_NUM_GROUPS 1 // 1..16 + #define CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS 1 // 1..32 + #define CFG_TUD_MIDI2_EP_NAME "TinyUSB MIDI 2.0" + #define CFG_TUD_MIDI2_PRODUCT_ID "TinyUSB-MIDI2" + +Public API +---------- + +Query Functions +^^^^^^^^^^^^^^^ + +.. code-block:: c + + bool tud_midi2_mounted(void); + uint32_t tud_midi2_available(void); + uint8_t tud_midi2_alt_setting(void); + bool tud_midi2_negotiated(void); + uint8_t tud_midi2_protocol(void); + +I/O Functions +^^^^^^^^^^^^^ + +.. code-block:: c + + uint32_t tud_midi2_ump_read(uint32_t* words, uint32_t max_words); + uint32_t tud_midi2_ump_write(const uint32_t* words, uint32_t count); + bool tud_midi2_packet_read(uint8_t packet[4]); + bool tud_midi2_packet_write(const uint8_t packet[4]); + +Callbacks +^^^^^^^^^ + +.. code-block:: c + + void tud_midi2_rx_cb(uint8_t itf); + void tud_midi2_set_itf_cb(uint8_t itf, uint8_t alt); + bool tud_midi2_get_req_itf_cb(uint8_t rhport, const tusb_control_request_t* request); + +MIDI 2.0 Host Driver +===================== + +Overview +-------- + +The MIDI 2.0 Host driver enables TinyUSB to enumerate and communicate with USB MIDI 2.0 devices. It implements the USB MIDI 2.0 specification, supporting both MIDI 1.0 legacy devices and modern MIDI 2.0 devices with UMP (Universal MIDI Packet) protocol. + +**Key Features:** + +- **Reactive Architecture**: Auto-detects Alt Setting 1 (MIDI 2.0) capability during enumeration +- **Auto-Selection**: Automatically selects the highest available protocol (MIDI 2.0 preferred) +- **Transparent Stream Messages**: All data (UMP packets + Stream Messages) flow through callbacks +- **Memory Safe**: No dynamic allocation, fixed-size instances per device + +Configuration +------------- + +Enable MIDI 2.0 Host support in ``tusb_config.h``: + +.. code-block:: c + + #define CFG_TUH_ENABLED 1 + #define CFG_TUH_MIDI2 4 // Number of MIDI 2.0 devices to support + +Optional buffer configuration: + +.. code-block:: c + + #define CFG_TUH_MIDI2_RX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) + #define CFG_TUH_MIDI2_TX_BUFSIZE (4 * TUH_EPSIZE_BULK_MAX) + +Enumeration Lifecycle +--------------------- + +When a MIDI 2.0 device is connected, the host stack invokes callbacks in this order: + +.. code-block:: none + + Device Connected + | + [Host detects Alt 0 and Alt 1 descriptors] + | + tuh_midi2_descriptor_cb() <- Device detected, NOT yet ready + | + [Auto-select highest protocol] + | + tuh_midi2_mount_cb() <- Device ready to use + | + [Application can read/write data] + | + tuh_midi2_rx_cb() <- Data arrived + tuh_midi2_tx_cb() <- TX buffer space available + | + [Device disconnects] + | + tuh_midi2_umount_cb() <- Device removed + +Public API +---------- + +Query Functions +^^^^^^^^^^^^^^^ + +.. code-block:: c + + bool tuh_midi2_mounted(uint8_t idx); + uint8_t tuh_midi2_get_protocol_version(uint8_t idx); // 0=MIDI 1.0, 1=MIDI 2.0 + uint8_t tuh_midi2_get_alt_setting_active(uint8_t idx); // 0 or 1 + uint8_t tuh_midi2_get_cable_count(uint8_t idx); + +I/O Functions +^^^^^^^^^^^^^ + +Read and write UMP (Universal MIDI Packet) data: + +.. code-block:: c + + uint32_t tuh_midi2_ump_read(uint8_t idx, uint32_t* words, uint32_t max_words); + uint32_t tuh_midi2_ump_write(uint8_t idx, const uint32_t* words, uint32_t count); + uint32_t tuh_midi2_write_flush(uint8_t idx); + +Callbacks +--------- + +Application can define weak callback implementations to respond to device events. + +Descriptor Callback +^^^^^^^^^^^^^^^^^^^ + +Invoked when device is detected but not yet ready for I/O: + +.. code-block:: c + + void tuh_midi2_descriptor_cb(uint8_t idx, const tuh_midi2_descriptor_cb_t *desc_cb_data) { + printf("MIDI %s device detected\r\n", + desc_cb_data->protocol_version == 0 ? "1.0" : "2.0"); + } + +Mount Callback +^^^^^^^^^^^^^^ + +Invoked when device is ready for I/O: + +.. code-block:: c + + void tuh_midi2_mount_cb(uint8_t idx, const tuh_midi2_mount_cb_t *mount_cb_data) { + printf("Device mounted at idx=%u, protocol=%u, alt_setting=%u\r\n", + idx, mount_cb_data->protocol_version, mount_cb_data->alt_setting_active); + } + +RX Callback +^^^^^^^^^^^ + +Invoked when data arrives from device (both UMP packets and Stream Messages): + +.. code-block:: c + + void tuh_midi2_rx_cb(uint8_t idx, uint32_t xferred_bytes) { + uint32_t words[4]; + uint32_t n = tuh_midi2_ump_read(idx, words, 4); + + for (uint32_t i = 0; i < n; i++) { + uint8_t mt = (words[i] >> 28) & 0x0F; + if (mt == 0x0F) { + // Stream Message - app handles discovery, negotiation, etc. + } else { + // Regular MIDI UMP packet + } + } + } + +TX Callback +^^^^^^^^^^^ + +Invoked when TX buffer space becomes available: + +.. code-block:: c + + void tuh_midi2_tx_cb(uint8_t idx, uint32_t xferred_bytes) { + // Buffer space available for writing + } + +Unmount Callback +^^^^^^^^^^^^^^^^ + +Invoked when device is disconnected: + +.. code-block:: c + + void tuh_midi2_umount_cb(uint8_t idx) { + printf("Device at idx=%u disconnected\r\n", idx); + } + +Complete Example +---------------- + +.. code-block:: c + + #include "tusb.h" + + void tuh_midi2_mount_cb(uint8_t idx, const tuh_midi2_mount_cb_t *mount_cb_data) { + printf("MIDI 2.0 device mounted\r\n"); + } + + void tuh_midi2_rx_cb(uint8_t idx, uint32_t xferred_bytes) { + uint32_t words[4]; + uint32_t n = tuh_midi2_ump_read(idx, words, 4); + + for (uint32_t i = 0; i < n; i++) { + printf("RX: 0x%08lx\r\n", words[i]); + } + } + + void tuh_midi2_umount_cb(uint8_t idx) { + printf("MIDI 2.0 device disconnected\r\n"); + } + + int main(void) { + board_init(); + + tusb_rhport_init_t host_init = {.role = TUSB_ROLE_HOST, .speed = TUSB_SPEED_AUTO}; + tusb_init(BOARD_TUH_RHPORT, &host_init); + + while (1) { + tuh_task(); + } + } + +Architecture +------------ + +The MIDI 2.0 Host driver uses a **reactive, callback-driven architecture** that mirrors the proven patterns in TinyUSB's existing device drivers (CDC, HID, etc.): + +- **Auto-Detection**: Host automatically detects Alt Setting 1 capability +- **Auto-Selection**: Selects highest protocol available (MIDI 2.0 preferred) +- **Application Control**: App makes protocol behavior decisions via callbacks +- **Transparent I/O**: Stream Messages and UMP packets flow transparently + +Differences from MIDI 1.0 Host +^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ + +.. list-table:: + :header-rows: 1 + + * - Aspect + - MIDI 1.0 Host + - MIDI 2.0 Host + * - Alt Settings + - Parses only Alt 0 + - Parses Alt 0 + Alt 1 + * - Data Format + - 4-byte MIDI packets + - UMP (32/64/128-bit) + * - Version Detection + - None + - bcdMSC from descriptor + * - GTB + - N/A + - Presence detection + * - Stream Messages + - N/A + - Transparent passthrough + * - Callbacks + - descriptor_cb, mount_cb, rx_cb, umount_cb + - descriptor_cb, mount_cb, rx_cb, tx_cb, umount_cb + * - Public API + - tuh_midi_* + - tuh_midi2_* + +Implementation Notes +-------------------- + +- All internal state is statically allocated (no dynamic allocation) +- Endpoint streams use TinyUSB's tu_edpt_stream_t for buffered I/O +- Protocol version detection via bcdMSC field +- Alt Setting is automatically selected during mount +- Compatible with all TinyUSB-supported MCU families diff --git a/docs/reference/index.rst b/docs/reference/index.rst index d3c96eeee..148e8a63b 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -9,6 +9,7 @@ Complete reference documentation for TinyUSB APIs, configuration, and supported architecture usb_concepts + class_drivers boards dependencies concurrency diff --git a/test/unit-test/test/device/midi2/test_midi2_device.c b/test/unit-test/test/device/midi2/test_midi2_device.c new file mode 100644 index 000000000..9d716d93b --- /dev/null +++ b/test/unit-test/test/device/midi2/test_midi2_device.c @@ -0,0 +1,263 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * 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. + */ + +#include "unity.h" +#include "tusb_types.h" +#include "class/audio/audio.h" +#include "class/midi/midi.h" +#include "device/usbd.h" + +void setUp(void) {} +void tearDown(void) {} + +//--------------------------------------------------------------------+ +// UMP Word Count: all 16 message types +//--------------------------------------------------------------------+ + +void test_ump_word_count_1word_types(void) { + uint8_t types[] = {0x0, 0x1, 0x2, 0x6, 0x7}; + for (int i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(1, midi2_ump_word_count(types[i])); + } +} + +void test_ump_word_count_2word_types(void) { + uint8_t types[] = {0x3, 0x4, 0x8, 0x9, 0xA}; + for (int i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(2, midi2_ump_word_count(types[i])); + } +} + +void test_ump_word_count_3word_types(void) { + TEST_ASSERT_EQUAL(3, midi2_ump_word_count(0xB)); + TEST_ASSERT_EQUAL(3, midi2_ump_word_count(0xC)); +} + +void test_ump_word_count_4word_types(void) { + uint8_t types[] = {0x5, 0xD, 0xE, 0xF}; + for (int i = 0; i < 4; i++) { + TEST_ASSERT_EQUAL(4, midi2_ump_word_count(types[i])); + } +} + +void test_ump_word_count_covers_all_16(void) { + for (uint8_t mt = 0; mt <= 0xF; mt++) { + uint8_t wc = midi2_ump_word_count(mt); + TEST_ASSERT_TRUE(wc >= 1 && wc <= 4); + } +} + +//--------------------------------------------------------------------+ +// CS Endpoint subtypes (defined in midi.h) +//--------------------------------------------------------------------+ + +void test_cs_endpoint_subtypes(void) { + TEST_ASSERT_EQUAL(0x01, MIDI_CS_ENDPOINT_GENERAL); + TEST_ASSERT_EQUAL(0x02, MIDI_CS_ENDPOINT_GENERAL_2_0); +} + +//--------------------------------------------------------------------+ +// Descriptor macro length calculations +//--------------------------------------------------------------------+ + +void test_midi1_desc_len(void) { + TEST_ASSERT_EQUAL(TUD_MIDI_DESC_HEAD_LEN + TUD_MIDI_DESC_JACK_LEN + TUD_MIDI_DESC_EP_LEN(1) * 2, + TUD_MIDI_DESC_LEN); +} + +void test_midi2_alt1_head_len(void) { + TEST_ASSERT_EQUAL(16, TUD_MIDI2_DESC_ALT1_HEAD_LEN); +} + +void test_midi2_alt1_ep_len(void) { + // EP(7) + CS base(4) + numgtbs + TEST_ASSERT_EQUAL(12, TUD_MIDI2_DESC_ALT1_EP_LEN(1)); + TEST_ASSERT_EQUAL(13, TUD_MIDI2_DESC_ALT1_EP_LEN(2)); + TEST_ASSERT_EQUAL(18, TUD_MIDI2_DESC_ALT1_EP_LEN(7)); +} + +void test_midi2_desc_len(void) { + int expected = TUD_MIDI_DESC_LEN + TUD_MIDI2_DESC_ALT1_HEAD_LEN + TUD_MIDI2_DESC_ALT1_EP_LEN(1) * 2; + TEST_ASSERT_EQUAL(expected, TUD_MIDI2_DESC_LEN); +} + +void test_midi2_desc_len_greater_than_midi1(void) { + TEST_ASSERT_TRUE(TUD_MIDI2_DESC_LEN > TUD_MIDI_DESC_LEN); +} + +//--------------------------------------------------------------------+ +// Descriptor macro byte validation +//--------------------------------------------------------------------+ + +void test_midi2_descriptor_bytes(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x01, 0x81, 64) }; + + TEST_ASSERT_EQUAL(TUD_MIDI2_DESC_LEN, sizeof(desc)); + + // First byte: Audio Control Interface descriptor length = 9 + TEST_ASSERT_EQUAL(9, desc[0]); + TEST_ASSERT_EQUAL(TUSB_DESC_INTERFACE, desc[1]); + TEST_ASSERT_EQUAL(0, desc[2]); + + // Find Alt Setting 1 by scanning + int alt1_offset = -1; + int pos = 0; + while (pos < (int)sizeof(desc)) { + if (desc[pos + 1] == TUSB_DESC_INTERFACE && desc[pos + 3] == 1) { + alt1_offset = pos; + break; + } + pos += desc[pos]; + } + + TEST_ASSERT_TRUE_MESSAGE(alt1_offset >= 0, "Alt Setting 1 interface not found"); + + TEST_ASSERT_EQUAL(9, desc[alt1_offset]); + TEST_ASSERT_EQUAL(TUSB_DESC_INTERFACE, desc[alt1_offset + 1]); + TEST_ASSERT_EQUAL(1, desc[alt1_offset + 2]); // bInterfaceNumber + TEST_ASSERT_EQUAL(1, desc[alt1_offset + 3]); // bAlternateSetting + TEST_ASSERT_EQUAL(2, desc[alt1_offset + 4]); // bNumEndpoints + TEST_ASSERT_EQUAL(TUSB_CLASS_AUDIO, desc[alt1_offset + 5]); + + // MS Header after Alt Setting 1 interface: bcdMSC = 0x0200 + int ms2_offset = alt1_offset + 9; + TEST_ASSERT_EQUAL(7, desc[ms2_offset]); + TEST_ASSERT_EQUAL(TUSB_DESC_CS_INTERFACE, desc[ms2_offset + 1]); + TEST_ASSERT_EQUAL(MIDI_CS_INTERFACE_HEADER, desc[ms2_offset + 2]); + TEST_ASSERT_EQUAL(0x00, desc[ms2_offset + 3]); + TEST_ASSERT_EQUAL(0x02, desc[ms2_offset + 4]); +} + +void test_midi2_descriptor_alt1_cs_endpoint_subtype(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x01, 0x81, 64) }; + + int cs_ep_count = 0; + int pos = 0; + while (pos < (int)sizeof(desc)) { + if (desc[pos + 1] == TUSB_DESC_CS_ENDPOINT && + desc[pos + 2] == MIDI_CS_ENDPOINT_GENERAL_2_0) { + cs_ep_count++; + TEST_ASSERT_EQUAL(1, desc[pos + 3]); + } + pos += desc[pos]; + } + TEST_ASSERT_EQUAL(2, cs_ep_count); +} + +void test_midi2_descriptor_has_both_alt_settings(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x01, 0x81, 64) }; + + int alt0_count = 0; + int alt1_count = 0; + int pos = 0; + while (pos < (int)sizeof(desc)) { + if (desc[pos + 1] == TUSB_DESC_INTERFACE) { + if (desc[pos + 3] == 0) alt0_count++; + if (desc[pos + 3] == 1) alt1_count++; + } + pos += desc[pos]; + } + TEST_ASSERT_TRUE(alt0_count >= 2); + TEST_ASSERT_EQUAL(1, alt1_count); +} + +void test_midi2_descriptor_endpoint_addresses(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x02, 0x82, 64) }; + + int ep_out_count = 0; + int ep_in_count = 0; + int pos = 0; + while (pos < (int)sizeof(desc)) { + if (desc[pos + 1] == TUSB_DESC_ENDPOINT) { + uint8_t ep_addr = desc[pos + 2]; + if (ep_addr == 0x02) ep_out_count++; + if (ep_addr == 0x82) ep_in_count++; + TEST_ASSERT_EQUAL(TUSB_XFER_BULK, desc[pos + 3]); + TEST_ASSERT_EQUAL(64, desc[pos + 4]); + TEST_ASSERT_EQUAL(0, desc[pos + 5]); + } + pos += desc[pos]; + } + TEST_ASSERT_EQUAL(2, ep_out_count); + TEST_ASSERT_EQUAL(2, ep_in_count); +} + +void test_midi2_descriptor_nonzero_itfnum(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(2, 0, 0x03, 0x83, 64) }; + + TEST_ASSERT_EQUAL(2, desc[2]); + + int pos = desc[0]; + while (pos < (int)sizeof(desc)) { + if (desc[pos + 1] == TUSB_DESC_INTERFACE) { + TEST_ASSERT_EQUAL(3, desc[pos + 2]); + break; + } + pos += desc[pos]; + } +} + +//--------------------------------------------------------------------+ +// Descriptor traversal integrity +//--------------------------------------------------------------------+ + +void test_midi2_descriptor_no_zero_length(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x01, 0x81, 64) }; + + int pos = 0; + int desc_count = 0; + while (pos < (int)sizeof(desc)) { + TEST_ASSERT_TRUE_MESSAGE(desc[pos] > 0, "Zero-length descriptor found"); + TEST_ASSERT_TRUE_MESSAGE(desc[pos] <= (int)sizeof(desc) - pos, + "Descriptor length exceeds remaining bytes"); + pos += desc[pos]; + desc_count++; + } + TEST_ASSERT_EQUAL((int)sizeof(desc), pos); + TEST_ASSERT_TRUE(desc_count > 5); +} + +void test_midi2_descriptor_valid_types(void) { + uint8_t desc[] = { TUD_MIDI2_DESCRIPTOR(0, 0, 0x01, 0x81, 64) }; + + int pos = 0; + while (pos < (int)sizeof(desc)) { + uint8_t dtype = desc[pos + 1]; + bool valid = (dtype == TUSB_DESC_INTERFACE || + dtype == TUSB_DESC_ENDPOINT || + dtype == TUSB_DESC_CS_INTERFACE || + dtype == TUSB_DESC_CS_ENDPOINT); + TEST_ASSERT_TRUE_MESSAGE(valid, "Invalid descriptor type found"); + pos += desc[pos]; + } +} + +//--------------------------------------------------------------------+ +// Edge cases +//--------------------------------------------------------------------+ + +void test_ump_word_count_with_values_beyond_0xf(void) { + TEST_ASSERT_EQUAL(4, midi2_ump_word_count(0x10)); + TEST_ASSERT_EQUAL(4, midi2_ump_word_count(0xFF)); +} diff --git a/test/unit-test/test/host/midi2/test_midi2_host.c b/test/unit-test/test/host/midi2/test_midi2_host.c new file mode 100644 index 000000000..8ad77c14e --- /dev/null +++ b/test/unit-test/test/host/midi2/test_midi2_host.c @@ -0,0 +1,101 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2026 Saulo Verissimo + * + * 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. + */ + +#include "unity.h" +#include "tusb_option.h" +#include "class/midi/midi.h" +#include "class/midi/midi2_host.h" + +void setUp(void) {} +void tearDown(void) {} + +//--------------------------------------------------------------------+ +// UMP Word Count (shared helper, defined in midi.h) +//--------------------------------------------------------------------+ + +void test_midi2_host_ump_word_count_1word(void) { + uint8_t types[] = {0x0, 0x1, 0x2, 0x6, 0x7}; + for (int i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(1, midi2_ump_word_count(types[i])); + } +} + +void test_midi2_host_ump_word_count_2word(void) { + uint8_t types[] = {0x3, 0x4, 0x8, 0x9, 0xA}; + for (int i = 0; i < 5; i++) { + TEST_ASSERT_EQUAL(2, midi2_ump_word_count(types[i])); + } +} + +void test_midi2_host_ump_word_count_4word(void) { + uint8_t types[] = {0x5, 0xD, 0xE, 0xF}; + for (int i = 0; i < 4; i++) { + TEST_ASSERT_EQUAL(4, midi2_ump_word_count(types[i])); + } +} + +//--------------------------------------------------------------------+ +// Callback struct field validation +//--------------------------------------------------------------------+ + +void test_midi2_descriptor_cb_struct_fields(void) { + tuh_midi2_descriptor_cb_t desc = { + .protocol_version = 1, + .bcdMSC_hi = 0x02, + .bcdMSC_lo = 0x00, + .rx_cable_count = 1, + .tx_cable_count = 1 + }; + TEST_ASSERT_EQUAL(1, desc.protocol_version); + TEST_ASSERT_EQUAL(0x02, desc.bcdMSC_hi); + TEST_ASSERT_EQUAL(0x00, desc.bcdMSC_lo); + TEST_ASSERT_EQUAL(1, desc.rx_cable_count); + TEST_ASSERT_EQUAL(1, desc.tx_cable_count); +} + +void test_midi2_mount_cb_struct_fields(void) { + tuh_midi2_mount_cb_t mount = { + .daddr = 1, + .bInterfaceNumber = 0, + .protocol_version = 1, + .alt_setting_active = 1, + .rx_cable_count = 2, + .tx_cable_count = 2 + }; + TEST_ASSERT_EQUAL(1, mount.daddr); + TEST_ASSERT_EQUAL(0, mount.bInterfaceNumber); + TEST_ASSERT_EQUAL(1, mount.protocol_version); + TEST_ASSERT_EQUAL(1, mount.alt_setting_active); + TEST_ASSERT_EQUAL(2, mount.rx_cable_count); + TEST_ASSERT_EQUAL(2, mount.tx_cable_count); +} + +//--------------------------------------------------------------------+ +// CS Endpoint subtypes +//--------------------------------------------------------------------+ + +void test_midi2_host_cs_endpoint_subtypes(void) { + TEST_ASSERT_EQUAL(0x01, MIDI_CS_ENDPOINT_GENERAL); + TEST_ASSERT_EQUAL(0x02, MIDI_CS_ENDPOINT_GENERAL_2_0); +} -- cgit v1.3.1 From fa9edeff9c00ee1fc4ee7ab9938b1a5955a6281a Mon Sep 17 00:00:00 2001 From: Saulo Veríssimo Date: Wed, 25 Mar 2026 07:05:56 -0300 Subject: fix: address PR review feedback for MIDI 2.0 drivers Host driver (midi2_host.c): - midih2_open() now returns actual parsed length instead of max_len, preventing composite device interface conflicts - Parsers (alt0/alt1) refactored to return const uint8_t* end pointer following midi_host.c switch/case pattern - Alt 1 CS Endpoint now parses MIDI 2.0 layout (bNumGrpTrmBlk at offset 3 with MIDI_CS_ENDPOINT_GENERAL_2_0 subtype check) instead of reusing MIDI 1.0 struct (bNumEmbMIDIJack) - midih2_set_config() now issues SET_INTERFACE control request via tuh_interface_set() before completing configuration. Falls back to alt 0 if SET_INTERFACE fails - Extracted midih2_set_config_complete() and midih2_set_interface_cb() for async SET_INTERFACE handling Device driver (midi2_device.c): - midi2d_open() skip loop now checks bInterfaceNumber, stopping at interfaces that belong to other functions in composite devices - SET_INTERFACE handler now rejects alt > 1 (returns false/stall) - Named constants for GTB descriptor types and MIDI protocol values Descriptor macros (usbd.h): - TUD_MIDI2_DESC_ALT1_HEAD: iInterface set to 0 (consistent with Alt 0), wTotalLength now uses TUD_MIDI2_DESC_ALT1_CS_LEN to cover all Alt 1 class-specific descriptors - TUD_MIDI2_DESC_ALT1_EP: now accepts GTB ID list via variadic args, emitting complete CS endpoint descriptor Host example: - CMakeLists.txt restricted to rp2040 family (display.c requires Pico SDK headers) - display.c: null terminator after strncpy in log scroll Documentation: - class_drivers.rst updated to reflect SET_INTERFACE behavior and auto-select with fallback Addresses: Codex P1 (#1, #2, #3), Copilot (#4-#9) --- docs/reference/class_drivers.rst | 8 +- examples/host/midi2_host/CMakeLists.txt | 3 +- examples/host/midi2_host/src/display.c | 1 + src/class/midi/midi2_device.c | 14 ++- src/class/midi/midi2_host.c | 213 ++++++++++++++++++++------------ src/device/usbd.h | 24 ++-- 6 files changed, 166 insertions(+), 97 deletions(-) (limited to 'docs') diff --git a/docs/reference/class_drivers.rst b/docs/reference/class_drivers.rst index 9ed332acb..3ac0d8d4e 100644 --- a/docs/reference/class_drivers.rst +++ b/docs/reference/class_drivers.rst @@ -87,7 +87,7 @@ The MIDI 2.0 Host driver enables TinyUSB to enumerate and communicate with USB M **Key Features:** - **Reactive Architecture**: Auto-detects Alt Setting 1 (MIDI 2.0) capability during enumeration -- **Auto-Selection**: Automatically selects the highest available protocol (MIDI 2.0 preferred) +- **Auto-Selection**: Automatically selects the highest available protocol and issues SET_INTERFACE to activate Alt Setting 1 when MIDI 2.0 is detected - **Transparent Stream Messages**: All data (UMP packets + Stream Messages) flow through callbacks - **Memory Safe**: No dynamic allocation, fixed-size instances per device @@ -271,9 +271,9 @@ Architecture The MIDI 2.0 Host driver uses a **reactive, callback-driven architecture** that mirrors the proven patterns in TinyUSB's existing device drivers (CDC, HID, etc.): - **Auto-Detection**: Host automatically detects Alt Setting 1 capability -- **Auto-Selection**: Selects highest protocol available (MIDI 2.0 preferred) -- **Application Control**: App makes protocol behavior decisions via callbacks -- **Transparent I/O**: Stream Messages and UMP packets flow transparently +- **Auto-Selection**: Selects highest protocol available and issues SET_INTERFACE +- **Transparent I/O**: Stream Messages and UMP packets flow through callbacks +- **Callback-Driven**: App receives events via callbacks (descriptor, mount, rx, tx, unmount) Differences from MIDI 1.0 Host ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ diff --git a/examples/host/midi2_host/CMakeLists.txt b/examples/host/midi2_host/CMakeLists.txt index 221de7adf..cd70d122a 100644 --- a/examples/host/midi2_host/CMakeLists.txt +++ b/examples/host/midi2_host/CMakeLists.txt @@ -6,7 +6,8 @@ project(midi2_host C CXX ASM) family_initialize_project(${PROJECT_NAME} ${CMAKE_CURRENT_LIST_DIR}) -if(FAMILY STREQUAL "espressif") +# This example requires PIO-USB and Pico SDK (I2C, SSD1306 display) +if(NOT FAMILY STREQUAL "rp2040") return() endif() diff --git a/examples/host/midi2_host/src/display.c b/examples/host/midi2_host/src/display.c index 6d81bcd5c..4745c2961 100644 --- a/examples/host/midi2_host/src/display.c +++ b/examples/host/midi2_host/src/display.c @@ -190,6 +190,7 @@ void display_log(const char* text, uint16_t color) { if (log_count >= LOG_LINES) { for (int i = 0; i < LOG_LINES - 1; i++) { strncpy(log_lines[i], log_lines[i + 1], CHARS_PER_LINE); + log_lines[i][CHARS_PER_LINE] = '\0'; } log_count = LOG_LINES - 1; } diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index 9363aac11..aecbda4c5 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -505,12 +505,19 @@ uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint } // Skip remaining descriptors (alt setting 1, CS endpoints, GTB) + // Stop at any interface descriptor that is not our MIDI Streaming alt setting while (tu_desc_in_bounds(p_desc, desc_end)) { uint8_t dtype = tu_desc_type(p_desc); - if (dtype != TUSB_DESC_CS_INTERFACE && dtype != TUSB_DESC_CS_ENDPOINT && - dtype != TUSB_DESC_INTERFACE && dtype != TUSB_DESC_ENDPOINT) { + + if (dtype == TUSB_DESC_INTERFACE) { + const tusb_desc_interface_t* next_itf = (const tusb_desc_interface_t*) p_desc; + // Continue only if this is an alternate setting of our own interface + if (next_itf->bInterfaceNumber != desc_midi->bInterfaceNumber) break; + } else if (dtype != TUSB_DESC_CS_INTERFACE && dtype != TUSB_DESC_CS_ENDPOINT && + dtype != TUSB_DESC_ENDPOINT) { break; } + p_desc = tu_desc_next(p_desc); } @@ -528,6 +535,9 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re uint8_t itf_num = tu_u16_low(request->wIndex); uint8_t alt = tu_u16_low(request->wValue); + // Only Alt Setting 0 (MIDI 1.0) and 1 (UMP) are valid + if (alt > 1) return false; + uint8_t idx = find_midi2_itf_by_num(itf_num); if (idx >= CFG_TUD_MIDI2) return false; diff --git a/src/class/midi/midi2_host.c b/src/class/midi/midi2_host.c index beb441b56..5b9f98f8b 100644 --- a/src/class/midi/midi2_host.c +++ b/src/class/midi/midi2_host.c @@ -125,9 +125,10 @@ static inline uint8_t get_idx_by_ep_addr(uint8_t daddr, uint8_t ep_addr) { // Descriptor parsing //--------------------------------------------------------------------+ -static void midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, +// Parse Alt Setting 0 (MIDI 1.0) descriptors. Returns pointer past last consumed descriptor. +static const uint8_t* midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, NULL); p_midi->bInterfaceNumber = desc_itf->bInterfaceNumber; @@ -136,93 +137,113 @@ static void midih2_parse_descriptors_alt0(midih2_interface_t *p_midi, uint8_t rx_cable_count = 0; uint8_t tx_cable_count = 0; + bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, desc_end)) { - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { - break; - } - - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { - const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; - - // Open endpoint and stream - TU_ASSERT(tuh_edpt_open(p_midi->daddr, p_ep),); - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); - tu_edpt_stream_clear(&p_midi->ep_stream.rx); - } else { - tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); - } - - p_desc = tu_desc_next(p_desc); + while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { + switch (tu_desc_type(p_desc)) { + case TUSB_DESC_INTERFACE: + found_new_interface = true; + break; - if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { - const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + case TUSB_DESC_ENDPOINT: { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - tx_cable_count = p_csep->bNumEmbMIDIJack; + TU_ASSERT(tuh_edpt_open(p_midi->daddr, p_ep), NULL); + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_midi->ep_stream.rx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.rx); } else { - rx_cable_count = p_csep->bNumEmbMIDIJack; + tu_edpt_stream_open(&p_midi->ep_stream.tx, p_midi->daddr, p_ep, tu_edpt_packet_size(p_ep)); + tu_edpt_stream_clear(&p_midi->ep_stream.tx); + } + + p_desc = tu_desc_next(p_desc); + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = p_csep->bNumEmbMIDIJack; + } else { + rx_cable_count = p_csep->bNumEmbMIDIJack; + } } + break; } + + default: + break; } - p_desc = tu_desc_next(p_desc); + if (!found_new_interface) { + p_desc = tu_desc_next(p_desc); + } } p_midi->rx_cable_count_alt0 = rx_cable_count; p_midi->tx_cable_count_alt0 = tx_cable_count; + return p_desc; } -static void midih2_parse_descriptors_alt1(midih2_interface_t *p_midi, +// Parse Alt Setting 1 (MIDI 2.0 UMP) descriptors. Returns pointer past last consumed descriptor. +static const uint8_t* midih2_parse_descriptors_alt1(midih2_interface_t *p_midi, const tusb_desc_interface_t *desc_itf, const uint8_t *desc_end) { - TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass,); - TU_VERIFY(desc_itf->bAlternateSetting == 1,); + TU_VERIFY(AUDIO_SUBCLASS_MIDI_STREAMING == desc_itf->bInterfaceSubClass, NULL); + TU_VERIFY(desc_itf->bAlternateSetting == 1, NULL); const uint8_t *p_desc = (const uint8_t *) desc_itf; p_desc = tu_desc_next(p_desc); uint8_t rx_cable_count = 0; uint8_t tx_cable_count = 0; + bool found_new_interface = false; - while (tu_desc_in_bounds(p_desc, desc_end)) { - if (tu_desc_type(p_desc) == TUSB_DESC_INTERFACE) { - break; - } + while (tu_desc_in_bounds(p_desc, desc_end) && !found_new_interface) { + switch (tu_desc_type(p_desc)) { + case TUSB_DESC_INTERFACE: + found_new_interface = true; + break; - if (tu_desc_type(p_desc) == TUSB_DESC_CS_INTERFACE) { - if (tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_HEADER) { - const uint8_t *bcd_ptr = p_desc + 3; - p_midi->bcdMSC_lo = bcd_ptr[0]; - p_midi->bcdMSC_hi = bcd_ptr[1]; + case TUSB_DESC_CS_INTERFACE: + if (tu_desc_subtype(p_desc) == MIDI_CS_INTERFACE_HEADER) { + // bcdMSC at offset 3-4 in CS Interface Header + const uint8_t *bcd_ptr = p_desc + 3; + p_midi->bcdMSC_lo = bcd_ptr[0]; + p_midi->bcdMSC_hi = bcd_ptr[1]; + if (p_midi->bcdMSC_hi == 0x02) { // bcdMSC 0x0200 = USB-MIDI 2.0 + p_midi->protocol_version = 1; + } + } + break; - if (p_midi->bcdMSC_hi == 0x02) { - p_midi->protocol_version = 1; + case TUSB_DESC_ENDPOINT: { + const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + p_desc = tu_desc_next(p_desc); + + if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { + // MIDI 2.0 CS Endpoint General 2.0: bNumGrpTrmBlk at offset 3 + if (p_desc[0] >= 4 && p_desc[2] == MIDI_CS_ENDPOINT_GENERAL_2_0) { + uint8_t num_grp_trm_blk = p_desc[3]; + if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { + tx_cable_count = num_grp_trm_blk; + } else { + rx_cable_count = num_grp_trm_blk; + } + } } + break; } + + default: + break; } - if (tu_desc_type(p_desc) == TUSB_DESC_ENDPOINT) { - const tusb_desc_endpoint_t *p_ep = (const tusb_desc_endpoint_t *) p_desc; + if (!found_new_interface) { p_desc = tu_desc_next(p_desc); - - if (tu_desc_in_bounds(p_desc, desc_end) && tu_desc_type(p_desc) == TUSB_DESC_CS_ENDPOINT) { - const midi_desc_cs_endpoint_t *p_csep = (const midi_desc_cs_endpoint_t *) p_desc; - - if (tu_edpt_dir(p_ep->bEndpointAddress) == TUSB_DIR_OUT) { - tx_cable_count = p_csep->bNumEmbMIDIJack; - } else { - rx_cable_count = p_csep->bNumEmbMIDIJack; - } - } } - - p_desc = tu_desc_next(p_desc); } p_midi->rx_cable_count_alt1 = rx_cable_count; p_midi->tx_cable_count_alt1 = tx_cable_count; + return p_desc; } //--------------------------------------------------------------------+ @@ -327,33 +348,20 @@ uint16_t midih2_open(uint8_t rhport, uint8_t dev_addr, const tusb_desc_interface desc_itf->bInterfaceNumber, desc_itf->bAlternateSetting, dev_addr); // Dispatch to appropriate parser based on Alt Setting + const uint8_t *p_end = NULL; if (desc_itf->bAlternateSetting == 0) { - midih2_parse_descriptors_alt0(p_midi, desc_itf, desc_end); + p_end = midih2_parse_descriptors_alt0(p_midi, desc_itf, desc_end); } else if (desc_itf->bAlternateSetting == 1) { - midih2_parse_descriptors_alt1(p_midi, desc_itf, desc_end); + p_end = midih2_parse_descriptors_alt1(p_midi, desc_itf, desc_end); } - return max_len; + // Return number of bytes consumed (following midi_host.c pattern) + uint16_t const parsed_len = (p_end != NULL) ? (uint16_t)(p_end - desc_start) : 0; + return parsed_len; } -bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { - uint8_t idx = 0; - for (idx = 0; idx < CFG_TUH_MIDI2; idx++) { - if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { - break; - } - } - - if (idx >= CFG_TUH_MIDI2) { - // Not our interface (e.g. Audio Control) - pass through to next - usbh_driver_set_config_complete(dev_addr, itf_num); - return true; - } - - midih2_interface_t *p_midi = &_midi2_host[idx]; - - // Auto-select alt setting - midih2_auto_select_alt_setting(p_midi); +static void midih2_set_config_complete(midih2_interface_t *p_midi, uint8_t idx) { + uint8_t dev_addr = p_midi->daddr; // Invoke descriptor_cb tuh_midi2_descriptor_cb_t desc_cb = { @@ -374,7 +382,7 @@ bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { // Invoke mount_cb tuh_midi2_mount_cb_t mount_cb = { - .daddr = p_midi->daddr, + .daddr = dev_addr, .bInterfaceNumber = p_midi->bInterfaceNumber, .protocol_version = p_midi->protocol_version, .alt_setting_active = p_midi->alt_setting_current, @@ -387,7 +395,56 @@ bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { tu_edpt_stream_read_xfer(&p_midi->ep_stream.rx); // Signal USBH that configuration is complete - usbh_driver_set_config_complete(dev_addr, itf_num); + usbh_driver_set_config_complete(dev_addr, p_midi->bInterfaceNumber); +} + +static void midih2_set_interface_cb(tuh_xfer_t *xfer) { + uint8_t const dev_addr = xfer->daddr; + uint8_t const itf_num = (uint8_t) tu_le16toh(xfer->setup->wIndex); + + // Find our interface + for (uint8_t idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { + if (xfer->result == XFER_RESULT_SUCCESS) { + midih2_set_config_complete(&_midi2_host[idx], idx); + } else { + // SET_INTERFACE failed, fall back to alt 0 + TU_LOG_DRV("MIDI2 SET_INTERFACE failed, falling back to alt 0\r\n"); + _midi2_host[idx].alt_setting_current = 0; + midih2_set_config_complete(&_midi2_host[idx], idx); + } + return; + } + } +} + +bool midih2_set_config(uint8_t dev_addr, uint8_t itf_num) { + uint8_t idx = 0; + for (idx = 0; idx < CFG_TUH_MIDI2; idx++) { + if (_midi2_host[idx].daddr == dev_addr && _midi2_host[idx].bInterfaceNumber == itf_num) { + break; + } + } + + if (idx >= CFG_TUH_MIDI2) { + // Not our interface (e.g. Audio Control) - pass through to next + usbh_driver_set_config_complete(dev_addr, itf_num); + return true; + } + + midih2_interface_t *p_midi = &_midi2_host[idx]; + + // Auto-select alt setting + midih2_auto_select_alt_setting(p_midi); + + // If MIDI 2.0 detected, issue SET_INTERFACE to activate Alt Setting 1 + if (p_midi->alt_setting_current == 1) { + TU_LOG_DRV("MIDI2 requesting SET_INTERFACE alt 1 for itf %u\r\n", itf_num); + TU_ASSERT(tuh_interface_set(dev_addr, itf_num, 1, midih2_set_interface_cb, 0)); + } else { + // MIDI 1.0 only, complete immediately + midih2_set_config_complete(p_midi, idx); + } return true; } diff --git a/src/device/usbd.h b/src/device/usbd.h index af37eff56..a9f4c5f08 100644 --- a/src/device/usbd.h +++ b/src/device/usbd.h @@ -429,18 +429,20 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ //--------------------------------------------------------------------+ // Alt Setting 1: MS Interface + MS Header (bcdMSC=0x0200) +// wTotalLength covers MS Header + all CS Endpoint descriptors +#define TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs) (7 + (4 + (_numgtbs)) * 2) #define TUD_MIDI2_DESC_ALT1_HEAD_LEN (9 + 7) -#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx) \ +#define TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, _numgtbs) \ /* MIDI Streaming Interface, Alt Setting 1 */\ - 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, _stridx,\ - /* MS Header (MIDI 2.0) */\ - 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(7) + 9, TUSB_DESC_INTERFACE, (uint8_t)((_itfnum) + 1), 1, 2, TUSB_CLASS_AUDIO, AUDIO_SUBCLASS_MIDI_STREAMING, AUDIO_FUNC_PROTOCOL_CODE_UNDEF, 0,\ + /* MS Header (MIDI 2.0): wTotalLength = header + 2x CS Endpoint */\ + 7, TUSB_DESC_CS_INTERFACE, MIDI_CS_INTERFACE_HEADER, U16_TO_U8S_LE(0x0200), U16_TO_U8S_LE(TUD_MIDI2_DESC_ALT1_CS_LEN(_numgtbs)) -// Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint (subtype 0x02) +// Alt Setting 1: Standard USB Endpoint (7 bytes) + CS Endpoint General 2.0 #define TUD_MIDI2_DESC_ALT1_EP_LEN(_numgtbs) (7 + 4 + (_numgtbs)) -#define TUD_MIDI2_DESC_ALT1_EP(_ep, _epsize, _numgtbs) \ +#define TUD_MIDI2_DESC_ALT1_EP(_ep, _epsize, _numgtbs, ...) \ 7, TUSB_DESC_ENDPOINT, _ep, TUSB_XFER_BULK, U16_TO_U8S_LE(_epsize), 0, \ - (uint8_t)(4 + (_numgtbs)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL_2_0, _numgtbs + (uint8_t)(4 + (_numgtbs)), TUSB_DESC_CS_ENDPOINT, MIDI_CS_ENDPOINT_GENERAL_2_0, _numgtbs, ## __VA_ARGS__ // Total length: Alt 0 (MIDI 1.0) + Alt 1 (UMP) #define TUD_MIDI2_DESC_LEN (TUD_MIDI_DESC_LEN + TUD_MIDI2_DESC_ALT1_HEAD_LEN + TUD_MIDI2_DESC_ALT1_EP_LEN(1) * 2) @@ -455,11 +457,9 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ TUD_MIDI_DESC_EP(_epin, _epsize, 1),\ TUD_MIDI_JACKID_OUT_EMB(1),\ /* Alt Setting 1 (UMP) */\ - TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx),\ - TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1),\ - 1, /* bAssoGrpTrmBlkID = 1 */\ - TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1),\ - 1 /* bAssoGrpTrmBlkID = 1 */ + TUD_MIDI2_DESC_ALT1_HEAD(_itfnum, _stridx, 1),\ + TUD_MIDI2_DESC_ALT1_EP(_epout, _epsize, 1, 1 /* bAssoGrpTrmBlkID */),\ + TUD_MIDI2_DESC_ALT1_EP(_epin, _epsize, 1, 1 /* bAssoGrpTrmBlkID */) //--------------------------------------------------------------------+ // Audio Descriptor Templates -- cgit v1.3.1 From 4baf1883c194c2c4b6fa30cc0c443ad6c83e0b19 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 18 May 2026 23:07:49 +0200 Subject: midi2: convert to raw Tx FIFO for better segmentation handling, add count to packet api Signed-off-by: HiFiPhile --- docs/reference/class_drivers.rst | 4 +- src/class/midi/midi2_device.c | 276 +++++++++++++++++++++++---------------- src/class/midi/midi2_device.h | 14 +- 3 files changed, 176 insertions(+), 118 deletions(-) (limited to 'docs') diff --git a/docs/reference/class_drivers.rst b/docs/reference/class_drivers.rst index 3ac0d8d4e..4a101fabc 100644 --- a/docs/reference/class_drivers.rst +++ b/docs/reference/class_drivers.rst @@ -64,8 +64,8 @@ I/O Functions uint32_t tud_midi2_ump_read(uint32_t* words, uint32_t max_words); uint32_t tud_midi2_ump_write(const uint32_t* words, uint32_t count); - bool tud_midi2_packet_read(uint8_t packet[4]); - bool tud_midi2_packet_write(const uint8_t packet[4]); + uint32_t tud_midi2_packet_read(uint8_t packets[], uint32_t max_packets); + uint32_t tud_midi2_packet_write(const uint8_t packets[], uint32_t count); Callbacks ^^^^^^^^^ diff --git a/src/class/midi/midi2_device.c b/src/class/midi/midi2_device.c index c61884689..b14f439f8 100644 --- a/src/class/midi/midi2_device.c +++ b/src/class/midi/midi2_device.c @@ -100,6 +100,16 @@ enum { //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ +typedef struct { + uint8_t ep_addr; + uint16_t mps; + tu_fifo_t ff; + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 + uint8_t* ep_buf; +#endif +} midi2d_tx_t; + typedef struct { uint8_t rhport; uint8_t itf_num; @@ -109,7 +119,7 @@ typedef struct { /*------------- From this point, data is not cleared by bus reset -------------*/ struct { - tu_edpt_stream_t tx; + midi2d_tx_t tx; tu_edpt_stream_t rx; uint8_t rx_ff_buf[CFG_TUD_MIDI2_RX_BUFSIZE]; @@ -117,19 +127,6 @@ typedef struct { } ep_stream; } midi2d_interface_t; -TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_GROUPS >= 1 && CFG_TUD_MIDI2_NUM_GROUPS <= 16, - "CFG_TUD_MIDI2_NUM_GROUPS must be 1..16"); -TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS <= 32, - "CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS must be 1..32"); - -#define ITF_MEM_RESET_SIZE offsetof(midi2d_interface_t, ep_stream) - -static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; - -static inline uint8_t _itf_idx(const midi2d_interface_t* p_midi) { - return (uint8_t)(p_midi - _midi2d_itf); -} - // Skip local EP buffer if dedicated hw FIFO is supported #if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 typedef struct { @@ -140,6 +137,15 @@ typedef struct { CFG_TUD_MEM_SECTION static midi2d_epbuf_t _midi2d_epbuf[CFG_TUD_MIDI2]; #endif +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_GROUPS >= 1 && CFG_TUD_MIDI2_NUM_GROUPS <= 16, + "CFG_TUD_MIDI2_NUM_GROUPS must be 1..16"); +TU_VERIFY_STATIC(CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS >= 1 && CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS <= 32, + "CFG_TUD_MIDI2_NUM_FUNCTION_BLOCKS must be 1..32"); + +#define ITF_MEM_RESET_SIZE offsetof(midi2d_interface_t, ep_stream) + +static midi2d_interface_t _midi2d_itf[CFG_TUD_MIDI2]; + // Default Group Terminal Block descriptor (USB-MIDI 2.0 spec, Table 5-5/5-6) static const uint8_t _default_gtb_desc[] = { // GTB Header (5 bytes) @@ -162,15 +168,112 @@ static const uint8_t _default_gtb_desc[] = { 0, 0 // wMaxOutputBandwidth: unknown }; +//--------------------------------------------------------------------+ +// Common utility functions +//--------------------------------------------------------------------+ + +static inline uint8_t _itf_idx(const midi2d_interface_t* p_midi) { + return (uint8_t)(p_midi - _midi2d_itf); +} + +static inline bool _tx_opened(const midi2d_interface_t* p_midi) { + return p_midi->ep_stream.tx.ep_addr != 0; +} + +static uint8_t _tx_byte_at(const tu_fifo_buffer_info_t* info, uint16_t offset) { + if (offset < info->linear.len) { + return info->linear.ptr[offset]; + } + + offset = (uint16_t) (offset - info->linear.len); + if (offset < info->wrapped.len) { + return info->wrapped.ptr[offset]; + } + + return 0; +} + +// Calculate the largest byte count that contains only whole UMP packets and +// fits in one USB transfer (<= mps). +static uint16_t _tx_nonseg_len_to_mps(midi2d_tx_t* tx) { + tu_fifo_buffer_info_t info; + tu_fifo_get_read_info(&tx->ff, &info); + + const uint16_t available = (uint16_t) (info.linear.len + info.wrapped.len); + uint16_t bytes = 0; + + while (bytes < tx->mps) { + if ((uint16_t) (available - bytes) < 4) break; + + uint8_t mt = (uint8_t)((_tx_byte_at(&info, (uint16_t) (bytes + 3)) >> 4) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t) pkt_words * 4; + + if (pkt_bytes == 0) break; + if ((uint16_t) (available - bytes) < pkt_bytes) break; + if ((uint16_t) (bytes + pkt_bytes) > tx->mps) break; + + bytes = (uint16_t) (bytes + pkt_bytes); + } + + return bytes; +} + +// Start one IN transfer capped at mps, return number of bytes queued to the controller, or 0 if nothing was queued. +static uint16_t _tx_start_xfer(midi2d_interface_t* p_midi) { + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + uint16_t ff_count = tu_fifo_count(&tx->ff); + + if (ff_count == 0) return 0; + + if (!usbd_edpt_claim(p_midi->rhport, tx->ep_addr)) return 0; + + uint16_t bytes; + if (p_midi->alt_setting == 1) { + bytes = _tx_nonseg_len_to_mps(tx); + } else { + bytes = tu_min16(tu_fifo_count(&tx->ff), tx->mps); + } + if (bytes == 0) { + usbd_edpt_release(p_midi->rhport, tx->ep_addr); + return 0; + } + +#if CFG_TUD_EDPT_DEDICATED_HWFIFO + TU_ASSERT(usbd_edpt_xfer_fifo(p_midi->rhport, tx->ep_addr, &tx->ff, bytes, false), 0); +#else + tu_fifo_read_n(&tx->ff, tx->ep_buf, bytes); + TU_ASSERT(usbd_edpt_xfer(p_midi->rhport, tx->ep_addr, tx->ep_buf, bytes, false), 0); +#endif + + return bytes; +} + +static uint32_t _tx_ump_write(midi2d_interface_t* p_midi, const uint32_t* words, uint32_t count) { + uint32_t written = 0; + while (written < count) { + uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); + uint8_t pkt_words = midi2_ump_word_count(mt); + uint16_t pkt_bytes = (uint16_t) pkt_words * 4; + + if (written + pkt_words > count) break; + if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < pkt_bytes) break; + + if (tu_fifo_write_n(&p_midi->ep_stream.tx.ff, &words[written], pkt_bytes) != pkt_bytes) break; + written += pkt_words; + } + + (void) _tx_start_xfer(p_midi); + return written; +} + //--------------------------------------------------------------------+ // Protocol Negotiation //--------------------------------------------------------------------+ static void _nego_send_ump(midi2d_interface_t* p_midi, const uint32_t* words, uint8_t count) { - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - if (!tu_edpt_stream_is_opened(ep_tx)) return; - if (tu_edpt_stream_write_available(ep_tx) < count * 4) return; - tu_edpt_stream_write(ep_tx, words, count * 4); - tu_edpt_stream_write_xfer(ep_tx); + if (!_tx_opened(p_midi)) return; + if (tu_fifo_remaining(&p_midi->ep_stream.tx.ff) < (uint32_t) count * 4) return; + (void) _tx_ump_write(p_midi, words, count); } static void _nego_send_endpoint_info(midi2d_interface_t* p_midi) { @@ -307,7 +410,7 @@ static void _nego_process_rx(midi2d_interface_t* p_midi) { bool tud_midi2_n_mounted(uint8_t itf) { TU_VERIFY(itf < CFG_TUD_MIDI2, false); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - return tu_edpt_stream_is_opened(&p_midi->ep_stream.tx) && + return _tx_opened(p_midi) && tu_edpt_stream_is_opened(&p_midi->ep_stream.rx); } @@ -346,10 +449,10 @@ uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words) return total_read; } -bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]) { - TU_VERIFY(itf < CFG_TUD_MIDI2, false); +uint32_t tud_midi2_n_packet_read(uint8_t itf, uint8_t packets[], uint32_t max_packets) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && packets != NULL && max_packets > 0, 0); midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - return 4 == tu_edpt_stream_read(&p_midi->ep_stream.rx, packet, 4); + return tu_edpt_stream_read(&p_midi->ep_stream.rx, packets, max_packets * 4u) >> 2u; } //--------------------------------------------------------------------+ @@ -362,44 +465,31 @@ uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t coun // UMP API is only valid on Alt Setting 1 (USB-MIDI 2.0). // Alt 0 carries USB-MIDI 1.0 32-bit Event Packets, not UMP words. if (p_midi->alt_setting != 1) { return 0; } + TU_VERIFY(_tx_opened(p_midi), 0); - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), 0); + return _tx_ump_write(p_midi, words, count); +} + +uint32_t tud_midi2_n_packet_write(uint8_t itf, const uint8_t packets[], uint32_t count) { + TU_VERIFY(itf < CFG_TUD_MIDI2 && packets != NULL && count > 0, 0); + midi2d_interface_t* p_midi = &_midi2d_itf[itf]; + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + + // Packet API is for Alt Setting 0 (USB-MIDI 1.0) event packets. + TU_VERIFY(p_midi->alt_setting == 0, 0); + TU_VERIFY(_tx_opened(p_midi), 0); uint32_t written = 0; while (written < count) { - uint8_t mt = (uint8_t)((words[written] >> 28) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint32_t pkt_bytes = (uint32_t)pkt_words * 4; + if (tu_fifo_remaining(&tx->ff) < 4) break; - if (written + pkt_words > count) break; - if (tu_edpt_stream_write_available(ep_tx) < pkt_bytes) break; - - // Flush whole packets already queued before adding one that would cross - // the wMaxPacketSize boundary. Prevents an UMP message from being split - // across two USB transfers, which would corrupt the host RX context. - uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - if (ff_count > 0 && ff_count + pkt_bytes > ep_tx->mps) { - tu_edpt_stream_write_xfer(ep_tx); - } - - tu_edpt_stream_write(ep_tx, &words[written], pkt_bytes); - written += pkt_words; + if (tu_fifo_write_n(&tx->ff, packets + written * 4u, 4) != 4) break; + written++; } - (void) tu_edpt_stream_write_xfer(ep_tx); - return written; -} + (void) _tx_start_xfer(p_midi); -bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]) { - TU_VERIFY(itf < CFG_TUD_MIDI2, false); - midi2d_interface_t* p_midi = &_midi2d_itf[itf]; - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - TU_VERIFY(tu_edpt_stream_is_opened(ep_tx), false); - TU_VERIFY(tu_edpt_stream_write_available(ep_tx) >= 4, false); - TU_VERIFY(tu_edpt_stream_write(ep_tx, packet, 4) > 0, false); - (void) tu_edpt_stream_write_xfer(ep_tx); - return true; + return written; } //--------------------------------------------------------------------+ @@ -439,8 +529,14 @@ void midi2d_init(void) { tu_edpt_stream_init(&p_midi->ep_stream.rx, false, false, false, p_midi->ep_stream.rx_ff_buf, CFG_TUD_MIDI2_RX_BUFSIZE, epout_buf); - tu_edpt_stream_init(&p_midi->ep_stream.tx, false, true, false, - p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI2_TX_BUFSIZE, epin_buf); + + midi2d_tx_t* tx = &p_midi->ep_stream.tx; + (void) tu_fifo_config(&tx->ff, p_midi->ep_stream.tx_ff_buf, CFG_TUD_MIDI2_TX_BUFSIZE, false); +#if CFG_TUD_EDPT_DEDICATED_HWFIFO == 0 + tx->ep_buf = epin_buf; +#else + (void) epin_buf; +#endif } } @@ -448,7 +544,6 @@ bool midi2d_deinit(void) { for (uint8_t i = 0; i < CFG_TUD_MIDI2; i++) { midi2d_interface_t* p_midi = &_midi2d_itf[i]; tu_edpt_stream_deinit(&p_midi->ep_stream.rx); - tu_edpt_stream_deinit(&p_midi->ep_stream.tx); } return true; } @@ -462,8 +557,8 @@ void midi2d_reset(uint8_t rhport) { tu_edpt_stream_clear(&p_midi->ep_stream.rx); tu_edpt_stream_close(&p_midi->ep_stream.rx); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); - tu_edpt_stream_close(&p_midi->ep_stream.tx); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); + p_midi->ep_stream.tx.ep_addr = 0; } } @@ -533,8 +628,9 @@ uint16_t midi2d_open(uint8_t rhport, const tusb_desc_interface_t* desc_itf, uint const uint8_t ep_addr = desc_ep->bEndpointAddress; if (tu_edpt_dir(ep_addr) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_midi->ep_stream.tx, rhport, desc_ep, CFG_TUD_MIDI2_TX_EPSIZE); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + p_midi->ep_stream.tx.ep_addr = ep_addr; + p_midi->ep_stream.tx.mps = tu_edpt_packet_size(desc_ep); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); } else { tu_edpt_stream_open(&p_midi->ep_stream.rx, rhport, desc_ep, tu_edpt_packet_size(desc_ep)); tu_edpt_stream_clear(&p_midi->ep_stream.rx); @@ -588,7 +684,7 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re p_midi->alt_setting = alt; tu_edpt_stream_clear(&p_midi->ep_stream.rx); - tu_edpt_stream_clear(&p_midi->ep_stream.tx); + tu_fifo_clear(&p_midi->ep_stream.tx.ff); if (alt == 1) { p_midi->negotiated = false; @@ -635,53 +731,6 @@ bool midi2d_control_xfer_cb(uint8_t rhport, uint8_t stage, const tusb_control_re } } -// Drain whole UMP packets from the TX FIFO into the EP buffer, capped at -// wMaxPacketSize. Needed when CFG_TUD_MIDI2_TX_BUFSIZE > mps: the FIFO can -// then hold more bytes than fit in a single USB transfer, and a blind -// tu_edpt_stream_write_xfer would split a UMP across two transfers. -static void midi2d_flush_tx_boundary_aware(midi2d_interface_t* p_midi, uint32_t last_xferred) { - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; - const uint16_t mps = ep_tx->mps; - const uint16_t ff_count = tu_fifo_count(&ep_tx->ff); - - if (ff_count == 0) { - (void) tu_edpt_stream_write_zlp_if_needed(ep_tx, last_xferred); - return; - } - if (ff_count <= mps) { - // Whole FIFO fits in one transfer; the stream API drain is safe. - (void) tu_edpt_stream_write_xfer(ep_tx); - return; - } - if (ep_tx->ep_buf == NULL) { - // HWFIFO mode: relies on CFG_TUD_MIDI2_TX_BUFSIZE <= mps for UMP integrity. - (void) tu_edpt_stream_write_xfer(ep_tx); - return; - } - - // ff_count > mps and a local EP buffer is available: drain only whole UMP - // packets up to mps to preserve packet boundaries on the USB wire. - uint8_t word_bytes[4]; - uint8_t* buf = ep_tx->ep_buf; - uint16_t bytes = 0; - while (bytes < mps) { - if (tu_fifo_count(&ep_tx->ff) < 4) break; - if (4 != tu_fifo_peek_n(&ep_tx->ff, word_bytes, 4)) break; - uint8_t mt = (uint8_t)((word_bytes[3] >> 4) & 0x0F); - uint8_t pkt_words = midi2_ump_word_count(mt); - uint16_t pkt_bytes = (uint16_t)(pkt_words * 4); - if (tu_fifo_count(&ep_tx->ff) < pkt_bytes) break; - if (bytes + pkt_bytes > mps) break; - tu_fifo_read_n(&ep_tx->ff, buf + bytes, pkt_bytes); - bytes = (uint16_t)(bytes + pkt_bytes); - } - if (bytes == 0) return; - if (!usbd_edpt_claim(p_midi->rhport, ep_tx->ep_addr)) return; - if (!usbd_edpt_xfer(p_midi->rhport, ep_tx->ep_addr, buf, bytes, false)) { - usbd_edpt_release(p_midi->rhport, ep_tx->ep_addr); - } -} - bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) rhport; @@ -690,7 +739,7 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 midi2d_interface_t* p_midi = &_midi2d_itf[idx]; tu_edpt_stream_t* ep_rx = &p_midi->ep_stream.rx; - tu_edpt_stream_t* ep_tx = &p_midi->ep_stream.tx; + midi2d_tx_t* ep_tx = &p_midi->ep_stream.tx; if (ep_addr == ep_rx->ep_addr) { if (result == XFER_RESULT_SUCCESS) { @@ -702,7 +751,14 @@ bool midi2d_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint3 } tu_edpt_stream_read_xfer(ep_rx); } else if (ep_addr == ep_tx->ep_addr && result == XFER_RESULT_SUCCESS) { - midi2d_flush_tx_boundary_aware(p_midi, xferred_bytes); + uint16_t queued = _tx_start_xfer(p_midi); + // Send ZLP if no more data is queued but the last transfer was exactly mps + if (queued == 0 && tu_fifo_count(&ep_tx->ff) == 0 && xferred_bytes > 0 && + (0 == (xferred_bytes & (ep_tx->mps - 1)))) { + if (usbd_edpt_claim(rhport, ep_tx->ep_addr)) { + usbd_edpt_xfer(rhport, ep_tx->ep_addr, NULL, 0, false); + } + } } else { return false; } diff --git a/src/class/midi/midi2_device.h b/src/class/midi/midi2_device.h index 6c29b8ddf..e53535693 100644 --- a/src/class/midi/midi2_device.h +++ b/src/class/midi/midi2_device.h @@ -130,8 +130,8 @@ uint8_t tud_midi2_n_protocol(uint8_t itf); uint32_t tud_midi2_n_ump_read(uint8_t itf, uint32_t* words, uint32_t max_words); uint32_t tud_midi2_n_ump_write(uint8_t itf, const uint32_t* words, uint32_t count); -bool tud_midi2_n_packet_read(uint8_t itf, uint8_t packet[4]); -bool tud_midi2_n_packet_write(uint8_t itf, const uint8_t packet[4]); +uint32_t tud_midi2_n_packet_read(uint8_t itf, uint8_t packets[], uint32_t max_packets); +uint32_t tud_midi2_n_packet_write(uint8_t itf, const uint8_t packets[], uint32_t count); //--------------------------------------------------------------------+ // Application API (Single Interface) @@ -166,12 +166,14 @@ tud_midi2_ump_write(const uint32_t* words, uint32_t count) { return tud_midi2_n_ump_write(0, words, count); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_read(uint8_t packet[4]) { - return tud_midi2_n_packet_read(0, packet); +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_packet_read(uint8_t packets[], uint32_t max_packets) { + return tud_midi2_n_packet_read(0, packets, max_packets); } -TU_ATTR_ALWAYS_INLINE static inline bool tud_midi2_packet_write(const uint8_t packet[4]) { - return tud_midi2_n_packet_write(0, packet); +TU_ATTR_ALWAYS_INLINE static inline uint32_t +tud_midi2_packet_write(const uint8_t packets[], uint32_t count) { + return tud_midi2_n_packet_write(0, packets, count); } //--------------------------------------------------------------------+ -- cgit v1.3.1 From 9c316a458cdfcc00f1d349e24f3504337a59daa1 Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Mon, 1 Jun 2026 22:37:14 +0200 Subject: add device errata document Signed-off-by: HiFiPhile --- README.rst | 275 +++++++++++++++++++++++------------------------ docs/index.rst | 1 + docs/troubleshooting.rst | 2 + 3 files changed, 140 insertions(+), 138 deletions(-) (limited to 'docs') diff --git a/README.rst b/README.rst index e1e73c3ad..c376599ec 100644 --- a/README.rst +++ b/README.rst @@ -130,144 +130,143 @@ TinyUSB is completely thread-safe by pushing all Interrupt Service Request (ISR) Supported CPUs -------------- - -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | -+==============+=============================+========+======+===========+========================+====================+ -| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | -| | MAX78002 | | | | | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | 512 USB RAM | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | F415, F435_437, F423, | ✔ | ✔ | | dwc2 | | -| | F425, F45x | | | | | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Bridgetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Espressif | S2, S3, H4 | ✔ | ✔ | ✖ | dwc2 | | -| ESP32 +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | P4 | ✔ | ✔ | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | S31 | ✔ | ✔ | ✔ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| HPMicro | HPM6750 | ✔ | ✔ | ✔ | ci_hs, ehci | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | | -+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | D51, E5x | ✔ | | ✖ | samd | | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | G55 | ✔ | | ✖ | samg | 1-dir ep | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | -| +-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| | PIC | 24 | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | dsPIC33 | ✔ | | | pic | ci_fs variant | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | 32mz | ✔ | | | pic32mz | musb variant | -+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| MindMotion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | -+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| NordicSemi | nRF52, nRF53 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | nRF54 | ✔ | ✖ | ✔ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | NUC121/NUC125, NUC126 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | NUC505 | ✔ | | ✔ | nuc505 | | -+--------------+---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | | -| +---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | -| +---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | NRND, read errata | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | -| +---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | | -| | +-------------------+--------+------+-----------+------------------------+--------------------+ -| | | A15 | ✔ | | | ci_fs | | -| +---------+-------------------+--------+------+-----------+------------------------+--------------------+ -| | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | -+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | -| +-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | -| | +-----------------------+--------+------+-----------+------------------------+--------------------+ -| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | -+--------------+-----+-----------------------+--------+------+-----------+------------------------+--------------------+ -| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| ST STM32 | F0, F3, L0, L1, L5, WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+------------------------+--------------------+ -| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | 512 USB RAM | -| | +------------------------+--------+------+-----------+------------------------+--------------------+ -| | | 105, 107 | ✔ | ✔ | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+------------------------+--------------------+ -| | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | -| +----+------------------------+--------+------+-----------+------------------------+--------------------+ -| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | -| | +------------------------+--------+------+-----------+------------------------+--------------------+ -| | | 4x5, 4x6, 4+ | ✔ | ✔ | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+------------------------+--------------------+ -| | N6 | ✔ | ✔ | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | U0 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | -| +----+------------------------+--------+------+-----------+------------------------+--------------------+ -| | U5 | 535, 545 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | -| | +------------------------+--------+------+-----------+------------------------+--------------------+ -| | | 575, 585 | ✔ | ✔ | ✖ | dwc2 | | -| | +------------------------+--------+------+-----------+------------------------+--------------------+ -| | | 59x,5Ax,5Fx,5Gx | ✔ | ✔ | ✔ | dwc2 | | -+--------------+----+------------------------+--------+------+-----------+------------------------+--------------------+ -| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | MSP432E4, TM4C123 | ✔ | | ✖ | musb | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ -| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | Data loss possible | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | Data loss possible | -| +-----------------------------+--------+------+-----------+------------------------+--------------------+ -| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | Data loss possible | -+--------------+-----------------------------+--------+------+-----------+------------------------+--------------------+ ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Manufacturer | Family | Device | Host | Highspeed | Driver | Note | ++==============+=============================+========+======+===========+========================+=============================================+ +| Allwinner | F1C100s/F1C200s | ✔ | | ✔ | sunxi | musb variant | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Analog | MAX3421E | | ✔ | ✖ | max3421 | via SPI | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | MAX32 650, 666, 690, | ✔ | | ✔ | musb | 1-dir ep | +| | MAX78002 | | | | | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Artery AT32 | F403a_407, F413 | ✔ | | | fsdev | 512 USB RAM | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | F415, F435_437, F423, | ✔ | ✔ | | dwc2 | | +| | F425, F45x | | | | | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | F402_F405 | ✔ | ✔ | ✔ | dwc2 | F405 is HS | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Bridgetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Espressif | S2, S3, H4 | ✔ | ✔ | ✖ | dwc2 | | +| ESP32 +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | P4 | ✔ | ✔ | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | S31 | ✔ | ✔ | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| HPMicro | HPM6750 | ✔ | ✔ | ✔ | ci_hs, ehci | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Infineon | XMC4500 | ✔ | ✔ | ✖ | dwc2 | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| MicroChip | SAM | D11, D21, L21, L22 | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | D51, E5x | ✔ | | ✖ | samd | | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | G55 | ✔ | | ✖ | samg | 1-dir ep | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | E70,S70,V70,V71 | ✔ | | ✔ | samx7x | 1-dir ep | +| +-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | PIC | 24 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 32 mm, mk, mx | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | dsPIC33 | ✔ | | | pic | ci_fs variant | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 32mz | ✔ | | | pic32mz | musb variant | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| MindMotion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| NordicSemi | nRF52, nRF53 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | nRF54 | ✔ | ✖ | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | NUC121/NUC125, NUC126 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | NUC505 | ✔ | | ✔ | nuc505 | | ++--------------+---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs, ehci | | +| +---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | +| +---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40, ohci | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs, ehci | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | :ref:`NRND, read errata ` | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | +| +---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs, ehci | | +| | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | A15 | ✔ | | | ci_fs | | +| +---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | RW61x | ✔ | ✔ | ✔ | ci_hs, ehci | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Raspberry Pi | RP2040, RP2350 | ✔ | ✔ | ✖ | rp2040, pio_usb | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Renesas | RX | 63N, 65N, 72N | ✔ | ✔ | ✖ | rusb2 | | +| +-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | RA | 4M1, 4M3, 6M1 | ✔ | ✔ | ✖ | rusb2 | | +| | +-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 6M5 | ✔ | ✔ | ✔ | rusb2 | | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Silabs | EFM32GG12 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| Sony | CXD56 | ✔ | ✖ | ✔ | cxd56 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| ST STM32 | F0, F3, L0, L1, L5, WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | 512 USB RAM | +| | +------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 105, 107 | ✔ | ✔ | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | F2, F4, F7, H7, H7RS | ✔ | ✔ | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | C0, G0, H5, U3 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | +| +----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | +| | +------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 4x5, 4x6, 4+ | ✔ | ✔ | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | N6 | ✔ | ✔ | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | U0 | ✔ | ✖ | ✖ | stm32_fsdev | 1KB USB RAM | +| +----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | U5 | 535, 545 | ✔ | ✔ | ✖ | stm32_fsdev | 2KB USB RAM | +| | +------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 575, 585 | ✔ | ✔ | ✖ | dwc2 | | +| | +------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | ✔ | ✔ | dwc2 | | ++--------------+----+------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | MSP432E4, TM4C123 | ✔ | | ✖ | musb | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | :ref:`ISO data loss ` | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | :ref:`ISO data loss ` | +| +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ +| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | :ref:`ISO data loss ` | ++--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ Table Legend ^^^^^^^^^^^^ diff --git a/docs/index.rst b/docs/index.rst index 39d30a038..a8762c2c2 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,6 +10,7 @@ reference/index faq troubleshooting + reference/errata .. toctree:: :maxdepth: 1 diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index bb9f15166..531d471ed 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -76,6 +76,8 @@ Invalid board name in build command. Runtime Issues ============== +Check :doc:`reference/errata` for known hardware-specific issues that may affect USB functionality on your device. + Device Mode Problems -------------------- -- cgit v1.3.1 From 72006885c7a2fd20d123536d25db9fe1f154d9b3 Mon Sep 17 00:00:00 2001 From: hathach Date: Tue, 2 Jun 2026 15:24:31 +0700 Subject: add sponsor section --- README.rst | 70 +++++++++++++++++++++++++++++++++++-------- docs/assets/adafruit_logo.svg | 6 ++-- docs/assets/stack.svg | 2 +- 3 files changed, 62 insertions(+), 16 deletions(-) (limited to 'docs') diff --git a/README.rst b/README.rst index 04998abaa..ea33a2a53 100644 --- a/README.rst +++ b/README.rst @@ -1,12 +1,32 @@ TinyUSB ======= -|Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |Membrowse| |License| +|Sponsor| |Build Status| |CircleCI Status| |Documentation Status| |Static Analysis| |Fuzzing Status| |Membrowse| |License| + +Overview +-------- + +.. figure:: docs/assets/logo.svg + :alt: TinyUSB + :align: left + +.. raw:: html + +
+ +TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems. It’s designed for memory safety +(no dynamic allocation) and thread safety (all interrupts deferred to non-ISR task functions). The stack emphasizes portability, +small footprint, and real-time performance across 50+ MCU families. Sponsors -------- -TinyUSB is funded by: Adafruit. Purchasing products from them helps to support this project. +TinyUSB's continued development is made possible by its sponsors. If TinyUSB helps your products or projects, consider funding its development on `GitHub Sponsors`_. + +Platinum +^^^^^^^^ + +`Adafruit`_ has backed TinyUSB since day one as its founding and sole Platinum sponsor. Buying their products directly funds the project's development. .. figure:: docs/assets/adafruit_logo.svg :alt: Adafruit Logo @@ -17,20 +37,44 @@ TinyUSB is funded by: Adafruit. Purchasing products from them helps to support t
-Overview --------- +Sponsors (QWORD) +^^^^^^^^^^^^^^^^ -.. figure:: docs/assets/logo.svg - :alt: TinyUSB - :align: left +.. QWORD-SPONSORS-START -.. raw:: html +*No QWORD sponsors yet — be the first!* -
+.. QWORD-SPONSORS-END -TinyUSB is an open-source cross-platform USB Host/Device stack for embedded systems. It’s designed for memory safety -(no dynamic allocation) and thread safety (all interrupts deferred to non-ISR task functions). The stack emphasizes portability, -small footprint, and real-time performance across 50+ MCU families. +Backers (DWORD) +^^^^^^^^^^^^^^^ + +.. DWORD-BACKERS-START + +*No backers yet — be the first!* + +.. DWORD-BACKERS-END + +Supporters (Word) +^^^^^^^^^^^^^^^^^ + +.. WORD-SUPPORTERS-START + +*No supporters yet — be the first!* + +.. WORD-SUPPORTERS-END + +Thanks (Byte) +^^^^^^^^^^^^^ + +.. BYTE-THANKS-START + +*No names listed yet — be the first!* + +.. BYTE-THANKS-END + +.. _GitHub Sponsors: https://github.com/sponsors/hathach +.. _Adafruit: https://www.adafruit.com Key Features ------------ @@ -303,6 +347,8 @@ The following tools are provided freely to support the development of the TinyUS :target: https://membrowse.com/public/hathach/tinyusb .. |License| image:: https://img.shields.io/badge/license-MIT-brightgreen.svg :target: https://opensource.org/licenses/MIT +.. |Sponsor| image:: https://img.shields.io/badge/sponsor-%E2%9D%A4-ec6cb9.svg + :target: https://github.com/sponsors/hathach .. _Changelog: docs/info/changelog.rst diff --git a/docs/assets/adafruit_logo.svg b/docs/assets/adafruit_logo.svg index cafd5a10e..e978f2c6e 100644 --- a/docs/assets/adafruit_logo.svg +++ b/docs/assets/adafruit_logo.svg @@ -1,8 +1,8 @@ - + - + diff --git a/docs/assets/stack.svg b/docs/assets/stack.svg index ed46c8649..113c92b60 100644 --- a/docs/assets/stack.svg +++ b/docs/assets/stack.svg @@ -1 +1 @@ - + -- cgit v1.3.1 From e35b070dae92fd2750b8116a6ca0f1de393c7a6a Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Jun 2026 10:41:27 +0200 Subject: rename to device issues Signed-off-by: HiFiPhile --- README.rst | 8 ++++---- docs/index.rst | 2 +- docs/reference/device_issues.rst | 39 +++++++++++++++++++++++++++++++++++++++ docs/reference/index.rst | 1 + docs/troubleshooting.rst | 2 +- 5 files changed, 46 insertions(+), 6 deletions(-) create mode 100644 docs/reference/device_issues.rst (limited to 'docs') diff --git a/README.rst b/README.rst index c376599ec..e039c2b61 100644 --- a/README.rst +++ b/README.rst @@ -207,7 +207,7 @@ Supported CPUs | | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ | | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ -| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | :ref:`NRND, read errata ` | +| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | :ref:`NRND, read errata ` | | | +-------------------+--------+------+-----------+------------------------+---------------------------------------------+ | | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | | +---------+-------------------+--------+------+-----------+------------------------+---------------------------------------------+ @@ -261,11 +261,11 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ -| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | :ref:`ISO data loss ` | +| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | :ref:`ISO data loss ` | | +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ -| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | :ref:`ISO data loss ` | +| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | :ref:`ISO data loss ` | | +-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ -| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | :ref:`ISO data loss ` | +| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | :ref:`ISO data loss ` | +--------------+-----------------------------+--------+------+-----------+------------------------+---------------------------------------------+ Table Legend diff --git a/docs/index.rst b/docs/index.rst index a8762c2c2..b80804ad4 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,7 @@ reference/index faq troubleshooting - reference/errata + reference/device_issues .. toctree:: :maxdepth: 1 diff --git a/docs/reference/device_issues.rst b/docs/reference/device_issues.rst new file mode 100644 index 000000000..22677f967 --- /dev/null +++ b/docs/reference/device_issues.rst @@ -0,0 +1,39 @@ +Device specific known issues and workarounds +=============================================== +This page lists known issues and workarounds for specific devices. + +.. _LPC54600 Issues: + +NXP LPC54600 +---------------- +**Severity: High** + +**Not recommended for USB device applications (except high-speed host controller)** + +Reference: `LPC54600 Errata Sheet`_ + +.. _LPC54600 Errata Sheet: https://www.nxp.com/docs/en/errata/ES_LPC546XX.pdf + +The LPC54600 series have a very buggy USB controller, with totally 17 issues listed in the errata which is more than half of the total issues. + +Most severe issues are: + +- USB.2: In USB high-speed device mode, the NBytes field is not correct after BULK IN transfer +- USB.5: In USB full-speed host mode, linked list on done queue is broken. +- USB.15: USB high-speed device in endpoint TX data corruption + +.. _WCH CH32X Issues: + +WCH CH32V10X/CH32V20X/CH32V30X +--------------------------------- +**Severity: Medium** + +**Not recommended for USB audio applications** + +Reference: `CH32V30X Reference Manual`_ USBFS/USBHS controller chapter + +.. _CH32V30X Reference Manual: https://www.wch-ic.com/downloads/CH32FV2x_V3xRM_PDF.html + +Data corruption may occur on isochronous endpoints. Due to the lacking of FIFO for interrupt status registers, later completed transfer will overwrite `INT_ST` and `RX_LEN` register if previous transfer processing is not completed. + +Other types of transfers are not affected. diff --git a/docs/reference/index.rst b/docs/reference/index.rst index d3c96eeee..fe504627d 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -12,4 +12,5 @@ Complete reference documentation for TinyUSB APIs, configuration, and supported boards dependencies concurrency + device_issues glossary diff --git a/docs/troubleshooting.rst b/docs/troubleshooting.rst index 531d471ed..613c7fcef 100644 --- a/docs/troubleshooting.rst +++ b/docs/troubleshooting.rst @@ -76,7 +76,7 @@ Invalid board name in build command. Runtime Issues ============== -Check :doc:`reference/errata` for known hardware-specific issues that may affect USB functionality on your device. +Check :doc:`reference/device_issues` for known hardware-specific issues that may affect USB functionality on your device. Device Mode Problems -------------------- -- cgit v1.3.1 From 22c2ece872262c1331482f8e80881ab1f5f36c0b Mon Sep 17 00:00:00 2001 From: HiFiPhile Date: Tue, 2 Jun 2026 11:10:15 +0200 Subject: try to get render right Signed-off-by: HiFiPhile --- README.rst | 8 ++++---- docs/conf.py | 19 +++++++++++++++++++ 2 files changed, 23 insertions(+), 4 deletions(-) (limited to 'docs') diff --git a/README.rst b/README.rst index fac098c1c..ecfbeb7cc 100644 --- a/README.rst +++ b/README.rst @@ -251,7 +251,7 @@ Supported CPUs | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | `NRND, read errata `_ | +| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | `NRND, read errata `_ | | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | | +---------+-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ @@ -305,11 +305,11 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | `ISO data loss `_ | +| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | `ISO data loss `_ | | +-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | `ISO data loss `_ | +| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | `ISO data loss `_ | | +-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | `ISO data loss `_ | +| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | `ISO data loss `_ | +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ Table Legend diff --git a/docs/conf.py b/docs/conf.py index 9e9784fb7..86ddcf672 100755 --- a/docs/conf.py +++ b/docs/conf.py @@ -53,6 +53,25 @@ def preprocess_readme(): tgt = Path(__file__).parent.parent / "README_processed.rst" if src.exists(): content = src.read_text(encoding='utf-8') + # if the matching is inside a table, keep the table cell width by adding the same number of spaces in the end of the line + # match pattern: | ... `... `_ ... | + # change into: | ... `... <...>`_ ... | + def _rewrite_table_line(line): + if not (line.startswith('|') and line.rstrip().endswith('|')): + return line + + rewritten = re.sub(r"]+)>", r"<\1>", line) + delta = len(line) - len(rewritten) - 1 # -1 for rst->html + + if delta > 0: + last_pipe = rewritten.rfind('|') + if last_pipe >= 0: + rewritten = rewritten[:last_pipe] + (' ' * delta) + rewritten[last_pipe:] + + return rewritten + + content = ''.join(_rewrite_table_line(line) for line in content.splitlines(keepends=True)) + content = re.sub(r"docs/", r"", content) content = re.sub(r"\.rst\b", r".html", content) if not content.endswith("\n"): -- cgit v1.3.1 From ff3fef931dd2be604fd525814654d1cfcd7c725c Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:01:23 +0000 Subject: docs: fix review issues in device_issues and README MIME-Version: 1.0 Content-Type: text/plain; charset=UTF-8 Content-Transfer-Encoding: 8bit - Remove duplicate toctree entry for reference/device_issues from docs/index.rst (already included via docs/reference/index.rst) - Fix WCH section title: CH32V10X/CH32V20X/CH32V30X → CH32F20x/CH32V20x/CH32V30x to match the three actual README table entries (CH32F20x, CH32V20x, CH32V305/307) - Update README anchor links to match the renamed section - Qualify USBFS non-ISO transfer safety claim: USBHS is protected by USBHS_INT_BUSY_EN but USBFS behavior is not yet confirmed - Fix LPC54600 note: "read errata" → "see device issues" - Remove "totally" from LPC54600 description Co-authored-by: Ha Thach --- README.rst | 8 ++++---- docs/index.rst | 1 - docs/reference/device_issues.rst | 6 +++--- 3 files changed, 7 insertions(+), 8 deletions(-) (limited to 'docs') diff --git a/README.rst b/README.rst index ecfbeb7cc..67149a4f2 100644 --- a/README.rst +++ b/README.rst @@ -251,7 +251,7 @@ Supported CPUs | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | `NRND, read errata `_ | +| | | 54 | ⚠ | ⚠ | ✔ | lpc_ip3511, lpc_ip3516 | `NRND, see device issues `_ | | | +-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | | | 55 | ✔ | ✔ | ✔ | lpc_ip3511, lpc_ip3516 | | | +---------+-------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ @@ -305,11 +305,11 @@ Supported CPUs +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ | ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | `ISO data loss `_ | +| WCH | CH32F20x | ⚠ | | ✔ | ch32_usbhs | `ISO data loss `_ | | +-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | `ISO data loss `_ | +| | CH32V20x | ⚠ | | ✖ | stm32_fsdev/ch32_usbfs | `ISO data loss `_ | | +-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ -| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | `ISO data loss `_ | +| | CH32V305, CH32V307 | ⚠ | | ✔ | ch32_usbfs/hs | `ISO data loss `_ | +--------------+-----------------------------+--------+------+-----------+------------------------+-----------------------------------------------------------------------------------------+ Table Legend diff --git a/docs/index.rst b/docs/index.rst index b80804ad4..39d30a038 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -10,7 +10,6 @@ reference/index faq troubleshooting - reference/device_issues .. toctree:: :maxdepth: 1 diff --git a/docs/reference/device_issues.rst b/docs/reference/device_issues.rst index a69f6ba80..6dafe4de2 100644 --- a/docs/reference/device_issues.rst +++ b/docs/reference/device_issues.rst @@ -12,7 +12,7 @@ Reference: `LPC54600 Errata Sheet`_ .. _LPC54600 Errata Sheet: https://www.nxp.com/docs/en/errata/ES_LPC546XX.pdf -The LPC54600 series have a very buggy USB controller, with totally 17 issues listed in the errata which is more than half of the total issues. +The LPC54600 series have a very buggy USB controller, with 17 issues listed in the errata which is more than half of the total issues. Most severe issues are: @@ -20,7 +20,7 @@ Most severe issues are: - USB.5: In USB full-speed host mode, linked list on done queue is broken. - USB.15: USB high-speed device in endpoint TX data corruption -WCH CH32V10X/CH32V20X/CH32V30X +WCH CH32F20x/CH32V20x/CH32V30x --------------------------------- **Severity: Medium** @@ -32,4 +32,4 @@ Reference: `CH32V30X Reference Manual`_ USBFS/USBHS controller chapter Data corruption may occur on isochronous endpoints. Due to the lacking of FIFO for interrupt status registers, later completed transfer will overwrite `INT_ST` and `RX_LEN` register if previous transfer processing is not completed. -Other types of transfers are not affected. +For USBHS devices (CH32F20x, CH32V305/CH32V307), other transfer types are protected by the ``USBHS_INT_BUSY_EN`` mechanism which holds off new transfers while an interrupt is being processed. USBFS device behavior is not fully confirmed. -- cgit v1.3.1 From f19c01216fc5fc0f07789932df1db6fde82f525b Mon Sep 17 00:00:00 2001 From: "claude[bot]" <209825114+claude[bot]@users.noreply.github.com> Date: Tue, 2 Jun 2026 16:59:14 +0000 Subject: docs: revert USBFS non-ISO transfer qualification in device_issues Restore original "Other types of transfers are not affected" statement, removing the conditional USBHS_INT_BUSY_EN / USBFS-unconfirmed wording. Co-authored-by: Zixun LI --- docs/reference/device_issues.rst | 2 +- 1 file changed, 1 insertion(+), 1 deletion(-) (limited to 'docs') diff --git a/docs/reference/device_issues.rst b/docs/reference/device_issues.rst index 6dafe4de2..ae9cd55f1 100644 --- a/docs/reference/device_issues.rst +++ b/docs/reference/device_issues.rst @@ -32,4 +32,4 @@ Reference: `CH32V30X Reference Manual`_ USBFS/USBHS controller chapter Data corruption may occur on isochronous endpoints. Due to the lacking of FIFO for interrupt status registers, later completed transfer will overwrite `INT_ST` and `RX_LEN` register if previous transfer processing is not completed. -For USBHS devices (CH32F20x, CH32V305/CH32V307), other transfer types are protected by the ``USBHS_INT_BUSY_EN`` mechanism which holds off new transfers while an interrupt is being processed. USBFS device behavior is not fully confirmed. +Other types of transfers are not affected. -- cgit v1.3.1 From eda704ca1acef9691b51e17026765f497b1fffbe Mon Sep 17 00:00:00 2001 From: hathach Date: Mon, 22 Jun 2026 15:23:08 +0700 Subject: hw/bsp+wch: rename the CH58x family to ch583 and OPT_MCU_CH58X to OPT_MCU_CH583 The BSP family and MCU option were named "ch58x"/"CH58X", but the supported part is the CH583/CH582 (and the SDK repo is openwch/ch583); CH585 is a separate MCU family, so the CH58x umbrella was misleading. Rename to the specific family: - hw/bsp/ch58x -> hw/bsp/ch583 (dir), and the BSP-local files ch58x_it.* -> ch583_it.*, system_ch58x.* -> system_ch583.* (include guards/refs updated). The vendor SDK files (CH58x_common.h, CH58x_*.c in hw/mcu/wch/ch583) keep their names. - OPT_MCU_CH58X -> OPT_MCU_CH583 in tusb_option.h, tusb_mcu.h, and the shared WCH USBFS driver (ch32_usbfs_reg.h, dcd_ch32_usbfs.c). OPT_MCU_CH582 is kept as an alias (same value), so either name selects the same code. - FAMILY_MCUS CH58X -> CH583, CFG_TUSB_MCU=OPT_MCU_CH583, mcu:CH58X -> mcu:CH583 in the example skip lists, the CI build matrix (ci_set_matrix.py), the get_deps family tag, and docs/reference/boards.rst. Board names (ch582m_evt, yd-ch582m) are unchanged. Verified: make + cmake build for ch582m_evt, and ci.lan HIL (all device examples pass). Co-Authored-By: Claude Opus 4.8 (1M context) --- .github/workflows/ci_set_matrix.py | 2 +- docs/reference/boards.rst | 2 +- examples/device/audio_4_channel_mic/skip.txt | 2 +- .../device/audio_4_channel_mic_freertos/skip.txt | 2 +- examples/device/audio_test/skip.txt | 2 +- examples/device/audio_test_freertos/skip.txt | 2 +- examples/device/audio_test_multi_rate/skip.txt | 2 +- examples/device/cdc_msc_freertos/skip.txt | 2 +- examples/device/cdc_uac2/skip.txt | 2 +- examples/device/dfu_runtime/skip.txt | 1 + examples/device/hid_boot_interface/skip.txt | 1 + examples/device/hid_composite/skip.txt | 1 + examples/device/hid_composite_freertos/skip.txt | 2 +- examples/device/hid_generic_inout/skip.txt | 1 + examples/device/hid_multiple_interface/skip.txt | 1 + examples/device/midi_test/skip.txt | 1 + examples/device/midi_test_freertos/skip.txt | 2 +- examples/device/uac2_headset/skip.txt | 2 +- examples/device/uac2_speaker_fb/skip.txt | 2 +- examples/device/video_capture/skip.txt | 2 +- examples/device/video_capture_2ch/skip.txt | 2 +- examples/device/webusb_serial/skip.txt | 1 + hw/bsp/ch583/boards/ch582m_evt/board.cmake | 5 + hw/bsp/ch583/boards/ch582m_evt/board.h | 61 +++++++ hw/bsp/ch583/boards/ch582m_evt/board.mk | 3 + hw/bsp/ch583/boards/yd-ch582m/board.cmake | 5 + hw/bsp/ch583/boards/yd-ch582m/board.h | 61 +++++++ hw/bsp/ch583/boards/yd-ch582m/board.mk | 3 + hw/bsp/ch583/ch583_it.c | 37 ++++ hw/bsp/ch583/ch583_it.h | 46 +++++ hw/bsp/ch583/debug_uart.c | 86 +++++++++ hw/bsp/ch583/debug_uart.h | 44 +++++ hw/bsp/ch583/family.c | 194 +++++++++++++++++++++ hw/bsp/ch583/family.cmake | 108 ++++++++++++ hw/bsp/ch583/family.mk | 59 +++++++ hw/bsp/ch583/linker/ch582.ld | 167 ++++++++++++++++++ hw/bsp/ch583/system_ch583.c | 39 +++++ hw/bsp/ch583/system_ch583.h | 43 +++++ hw/bsp/ch583/wch-riscv.cfg | 17 ++ hw/bsp/ch58x/boards/ch582m_evt/board.cmake | 5 - hw/bsp/ch58x/boards/ch582m_evt/board.h | 61 ------- hw/bsp/ch58x/boards/ch582m_evt/board.mk | 3 - hw/bsp/ch58x/boards/yd-ch582m/board.cmake | 5 - hw/bsp/ch58x/boards/yd-ch582m/board.h | 61 ------- hw/bsp/ch58x/boards/yd-ch582m/board.mk | 3 - hw/bsp/ch58x/ch58x_it.c | 37 ---- hw/bsp/ch58x/ch58x_it.h | 46 ----- hw/bsp/ch58x/debug_uart.c | 86 --------- hw/bsp/ch58x/debug_uart.h | 44 ----- hw/bsp/ch58x/family.c | 194 --------------------- hw/bsp/ch58x/family.cmake | 108 ------------ hw/bsp/ch58x/family.mk | 59 ------- hw/bsp/ch58x/linker/ch582.ld | 167 ------------------ hw/bsp/ch58x/system_ch58x.c | 39 ----- hw/bsp/ch58x/system_ch58x.h | 43 ----- hw/bsp/ch58x/wch-riscv.cfg | 17 -- src/common/tusb_mcu.h | 2 +- src/portable/wch/ch32_usbfs_reg.h | 2 +- src/portable/wch/dcd_ch32_usbfs.c | 16 +- src/tusb_option.h | 2 +- tools/get_deps.py | 2 +- 61 files changed, 1012 insertions(+), 1005 deletions(-) create mode 100644 examples/device/dfu_runtime/skip.txt create mode 100644 examples/device/hid_boot_interface/skip.txt create mode 100644 examples/device/hid_composite/skip.txt create mode 100644 examples/device/hid_generic_inout/skip.txt create mode 100644 examples/device/hid_multiple_interface/skip.txt create mode 100644 examples/device/midi_test/skip.txt create mode 100644 examples/device/webusb_serial/skip.txt create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.cmake create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.h create mode 100644 hw/bsp/ch583/boards/ch582m_evt/board.mk create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.cmake create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.h create mode 100644 hw/bsp/ch583/boards/yd-ch582m/board.mk create mode 100644 hw/bsp/ch583/ch583_it.c create mode 100644 hw/bsp/ch583/ch583_it.h create mode 100644 hw/bsp/ch583/debug_uart.c create mode 100644 hw/bsp/ch583/debug_uart.h create mode 100644 hw/bsp/ch583/family.c create mode 100644 hw/bsp/ch583/family.cmake create mode 100644 hw/bsp/ch583/family.mk create mode 100644 hw/bsp/ch583/linker/ch582.ld create mode 100644 hw/bsp/ch583/system_ch583.c create mode 100644 hw/bsp/ch583/system_ch583.h create mode 100644 hw/bsp/ch583/wch-riscv.cfg delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.cmake delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.h delete mode 100644 hw/bsp/ch58x/boards/ch582m_evt/board.mk delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.cmake delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.h delete mode 100644 hw/bsp/ch58x/boards/yd-ch582m/board.mk delete mode 100644 hw/bsp/ch58x/ch58x_it.c delete mode 100644 hw/bsp/ch58x/ch58x_it.h delete mode 100644 hw/bsp/ch58x/debug_uart.c delete mode 100644 hw/bsp/ch58x/debug_uart.h delete mode 100644 hw/bsp/ch58x/family.c delete mode 100644 hw/bsp/ch58x/family.cmake delete mode 100644 hw/bsp/ch58x/family.mk delete mode 100644 hw/bsp/ch58x/linker/ch582.ld delete mode 100644 hw/bsp/ch58x/system_ch58x.c delete mode 100644 hw/bsp/ch58x/system_ch58x.h delete mode 100644 hw/bsp/ch58x/wch-riscv.cfg (limited to 'docs') diff --git a/.github/workflows/ci_set_matrix.py b/.github/workflows/ci_set_matrix.py index 400f319d3..dc0d3871f 100755 --- a/.github/workflows/ci_set_matrix.py +++ b/.github/workflows/ci_set_matrix.py @@ -30,7 +30,7 @@ family_list = { "ch32v10x": ["riscv-gcc"], "ch32v20x": ["riscv-gcc"], "ch32v30x": ["riscv-gcc"], - "ch58x": ["riscv-gcc"], + "ch583": ["riscv-gcc"], "da1469x": ["arm-gcc"], "fomu": ["riscv-gcc"], "ft9xx": ["ft9xx-gcc"], diff --git a/docs/reference/boards.rst b/docs/reference/boards.rst index 7ea9c228b..8a83496a4 100644 --- a/docs/reference/boards.rst +++ b/docs/reference/boards.rst @@ -370,5 +370,5 @@ ch32v203g_r0_1v0 CH32V203G-R0-1v0 ch32v20x https://github.com/openwch/ch32v20 nanoch32v203 nanoCH32V203 ch32v20x https://github.com/wuxx/nanoCH32V203 ch32v307v_r1_1v0 CH32V307V-R1-1v0 ch32v30x https://github.com/openwch/ch32v307/tree/main/SCHPCB/CH32V307V-R1-1v0 nanoch32v305 nanoCH32V305 ch32v30x https://github.com/wuxx/nanoCH32V305 -yd-ch582m yd-ch582m ch58x http://vcc-gnd.com +yd-ch582m yd-ch582m ch583 http://vcc-gnd.com ================ ================ ======== ===================================================================== ====== diff --git a/examples/device/audio_4_channel_mic/skip.txt b/examples/device/audio_4_channel_mic/skip.txt index 8c64832f7..3ca433c08 100644 --- a/examples/device/audio_4_channel_mic/skip.txt +++ b/examples/device/audio_4_channel_mic/skip.txt @@ -3,4 +3,4 @@ mcu:SAME5X mcu:SAMG family:broadcom_64bit family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/audio_4_channel_mic_freertos/skip.txt b/examples/device/audio_4_channel_mic_freertos/skip.txt index dae0a5428..1fd6b4b8a 100644 --- a/examples/device/audio_4_channel_mic_freertos/skip.txt +++ b/examples/device/audio_4_channel_mic_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/audio_test/skip.txt b/examples/device/audio_test/skip.txt index 6e3082a54..42394bb11 100644 --- a/examples/device/audio_test/skip.txt +++ b/examples/device/audio_test/skip.txt @@ -2,4 +2,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/audio_test_freertos/skip.txt b/examples/device/audio_test_freertos/skip.txt index 20deaca28..660bacd25 100644 --- a/examples/device/audio_test_freertos/skip.txt +++ b/examples/device/audio_test_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/audio_test_multi_rate/skip.txt b/examples/device/audio_test_multi_rate/skip.txt index 6e3082a54..42394bb11 100644 --- a/examples/device/audio_test_multi_rate/skip.txt +++ b/examples/device/audio_test_multi_rate/skip.txt @@ -2,4 +2,4 @@ mcu:SAMD11 mcu:SAME5X mcu:SAMG family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/cdc_msc_freertos/skip.txt b/examples/device/cdc_msc_freertos/skip.txt index 197060eeb..48781de84 100644 --- a/examples/device/cdc_msc_freertos/skip.txt +++ b/examples/device/cdc_msc_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/cdc_uac2/skip.txt b/examples/device/cdc_uac2/skip.txt index 4222d08c6..db1d5b80b 100644 --- a/examples/device/cdc_uac2/skip.txt +++ b/examples/device/cdc_uac2/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/dfu_runtime/skip.txt b/examples/device/dfu_runtime/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/dfu_runtime/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_boot_interface/skip.txt b/examples/device/hid_boot_interface/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_boot_interface/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_composite/skip.txt b/examples/device/hid_composite/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_composite/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_composite_freertos/skip.txt b/examples/device/hid_composite_freertos/skip.txt index fccddabcd..97d8e168b 100644 --- a/examples/device/hid_composite_freertos/skip.txt +++ b/examples/device/hid_composite_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/hid_generic_inout/skip.txt b/examples/device/hid_generic_inout/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_generic_inout/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/hid_multiple_interface/skip.txt b/examples/device/hid_multiple_interface/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/hid_multiple_interface/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/midi_test/skip.txt b/examples/device/midi_test/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/midi_test/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/examples/device/midi_test_freertos/skip.txt b/examples/device/midi_test_freertos/skip.txt index fccddabcd..97d8e168b 100644 --- a/examples/device/midi_test_freertos/skip.txt +++ b/examples/device/midi_test_freertos/skip.txt @@ -2,7 +2,7 @@ mcu:CH32F20X mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:CXD56 mcu:F1C100S mcu:GD32VF103 diff --git a/examples/device/uac2_headset/skip.txt b/examples/device/uac2_headset/skip.txt index 4222d08c6..db1d5b80b 100644 --- a/examples/device/uac2_headset/skip.txt +++ b/examples/device/uac2_headset/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:espressif -mcu:CH58X +mcu:CH583 diff --git a/examples/device/uac2_speaker_fb/skip.txt b/examples/device/uac2_speaker_fb/skip.txt index 48a484f96..0c7339c65 100644 --- a/examples/device/uac2_speaker_fb/skip.txt +++ b/examples/device/uac2_speaker_fb/skip.txt @@ -6,4 +6,4 @@ mcu:SAME5X mcu:SAMG board:stm32l052dap52 family:broadcom_64bit -mcu:CH58X +mcu:CH583 diff --git a/examples/device/video_capture/skip.txt b/examples/device/video_capture/skip.txt index 7f000d472..5a7a1d00e 100644 --- a/examples/device/video_capture/skip.txt +++ b/examples/device/video_capture/skip.txt @@ -1,6 +1,6 @@ mcu:CH32V103 mcu:CH32V20X -mcu:CH58X +mcu:CH583 mcu:MSP430x5xx mcu:NUC121 mcu:SAMD11 diff --git a/examples/device/video_capture_2ch/skip.txt b/examples/device/video_capture_2ch/skip.txt index 191edeb39..c37205b8c 100644 --- a/examples/device/video_capture_2ch/skip.txt +++ b/examples/device/video_capture_2ch/skip.txt @@ -5,7 +5,7 @@ mcu:GD32VF103 mcu:CH32V103 mcu:CH32V20X mcu:CH32V307 -mcu:CH58X +mcu:CH583 mcu:STM32L0 family:espressif board:curiosity_nano diff --git a/examples/device/webusb_serial/skip.txt b/examples/device/webusb_serial/skip.txt new file mode 100644 index 000000000..2c6c2a64c --- /dev/null +++ b/examples/device/webusb_serial/skip.txt @@ -0,0 +1 @@ +family:espressif diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.cmake b/hw/bsp/ch583/boards/ch582m_evt/board.cmake new file mode 100644 index 000000000..4129c4550 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.cmake @@ -0,0 +1,5 @@ +set(LD_FLASH_SIZE 448K) +set(LD_RAM_SIZE 32K) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.h b/hw/bsp/ch583/boards/ch582m_evt/board.h new file mode 100644 index 000000000..c3483bf17 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.h @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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. + */ + +/* metadata: + name: CH582M-EVT evaluation board + url: https://www.wch-ic.com/products/CH582.html +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// LED: PB4 on CH582M-EVT +#define LED_PIN GPIO_Pin_4 +#define LED_STATE_ON 0 + +// Directly reuse BOOT pin as user button +#define BUTTON_PIN GPIO_Pin_22 +#define BUTTON_STATE_ACTIVE 0 + +// UART: UART1 TX=PA9, RX=PA8 +#define CFG_BOARD_UART_BAUDRATE 115200 + +// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; +// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif +// #ifndef BOARD_TUH_RHPORT +// #define BOARD_TUH_RHPORT 1 +// #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch583/boards/ch582m_evt/board.mk b/hw/bsp/ch583/boards/ch582m_evt/board.mk new file mode 100644 index 000000000..a13979799 --- /dev/null +++ b/hw/bsp/ch583/boards/ch582m_evt/board.mk @@ -0,0 +1,3 @@ +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=448K \ + -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.cmake b/hw/bsp/ch583/boards/yd-ch582m/board.cmake new file mode 100644 index 000000000..4129c4550 --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.cmake @@ -0,0 +1,5 @@ +set(LD_FLASH_SIZE 448K) +set(LD_RAM_SIZE 32K) + +function(update_board TARGET) +endfunction() diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.h b/hw/bsp/ch583/boards/yd-ch582m/board.h new file mode 100644 index 000000000..0da5747bc --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.h @@ -0,0 +1,61 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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. + */ + +/* metadata: + name: yd-ch582m from vcc-gnd studio + url: http://vcc-gnd.com/ +*/ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +// LED: PB4 on yd-ch582m board +#define LED_PIN GPIO_Pin_4 +#define LED_STATE_ON 0 + +// Directly reuse BOOT pin as user button +#define BUTTON_PIN GPIO_Pin_22 +#define BUTTON_STATE_ACTIVE 0 + +// UART: UART1 TX=PA9, RX=PA8 +#define CFG_BOARD_UART_BAUDRATE 115200 + +// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; +// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. +#ifndef BOARD_TUD_RHPORT +#define BOARD_TUD_RHPORT 0 +#endif +// #ifndef BOARD_TUH_RHPORT +// #define BOARD_TUH_RHPORT 1 +// #endif + +#ifdef __cplusplus +} +#endif + +#endif diff --git a/hw/bsp/ch583/boards/yd-ch582m/board.mk b/hw/bsp/ch583/boards/yd-ch582m/board.mk new file mode 100644 index 000000000..a13979799 --- /dev/null +++ b/hw/bsp/ch583/boards/yd-ch582m/board.mk @@ -0,0 +1,3 @@ +LDFLAGS += \ + -Wl,--defsym=__FLASH_SIZE=448K \ + -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch583/ch583_it.c b/hw/bsp/ch583/ch583_it.c new file mode 100644 index 000000000..8479c537a --- /dev/null +++ b/hw/bsp/ch583/ch583_it.c @@ -0,0 +1,37 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 "ch583_it.h" + +// NMI exception handler +__INTERRUPT __HIGH_CODE void NMI_Handler(void) { + while (1) {} +} + +// Hard Fault exception handler +__INTERRUPT __HIGH_CODE void HardFault_Handler(void) { + while (1) {} +} diff --git a/hw/bsp/ch583/ch583_it.h b/hw/bsp/ch583/ch583_it.h new file mode 100644 index 000000000..29d175403 --- /dev/null +++ b/hw/bsp/ch583/ch583_it.h @@ -0,0 +1,46 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 CH583_IT_H_ +#define CH583_IT_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +#include "CH58x_common.h" + +void NMI_Handler(void); +void HardFault_Handler(void); +void USB_IRQHandler(void); +// void USB2_IRQHandler(void); // host on USB2 (rhport 1) — re-add together with the host driver +void SysTick_Handler(void); + +#ifdef __cplusplus +} +#endif + +#endif /* CH583_IT_H_ */ diff --git a/hw/bsp/ch583/debug_uart.c b/hw/bsp/ch583/debug_uart.c new file mode 100644 index 000000000..850e40718 --- /dev/null +++ b/hw/bsp/ch583/debug_uart.c @@ -0,0 +1,86 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 "debug_uart.h" +#include "CH58x_common.h" + +//--------------------------------------------------------------------+ +// Ring buffer based UART TX for non-blocking writes +//--------------------------------------------------------------------+ + +#define UART_RINGBUFFER_SIZE_TX 128 +#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX - 1) + +static char tx_buf[UART_RINGBUFFER_SIZE_TX]; +static uint32_t tx_produce; +static volatile uint32_t tx_consume; + +void uart_write(char c) { + uint32_t tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; + + // If the ring buffer is full, drain it here as the FIFO frees up: nothing else advances + // tx_consume between uart_write() calls, so a plain spin would deadlock on a >buffer-size burst. + while (tx_produce_next == tx_consume) { + if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { + R8_UART1_THR = tx_buf[tx_consume]; + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + + // If UART TX FIFO is empty and no pending data, send directly + if ((tx_consume == tx_produce) && (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP)) { + R8_UART1_THR = c; + } else { + tx_buf[tx_produce] = c; + tx_produce = tx_produce_next; + } +} + +void uart_sync(void) { + // Wait for ring buffer to drain + while (tx_consume != tx_produce) { + if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { + R8_UART1_THR = tx_buf[tx_consume]; + tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; + } + } + // Wait for last byte to finish transmitting + while (!(R8_UART1_LSR & RB_LSR_TX_ALL_EMP)) {} +} + +void usart_printf_init(uint32_t baudrate) { + tx_produce = 0; + tx_consume = 0; + + // Configure UART1 pins: TX=PA9, RX=PA8 + GPIOA_SetBits(GPIO_Pin_9); + GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); + GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); + + // Init UART1 with specified baud rate + UART1_DefInit(); + UART1_BaudRateCfg(baudrate); +} diff --git a/hw/bsp/ch583/debug_uart.h b/hw/bsp/ch583/debug_uart.h new file mode 100644 index 000000000..44c3e7948 --- /dev/null +++ b/hw/bsp/ch583/debug_uart.h @@ -0,0 +1,44 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 DEBUG_UART_H_ +#define DEBUG_UART_H_ + +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void uart_write(char c); +void uart_sync(void); +void usart_printf_init(uint32_t baudrate); + +#ifdef __cplusplus +} +#endif + +#endif /* DEBUG_UART_H_ */ diff --git a/hw/bsp/ch583/family.c b/hw/bsp/ch583/family.c new file mode 100644 index 000000000..716e2b76b --- /dev/null +++ b/hw/bsp/ch583/family.c @@ -0,0 +1,194 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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. + */ + +/* metadata: + manufacturer: WCH +*/ + +// WCH SDK's DEBUG macro enables a _write() that conflicts with TinyUSB's. +// TinyUSB uses UART1 for printf via debug_uart.c, so DEBUG is not needed. +// If you need a different UART or want to keep SDK's DEBUG, modify +// debug_uart.c (TinyUSB side) or CH58x_sys.c (SDK side) to remove one _write(). +// If done, remove this #error to continue. +#ifdef DEBUG + #error "Remove the DEBUG macro from preprocessor defines to avoid " \ + "duplicate _write() between WCH SDK and TinyUSB. " \ + "TinyUSB uses UART1 by default (see debug_uart.c)." +#endif + +#include "debug_uart.h" +#include "CH58x_common.h" +#include "ch583_it.h" + +#include "bsp/board_api.h" +#include "board.h" + +//--------------------------------------------------------------------+ +// Forward USB interrupt events to TinyUSB IRQ Handler +//--------------------------------------------------------------------+ + +// Device only: the shared dcd_ch32_usbfs.c drives USB0 (rhport 0). CH58x's second controller +// (USB2 / rhport 1) was driven by the now-removed ch58x host driver; its handler is kept +// commented out below to ease re-adding host support. +__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) { + tusb_int_handler(0, true); +} + +// __INTERRUPT __HIGH_CODE void USB2_IRQHandler(void) { +// tusb_int_handler(1, true); +// } + +//--------------------------------------------------------------------+ +// SysTick +//--------------------------------------------------------------------+ + +#if CFG_TUSB_OS == OPT_OS_NONE +volatile uint32_t system_ticks = 0; + +__INTERRUPT __HIGH_CODE void SysTick_Handler(void) { + SysTick->SR = 0; + system_ticks++; +} + +uint32_t tusb_time_millis_api(void) { + return system_ticks; +} +#endif + +//--------------------------------------------------------------------+ +// Board Init +//--------------------------------------------------------------------+ + +void board_init(void) { + // Disable interrupts during init + PFIC_DisableAllIRQ(); + + // Set system clock to PLL 60MHz (default for CH582) + SetSysClock(CLK_SOURCE_PLL_60MHz); + +#if CFG_TUSB_OS == OPT_OS_NONE + SysTick_Config(GetSysClock() / 1000); +#endif + + // UART1 init for debug output +#ifdef CFG_BOARD_UART_BAUDRATE + usart_printf_init(CFG_BOARD_UART_BAUDRATE); +#endif + + // LED +#ifdef LED_PORT_IS_A + GPIOA_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); +#else + GPIOB_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); +#endif + + // Button +#ifdef BUTTON_PIN + #ifdef BUTTON_PORT_IS_A + GPIOA_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); + #else + GPIOB_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); + #endif +#endif + + // Device only on USB0 (rhport 0): enable analog function for USB1 D+/D- and assert its D+ + // pull-up. The shared dcd_ch32_usbfs.c drives USB0; CH58x host / USB2 (rhport 1) is unsupported + // here — to re-add host, also OR in RB_PIN_USB2_IE below. + R16_PIN_ANALOG_IE |= RB_PIN_USB_IE; // | RB_PIN_USB2_IE (re-add for host on USB2) +#if CFG_TUD_ENABLED + R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU; +#endif + + // Keep USB clock active during sleep + R8_SLP_CLK_OFF1 &= ~RB_SLP_CLK_USB; + + // Enable interrupts globally + PFIC_EnableAllIRQ(); + + board_delay(2); +} + +//--------------------------------------------------------------------+ +// Board porting API +//--------------------------------------------------------------------+ + +void board_led_write(bool state) { +#ifdef LED_PORT_IS_A + if (state ^ LED_STATE_ON) { + GPIOA_ResetBits(LED_PIN); + } else { + GPIOA_SetBits(LED_PIN); + } +#else + if (state ^ LED_STATE_ON) { + GPIOB_ResetBits(LED_PIN); + } else { + GPIOB_SetBits(LED_PIN); + } +#endif +} + +uint32_t board_button_read(void) { +#ifdef BUTTON_PIN + #ifdef BUTTON_PORT_IS_A + return BUTTON_STATE_ACTIVE == (GPIOA_ReadPortPin(BUTTON_PIN) ? 1 : 0); + #else + return BUTTON_STATE_ACTIVE == (GPIOB_ReadPortPin(BUTTON_PIN) ? 1 : 0); + #endif +#else + return 0; +#endif +} + +// CH58x has no memory-mapped unique-ID register (unlike ch32v10x/v20x at 0x1FFFF7E8), but the +// factory programs a unique 6-byte MAC address into FlashROM (it is a BLE part). GetMACAddress() +// reads it via the ISP ROM command FLASH_EEPROM_CMD, which is provided by libISP583.a. +size_t board_get_unique_id(uint8_t id[], size_t max_len) { + // FLASH_EEPROM_CMD writes word-granular and requires a 4-byte-aligned buffer (CH58x_flash.c); + // size 8 matches the SDK's GET_UNIQUE_ID buffer (6 MAC bytes + 2 it pads), so the read can't + // run past the end whether it returns 6 or a full 8. + TU_ATTR_ALIGNED(4) uint8_t mac[8]; + GetMACAddress(mac); + size_t len = TU_MIN(max_len, (size_t) 6); // the 6-byte MAC is the unique part + memcpy(id, mac, len); + return len; +} + +int board_uart_read(uint8_t* buf, int len) { + (void) buf; + (void) len; + return 0; +} + +int board_uart_write(void const* buf, int len) { + int txsize = len; + const char* bufc = (const char*) buf; + while (txsize--) { + uart_write(*bufc++); + } + uart_sync(); + return len; +} diff --git a/hw/bsp/ch583/family.cmake b/hw/bsp/ch583/family.cmake new file mode 100644 index 000000000..a379298e5 --- /dev/null +++ b/hw/bsp/ch583/family.cmake @@ -0,0 +1,108 @@ +include_guard() + +set(SDK_DIR ${TOP}/hw/mcu/wch/ch583) +set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) + +# include board specific +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +# toolchain set up +set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") +set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) + +set(FAMILY_MCUS CH583 CACHE INTERNAL "") +set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") + +#------------------------------------ +# Startup & Linker script +#------------------------------------ +if (NOT DEFINED LD_FILE_GNU) + set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch582.ld) +endif () +set(LD_FILE_Clang ${LD_FILE_GNU}) +if (NOT DEFINED STARTUP_FILE_GNU) + set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_CH583.S) +endif () +set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) + +#------------------------------------ +# Board Target +#------------------------------------ +function(family_add_board BOARD_TARGET) + add_library(${BOARD_TARGET} STATIC + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_gpio.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_clk.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_uart1.c + ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_sys.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch583_it.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch583.c + ) + target_include_directories(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/RVMSIS + ${SDK_SRC_DIR}/StdPeriphDriver/inc + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ) + target_link_libraries(${BOARD_TARGET} PUBLIC + ${SDK_SRC_DIR}/StdPeriphDriver/libISP583.a + ) + target_compile_definitions(${BOARD_TARGET} PUBLIC + CFG_TUD_WCH_USBIP_USBFS=1 + FREQ_SYS=60000000 + DISK_LIB_ENABLE=0 + INT_SOFT + ) + + update_board(${BOARD_TARGET}) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_compile_options(${BOARD_TARGET} PUBLIC + -flto + -msmall-data-limit=16 + -mno-save-restore + -fmessage-length=0 + -fsigned-char + -Wno-error=strict-prototypes + ) + endif () +endfunction() + +#------------------------------------ +# Functions +#------------------------------------ +function(family_configure_example TARGET RTOS) + family_configure_common(${TARGET} ${RTOS}) + family_add_tinyusb(${TARGET} OPT_MCU_CH583) + + target_sources(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c + ${TOP}/src/portable/wch/dcd_ch32_usbfs.c + ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} + ) + target_include_directories(${TARGET} PUBLIC + ${CMAKE_CURRENT_FUNCTION_LIST_DIR} + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ + ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} + ) + + if (CMAKE_C_COMPILER_ID STREQUAL "GNU") + target_link_options(${TARGET} PUBLIC + -nostartfiles + --specs=nosys.specs --specs=nano.specs + -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} + -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} + "LINKER:--script=${LD_FILE_GNU}" + ) + elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") + message(FATAL_ERROR "Clang is not supported for CH58x") + endif () + + set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES + SKIP_LINTING ON + COMPILE_OPTIONS -w) + + # Flashing + family_add_bin_hex(${TARGET}) + family_flash_openocd_wch(${TARGET}) +endfunction() diff --git a/hw/bsp/ch583/family.mk b/hw/bsp/ch583/family.mk new file mode 100644 index 000000000..98d0f9337 --- /dev/null +++ b/hw/bsp/ch583/family.mk @@ -0,0 +1,59 @@ +# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable +#CROSS_COMPILE ?= riscv32-unknown-elf- + +# Toolchain from https://nucleisys.com/download.php +#CROSS_COMPILE ?= riscv-nuclei-elf- + +# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack +CROSS_COMPILE ?= riscv-none-elf- + +SDK_DIR = hw/mcu/wch/ch583 +SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC + +include $(TOP)/$(BOARD_PATH)/board.mk +CPU_CORE ?= rv32imac-ilp32 + +CFLAGS += \ + -flto \ + -msmall-data-limit=16 \ + -mno-save-restore \ + -fmessage-length=0 \ + -fsigned-char \ + -DCFG_TUSB_MCU=OPT_MCU_CH583 \ + -DCFG_TUD_WCH_USBIP_USBFS=1 \ + -DFREQ_SYS=60000000 \ + -DDISK_LIB_ENABLE=0 \ + -DINT_SOFT \ + -Wno-error=strict-prototypes + +LDFLAGS += \ + -nostartfiles \ + --specs=nosys.specs --specs=nano.specs + +LIBS += $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/libISP583.a + +SRC_C += \ + src/portable/wch/dcd_ch32_usbfs.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_gpio.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_clk.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_uart1.c \ + $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_sys.c \ + $(FAMILY_PATH)/debug_uart.c \ + $(FAMILY_PATH)/ch583_it.c \ + $(FAMILY_PATH)/system_ch583.c + +SRC_S += \ + $(SDK_SRC_DIR)/Startup/startup_CH583.S + +INC += \ + $(TOP)/$(BOARD_PATH) \ + $(TOP)/$(SDK_SRC_DIR)/RVMSIS \ + $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/inc + +LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld + +OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg +flash: flash-openocd-wch + +# For freeRTOS port source +FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch583/linker/ch582.ld b/hw/bsp/ch583/linker/ch582.ld new file mode 100644 index 000000000..821998a49 --- /dev/null +++ b/hw/bsp/ch583/linker/ch582.ld @@ -0,0 +1,167 @@ +/* CH582 Linker Script for TinyUSB + * Based on WCH CH583 SDK Link.ld + * Supports parameterized flash/ram sizes via --defsym + */ + +/* Default sizes if not provided via --defsym */ +__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 448K; +__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K; +__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; + +ENTRY( _start ) + +PROVIDE( _stack_size = __stack_size ); + +MEMORY +{ + FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size + RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size +} + +SECTIONS +{ + .init : + { + _sinit = .; + . = ALIGN(4); + KEEP(*(SORT_NONE(.init))) + . = ALIGN(4); + _einit = .; + } >FLASH AT>FLASH + + .highcodelalign : + { + . = ALIGN(4); + PROVIDE(_highcode_lma = .); + } >FLASH AT>FLASH + + .highcode : + { + . = ALIGN(4); + PROVIDE(_highcode_vma_start = .); + *(.vector); + KEEP(*(SORT_NONE(.vector_handler))) + *(.highcode); + *(.highcode.*); + . = ALIGN(4); + PROVIDE(_highcode_vma_end = .); + } >RAM AT>FLASH + + .text : + { + . = ALIGN(4); + KEEP(*(SORT_NONE(.handle_reset))) + *(.text) + *(.text.*) + *(.rodata) + *(.rodata*) + *(.sdata2.*) + *(.glue_7) + *(.glue_7t) + *(.gnu.linkonce.t.*) + . = ALIGN(4); + } >FLASH AT>FLASH + + .fini : + { + KEEP(*(SORT_NONE(.fini))) + . = ALIGN(4); + } >FLASH AT>FLASH + + PROVIDE( _etext = . ); + PROVIDE( _eitcm = . ); + + .preinit_array : + { + PROVIDE_HIDDEN (__preinit_array_start = .); + KEEP (*(.preinit_array)) + PROVIDE_HIDDEN (__preinit_array_end = .); + } >FLASH AT>FLASH + + .init_array : + { + PROVIDE_HIDDEN (__init_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) + KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) + PROVIDE_HIDDEN (__init_array_end = .); + } >FLASH AT>FLASH + + .fini_array : + { + PROVIDE_HIDDEN (__fini_array_start = .); + KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) + KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) + PROVIDE_HIDDEN (__fini_array_end = .); + } >FLASH AT>FLASH + + .ctors : + { + KEEP (*crtbegin.o(.ctors)) + KEEP (*crtbegin?.o(.ctors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) + KEEP (*(SORT(.ctors.*))) + KEEP (*(.ctors)) + } >FLASH AT>FLASH + + .dtors : + { + KEEP (*crtbegin.o(.dtors)) + KEEP (*crtbegin?.o(.dtors)) + KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) + KEEP (*(SORT(.dtors.*))) + KEEP (*(.dtors)) + } >FLASH AT>FLASH + + .dlalign : + { + . = ALIGN(4); + PROVIDE(_data_lma = .); + } >FLASH AT>FLASH + + .data : + { + . = ALIGN(4); + PROVIDE(_data_vma = .); + *(.gnu.linkonce.r.*) + *(.data .data.*) + *(.gnu.linkonce.d.*) + . = ALIGN(8); + PROVIDE( __global_pointer$ = . + 0x800 ); + *(.sdata .sdata.*) + *(.gnu.linkonce.s.*) + . = ALIGN(8); + *(.srodata.cst16) + *(.srodata.cst8) + *(.srodata.cst4) + *(.srodata.cst2) + *(.srodata .srodata.*) + . = ALIGN(4); + PROVIDE( _edata = .); + } >RAM AT>FLASH + + .bss : + { + . = ALIGN(4); + PROVIDE( _sbss = .); + *(.sbss*) + *(.gnu.linkonce.sb.*) + *(.bss*) + *(.gnu.linkonce.b.*) + *(COMMON*) + . = ALIGN(4); + PROVIDE( _ebss = .); + } >RAM AT>FLASH + + PROVIDE( _end = _ebss); + PROVIDE( end = . ); + + .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : + { + PROVIDE( _heap_end = . ); + . = ALIGN(4); + PROVIDE(_susrstack = . ); + . = . + __stack_size; + PROVIDE( _eusrstack = .); + __freertos_irq_stack_top = .; + } >RAM +} diff --git a/hw/bsp/ch583/system_ch583.c b/hw/bsp/ch583/system_ch583.c new file mode 100644 index 000000000..d3724f0ce --- /dev/null +++ b/hw/bsp/ch583/system_ch583.c @@ -0,0 +1,39 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 "CH58x_common.h" +#include "system_ch583.h" + +uint32_t SystemCoreClock = FREQ_SYS; + +void SystemInit(void) { + SetSysClock(CLK_SOURCE_PLL_60MHz); + SystemCoreClock = GetSysClock(); +} + +void SystemCoreClockUpdate(void) { + SystemCoreClock = GetSysClock(); +} diff --git a/hw/bsp/ch583/system_ch583.h b/hw/bsp/ch583/system_ch583.h new file mode 100644 index 000000000..c174c9f5e --- /dev/null +++ b/hw/bsp/ch583/system_ch583.h @@ -0,0 +1,43 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2024 TinyUSB contributors + * + * 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 SYSTEM_CH583_H_ +#define SYSTEM_CH583_H_ + +#ifdef __cplusplus +extern "C" { +#endif + +extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) + +extern void SystemInit(void); +extern void SystemCoreClockUpdate(void); + +#ifdef __cplusplus +} +#endif + +#endif /* SYSTEM_CH583_H_ */ diff --git a/hw/bsp/ch583/wch-riscv.cfg b/hw/bsp/ch583/wch-riscv.cfg new file mode 100644 index 000000000..64d595d8e --- /dev/null +++ b/hw/bsp/ch583/wch-riscv.cfg @@ -0,0 +1,17 @@ +adapter driver wlinke +adapter speed 6000 +transport select sdi + +wlink_set_address 0x00000000 +set _CHIPNAME wch_riscv +sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 + +set _TARGETNAME $_CHIPNAME.cpu + +target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME +$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1 +set _FLASHNAME $_CHIPNAME.flash + +flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 + +echo "Ready for Remote Connections" diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.cmake b/hw/bsp/ch58x/boards/ch582m_evt/board.cmake deleted file mode 100644 index 4129c4550..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(LD_FLASH_SIZE 448K) -set(LD_RAM_SIZE 32K) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.h b/hw/bsp/ch58x/boards/ch582m_evt/board.h deleted file mode 100644 index c3483bf17..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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. - */ - -/* metadata: - name: CH582M-EVT evaluation board - url: https://www.wch-ic.com/products/CH582.html -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// LED: PB4 on CH582M-EVT -#define LED_PIN GPIO_Pin_4 -#define LED_STATE_ON 0 - -// Directly reuse BOOT pin as user button -#define BUTTON_PIN GPIO_Pin_22 -#define BUTTON_STATE_ACTIVE 0 - -// UART: UART1 TX=PA9, RX=PA8 -#define CFG_BOARD_UART_BAUDRATE 115200 - -// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; -// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. -#ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 -#endif -// #ifndef BOARD_TUH_RHPORT -// #define BOARD_TUH_RHPORT 1 -// #endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch58x/boards/ch582m_evt/board.mk b/hw/bsp/ch58x/boards/ch582m_evt/board.mk deleted file mode 100644 index a13979799..000000000 --- a/hw/bsp/ch58x/boards/ch582m_evt/board.mk +++ /dev/null @@ -1,3 +0,0 @@ -LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=448K \ - -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.cmake b/hw/bsp/ch58x/boards/yd-ch582m/board.cmake deleted file mode 100644 index 4129c4550..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.cmake +++ /dev/null @@ -1,5 +0,0 @@ -set(LD_FLASH_SIZE 448K) -set(LD_RAM_SIZE 32K) - -function(update_board TARGET) -endfunction() diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.h b/hw/bsp/ch58x/boards/yd-ch582m/board.h deleted file mode 100644 index 0da5747bc..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.h +++ /dev/null @@ -1,61 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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. - */ - -/* metadata: - name: yd-ch582m from vcc-gnd studio - url: http://vcc-gnd.com/ -*/ - -#ifndef BOARD_H_ -#define BOARD_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -// LED: PB4 on yd-ch582m board -#define LED_PIN GPIO_Pin_4 -#define LED_STATE_ON 0 - -// Directly reuse BOOT pin as user button -#define BUTTON_PIN GPIO_Pin_22 -#define BUTTON_STATE_ACTIVE 0 - -// UART: UART1 TX=PA9, RX=PA8 -#define CFG_BOARD_UART_BAUDRATE 115200 - -// Device only on USB1 (rhport 0). CH58x host / USB2 is not supported by the shared usbfs dcd; -// BOARD_TUH_RHPORT is kept commented out to ease re-adding host later. -#ifndef BOARD_TUD_RHPORT -#define BOARD_TUD_RHPORT 0 -#endif -// #ifndef BOARD_TUH_RHPORT -// #define BOARD_TUH_RHPORT 1 -// #endif - -#ifdef __cplusplus -} -#endif - -#endif diff --git a/hw/bsp/ch58x/boards/yd-ch582m/board.mk b/hw/bsp/ch58x/boards/yd-ch582m/board.mk deleted file mode 100644 index a13979799..000000000 --- a/hw/bsp/ch58x/boards/yd-ch582m/board.mk +++ /dev/null @@ -1,3 +0,0 @@ -LDFLAGS += \ - -Wl,--defsym=__FLASH_SIZE=448K \ - -Wl,--defsym=__RAM_SIZE=32K \ diff --git a/hw/bsp/ch58x/ch58x_it.c b/hw/bsp/ch58x/ch58x_it.c deleted file mode 100644 index 2211e1eda..000000000 --- a/hw/bsp/ch58x/ch58x_it.c +++ /dev/null @@ -1,37 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 "ch58x_it.h" - -// NMI exception handler -__INTERRUPT __HIGH_CODE void NMI_Handler(void) { - while (1) {} -} - -// Hard Fault exception handler -__INTERRUPT __HIGH_CODE void HardFault_Handler(void) { - while (1) {} -} diff --git a/hw/bsp/ch58x/ch58x_it.h b/hw/bsp/ch58x/ch58x_it.h deleted file mode 100644 index 3e050344d..000000000 --- a/hw/bsp/ch58x/ch58x_it.h +++ /dev/null @@ -1,46 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 CH58X_IT_H_ -#define CH58X_IT_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -#include "CH58x_common.h" - -void NMI_Handler(void); -void HardFault_Handler(void); -void USB_IRQHandler(void); -// void USB2_IRQHandler(void); // host on USB2 (rhport 1) — re-add together with the host driver -void SysTick_Handler(void); - -#ifdef __cplusplus -} -#endif - -#endif /* CH58X_IT_H_ */ diff --git a/hw/bsp/ch58x/debug_uart.c b/hw/bsp/ch58x/debug_uart.c deleted file mode 100644 index 850e40718..000000000 --- a/hw/bsp/ch58x/debug_uart.c +++ /dev/null @@ -1,86 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 "debug_uart.h" -#include "CH58x_common.h" - -//--------------------------------------------------------------------+ -// Ring buffer based UART TX for non-blocking writes -//--------------------------------------------------------------------+ - -#define UART_RINGBUFFER_SIZE_TX 128 -#define UART_RINGBUFFER_MASK_TX (UART_RINGBUFFER_SIZE_TX - 1) - -static char tx_buf[UART_RINGBUFFER_SIZE_TX]; -static uint32_t tx_produce; -static volatile uint32_t tx_consume; - -void uart_write(char c) { - uint32_t tx_produce_next = (tx_produce + 1) & UART_RINGBUFFER_MASK_TX; - - // If the ring buffer is full, drain it here as the FIFO frees up: nothing else advances - // tx_consume between uart_write() calls, so a plain spin would deadlock on a >buffer-size burst. - while (tx_produce_next == tx_consume) { - if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { - R8_UART1_THR = tx_buf[tx_consume]; - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - - // If UART TX FIFO is empty and no pending data, send directly - if ((tx_consume == tx_produce) && (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP)) { - R8_UART1_THR = c; - } else { - tx_buf[tx_produce] = c; - tx_produce = tx_produce_next; - } -} - -void uart_sync(void) { - // Wait for ring buffer to drain - while (tx_consume != tx_produce) { - if (R8_UART1_LSR & RB_LSR_TX_FIFO_EMP) { - R8_UART1_THR = tx_buf[tx_consume]; - tx_consume = (tx_consume + 1) & UART_RINGBUFFER_MASK_TX; - } - } - // Wait for last byte to finish transmitting - while (!(R8_UART1_LSR & RB_LSR_TX_ALL_EMP)) {} -} - -void usart_printf_init(uint32_t baudrate) { - tx_produce = 0; - tx_consume = 0; - - // Configure UART1 pins: TX=PA9, RX=PA8 - GPIOA_SetBits(GPIO_Pin_9); - GPIOA_ModeCfg(GPIO_Pin_9, GPIO_ModeOut_PP_5mA); - GPIOA_ModeCfg(GPIO_Pin_8, GPIO_ModeIN_PU); - - // Init UART1 with specified baud rate - UART1_DefInit(); - UART1_BaudRateCfg(baudrate); -} diff --git a/hw/bsp/ch58x/debug_uart.h b/hw/bsp/ch58x/debug_uart.h deleted file mode 100644 index 44c3e7948..000000000 --- a/hw/bsp/ch58x/debug_uart.h +++ /dev/null @@ -1,44 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 DEBUG_UART_H_ -#define DEBUG_UART_H_ - -#include - -#ifdef __cplusplus -extern "C" { -#endif - -void uart_write(char c); -void uart_sync(void); -void usart_printf_init(uint32_t baudrate); - -#ifdef __cplusplus -} -#endif - -#endif /* DEBUG_UART_H_ */ diff --git a/hw/bsp/ch58x/family.c b/hw/bsp/ch58x/family.c deleted file mode 100644 index 64ae4a903..000000000 --- a/hw/bsp/ch58x/family.c +++ /dev/null @@ -1,194 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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. - */ - -/* metadata: - manufacturer: WCH -*/ - -// WCH SDK's DEBUG macro enables a _write() that conflicts with TinyUSB's. -// TinyUSB uses UART1 for printf via debug_uart.c, so DEBUG is not needed. -// If you need a different UART or want to keep SDK's DEBUG, modify -// debug_uart.c (TinyUSB side) or CH58x_sys.c (SDK side) to remove one _write(). -// If done, remove this #error to continue. -#ifdef DEBUG - #error "Remove the DEBUG macro from preprocessor defines to avoid " \ - "duplicate _write() between WCH SDK and TinyUSB. " \ - "TinyUSB uses UART1 by default (see debug_uart.c)." -#endif - -#include "debug_uart.h" -#include "CH58x_common.h" -#include "ch58x_it.h" - -#include "bsp/board_api.h" -#include "board.h" - -//--------------------------------------------------------------------+ -// Forward USB interrupt events to TinyUSB IRQ Handler -//--------------------------------------------------------------------+ - -// Device only: the shared dcd_ch32_usbfs.c drives USB0 (rhport 0). CH58x's second controller -// (USB2 / rhport 1) was driven by the now-removed ch58x host driver; its handler is kept -// commented out below to ease re-adding host support. -__INTERRUPT __HIGH_CODE void USB_IRQHandler(void) { - tusb_int_handler(0, true); -} - -// __INTERRUPT __HIGH_CODE void USB2_IRQHandler(void) { -// tusb_int_handler(1, true); -// } - -//--------------------------------------------------------------------+ -// SysTick -//--------------------------------------------------------------------+ - -#if CFG_TUSB_OS == OPT_OS_NONE -volatile uint32_t system_ticks = 0; - -__INTERRUPT __HIGH_CODE void SysTick_Handler(void) { - SysTick->SR = 0; - system_ticks++; -} - -uint32_t tusb_time_millis_api(void) { - return system_ticks; -} -#endif - -//--------------------------------------------------------------------+ -// Board Init -//--------------------------------------------------------------------+ - -void board_init(void) { - // Disable interrupts during init - PFIC_DisableAllIRQ(); - - // Set system clock to PLL 60MHz (default for CH582) - SetSysClock(CLK_SOURCE_PLL_60MHz); - -#if CFG_TUSB_OS == OPT_OS_NONE - SysTick_Config(GetSysClock() / 1000); -#endif - - // UART1 init for debug output -#ifdef CFG_BOARD_UART_BAUDRATE - usart_printf_init(CFG_BOARD_UART_BAUDRATE); -#endif - - // LED -#ifdef LED_PORT_IS_A - GPIOA_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); -#else - GPIOB_ModeCfg(LED_PIN, GPIO_ModeOut_PP_5mA); -#endif - - // Button -#ifdef BUTTON_PIN - #ifdef BUTTON_PORT_IS_A - GPIOA_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); - #else - GPIOB_ModeCfg(BUTTON_PIN, GPIO_ModeIN_PU); - #endif -#endif - - // Device only on USB0 (rhport 0): enable analog function for USB1 D+/D- and assert its D+ - // pull-up. The shared dcd_ch32_usbfs.c drives USB0; CH58x host / USB2 (rhport 1) is unsupported - // here — to re-add host, also OR in RB_PIN_USB2_IE below. - R16_PIN_ANALOG_IE |= RB_PIN_USB_IE; // | RB_PIN_USB2_IE (re-add for host on USB2) -#if CFG_TUD_ENABLED - R16_PIN_ANALOG_IE |= RB_PIN_USB_DP_PU; -#endif - - // Keep USB clock active during sleep - R8_SLP_CLK_OFF1 &= ~RB_SLP_CLK_USB; - - // Enable interrupts globally - PFIC_EnableAllIRQ(); - - board_delay(2); -} - -//--------------------------------------------------------------------+ -// Board porting API -//--------------------------------------------------------------------+ - -void board_led_write(bool state) { -#ifdef LED_PORT_IS_A - if (state ^ LED_STATE_ON) { - GPIOA_ResetBits(LED_PIN); - } else { - GPIOA_SetBits(LED_PIN); - } -#else - if (state ^ LED_STATE_ON) { - GPIOB_ResetBits(LED_PIN); - } else { - GPIOB_SetBits(LED_PIN); - } -#endif -} - -uint32_t board_button_read(void) { -#ifdef BUTTON_PIN - #ifdef BUTTON_PORT_IS_A - return BUTTON_STATE_ACTIVE == (GPIOA_ReadPortPin(BUTTON_PIN) ? 1 : 0); - #else - return BUTTON_STATE_ACTIVE == (GPIOB_ReadPortPin(BUTTON_PIN) ? 1 : 0); - #endif -#else - return 0; -#endif -} - -// CH58x has no memory-mapped unique-ID register (unlike ch32v10x/v20x at 0x1FFFF7E8), but the -// factory programs a unique 6-byte MAC address into FlashROM (it is a BLE part). GetMACAddress() -// reads it via the ISP ROM command FLASH_EEPROM_CMD, which is provided by libISP583.a. -size_t board_get_unique_id(uint8_t id[], size_t max_len) { - // FLASH_EEPROM_CMD writes word-granular and requires a 4-byte-aligned buffer (CH58x_flash.c); - // size 8 matches the SDK's GET_UNIQUE_ID buffer (6 MAC bytes + 2 it pads), so the read can't - // run past the end whether it returns 6 or a full 8. - TU_ATTR_ALIGNED(4) uint8_t mac[8]; - GetMACAddress(mac); - size_t len = TU_MIN(max_len, (size_t) 6); // the 6-byte MAC is the unique part - memcpy(id, mac, len); - return len; -} - -int board_uart_read(uint8_t* buf, int len) { - (void) buf; - (void) len; - return 0; -} - -int board_uart_write(void const* buf, int len) { - int txsize = len; - const char* bufc = (const char*) buf; - while (txsize--) { - uart_write(*bufc++); - } - uart_sync(); - return len; -} diff --git a/hw/bsp/ch58x/family.cmake b/hw/bsp/ch58x/family.cmake deleted file mode 100644 index a52309276..000000000 --- a/hw/bsp/ch58x/family.cmake +++ /dev/null @@ -1,108 +0,0 @@ -include_guard() - -set(SDK_DIR ${TOP}/hw/mcu/wch/ch583) -set(SDK_SRC_DIR ${SDK_DIR}/EVT/EXAM/SRC) - -# include board specific -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) - -# toolchain set up -set(CMAKE_SYSTEM_CPU rv32imac-ilp32 CACHE INTERNAL "System Processor") -set(CMAKE_TOOLCHAIN_FILE ${TOP}/examples/build_system/cmake/toolchain/riscv_${TOOLCHAIN}.cmake) - -set(FAMILY_MCUS CH58X CACHE INTERNAL "") -set(OPENOCD_OPTION "-f ${CMAKE_CURRENT_LIST_DIR}/wch-riscv.cfg") - -#------------------------------------ -# Startup & Linker script -#------------------------------------ -if (NOT DEFINED LD_FILE_GNU) - set(LD_FILE_GNU ${CMAKE_CURRENT_LIST_DIR}/linker/ch582.ld) -endif () -set(LD_FILE_Clang ${LD_FILE_GNU}) -if (NOT DEFINED STARTUP_FILE_GNU) - set(STARTUP_FILE_GNU ${SDK_SRC_DIR}/Startup/startup_CH583.S) -endif () -set(STARTUP_FILE_Clang ${STARTUP_FILE_GNU}) - -#------------------------------------ -# Board Target -#------------------------------------ -function(family_add_board BOARD_TARGET) - add_library(${BOARD_TARGET} STATIC - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_gpio.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_clk.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_uart1.c - ${SDK_SRC_DIR}/StdPeriphDriver/CH58x_sys.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/ch58x_it.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/system_ch58x.c - ) - target_include_directories(${BOARD_TARGET} PUBLIC - ${SDK_SRC_DIR}/RVMSIS - ${SDK_SRC_DIR}/StdPeriphDriver/inc - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ) - target_link_libraries(${BOARD_TARGET} PUBLIC - ${SDK_SRC_DIR}/StdPeriphDriver/libISP583.a - ) - target_compile_definitions(${BOARD_TARGET} PUBLIC - CFG_TUD_WCH_USBIP_USBFS=1 - FREQ_SYS=60000000 - DISK_LIB_ENABLE=0 - INT_SOFT - ) - - update_board(${BOARD_TARGET}) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_compile_options(${BOARD_TARGET} PUBLIC - -flto - -msmall-data-limit=16 - -mno-save-restore - -fmessage-length=0 - -fsigned-char - -Wno-error=strict-prototypes - ) - endif () -endfunction() - -#------------------------------------ -# Functions -#------------------------------------ -function(family_configure_example TARGET RTOS) - family_configure_common(${TARGET} ${RTOS}) - family_add_tinyusb(${TARGET} OPT_MCU_CH58X) - - target_sources(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/family.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/debug_uart.c - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../board.c - ${TOP}/src/portable/wch/dcd_ch32_usbfs.c - ${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} - ) - target_include_directories(${TARGET} PUBLIC - ${CMAKE_CURRENT_FUNCTION_LIST_DIR} - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/../../ - ${CMAKE_CURRENT_FUNCTION_LIST_DIR}/boards/${BOARD} - ) - - if (CMAKE_C_COMPILER_ID STREQUAL "GNU") - target_link_options(${TARGET} PUBLIC - -nostartfiles - --specs=nosys.specs --specs=nano.specs - -Wl,--defsym=__FLASH_SIZE=${LD_FLASH_SIZE} - -Wl,--defsym=__RAM_SIZE=${LD_RAM_SIZE} - "LINKER:--script=${LD_FILE_GNU}" - ) - elseif (CMAKE_C_COMPILER_ID STREQUAL "Clang") - message(FATAL_ERROR "Clang is not supported for CH58x") - endif () - - set_source_files_properties(${STARTUP_FILE_${CMAKE_C_COMPILER_ID}} PROPERTIES - SKIP_LINTING ON - COMPILE_OPTIONS -w) - - # Flashing - family_add_bin_hex(${TARGET}) - family_flash_openocd_wch(${TARGET}) -endfunction() diff --git a/hw/bsp/ch58x/family.mk b/hw/bsp/ch58x/family.mk deleted file mode 100644 index ac0443659..000000000 --- a/hw/bsp/ch58x/family.mk +++ /dev/null @@ -1,59 +0,0 @@ -# https://www.embecosm.com/resources/tool-chain-downloads/#riscv-stable -#CROSS_COMPILE ?= riscv32-unknown-elf- - -# Toolchain from https://nucleisys.com/download.php -#CROSS_COMPILE ?= riscv-nuclei-elf- - -# Toolchain from https://github.com/xpack-dev-tools/riscv-none-elf-gcc-xpack -CROSS_COMPILE ?= riscv-none-elf- - -SDK_DIR = hw/mcu/wch/ch583 -SDK_SRC_DIR = $(SDK_DIR)/EVT/EXAM/SRC - -include $(TOP)/$(BOARD_PATH)/board.mk -CPU_CORE ?= rv32imac-ilp32 - -CFLAGS += \ - -flto \ - -msmall-data-limit=16 \ - -mno-save-restore \ - -fmessage-length=0 \ - -fsigned-char \ - -DCFG_TUSB_MCU=OPT_MCU_CH58X \ - -DCFG_TUD_WCH_USBIP_USBFS=1 \ - -DFREQ_SYS=60000000 \ - -DDISK_LIB_ENABLE=0 \ - -DINT_SOFT \ - -Wno-error=strict-prototypes - -LDFLAGS += \ - -nostartfiles \ - --specs=nosys.specs --specs=nano.specs - -LIBS += $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/libISP583.a - -SRC_C += \ - src/portable/wch/dcd_ch32_usbfs.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_gpio.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_clk.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_uart1.c \ - $(SDK_SRC_DIR)/StdPeriphDriver/CH58x_sys.c \ - $(FAMILY_PATH)/debug_uart.c \ - $(FAMILY_PATH)/ch58x_it.c \ - $(FAMILY_PATH)/system_ch58x.c - -SRC_S += \ - $(SDK_SRC_DIR)/Startup/startup_CH583.S - -INC += \ - $(TOP)/$(BOARD_PATH) \ - $(TOP)/$(SDK_SRC_DIR)/RVMSIS \ - $(TOP)/$(SDK_SRC_DIR)/StdPeriphDriver/inc - -LD_FILE ?= $(FAMILY_PATH)/linker/ch582.ld - -OPENOCD_WCH_OPTION=-f $(TOP)/$(FAMILY_PATH)/wch-riscv.cfg -flash: flash-openocd-wch - -# For freeRTOS port source -FREERTOS_PORTABLE_SRC = $(FREERTOS_PORTABLE_PATH)/RISC-V diff --git a/hw/bsp/ch58x/linker/ch582.ld b/hw/bsp/ch58x/linker/ch582.ld deleted file mode 100644 index 821998a49..000000000 --- a/hw/bsp/ch58x/linker/ch582.ld +++ /dev/null @@ -1,167 +0,0 @@ -/* CH582 Linker Script for TinyUSB - * Based on WCH CH583 SDK Link.ld - * Supports parameterized flash/ram sizes via --defsym - */ - -/* Default sizes if not provided via --defsym */ -__flash_size = DEFINED(__FLASH_SIZE) ? __FLASH_SIZE : 448K; -__ram_size = DEFINED(__RAM_SIZE) ? __RAM_SIZE : 32K; -__stack_size = DEFINED(__STACK_SIZE) ? __STACK_SIZE : 2048; - -ENTRY( _start ) - -PROVIDE( _stack_size = __stack_size ); - -MEMORY -{ - FLASH (rx) : ORIGIN = 0x00000000, LENGTH = __flash_size - RAM (xrw) : ORIGIN = 0x20000000, LENGTH = __ram_size -} - -SECTIONS -{ - .init : - { - _sinit = .; - . = ALIGN(4); - KEEP(*(SORT_NONE(.init))) - . = ALIGN(4); - _einit = .; - } >FLASH AT>FLASH - - .highcodelalign : - { - . = ALIGN(4); - PROVIDE(_highcode_lma = .); - } >FLASH AT>FLASH - - .highcode : - { - . = ALIGN(4); - PROVIDE(_highcode_vma_start = .); - *(.vector); - KEEP(*(SORT_NONE(.vector_handler))) - *(.highcode); - *(.highcode.*); - . = ALIGN(4); - PROVIDE(_highcode_vma_end = .); - } >RAM AT>FLASH - - .text : - { - . = ALIGN(4); - KEEP(*(SORT_NONE(.handle_reset))) - *(.text) - *(.text.*) - *(.rodata) - *(.rodata*) - *(.sdata2.*) - *(.glue_7) - *(.glue_7t) - *(.gnu.linkonce.t.*) - . = ALIGN(4); - } >FLASH AT>FLASH - - .fini : - { - KEEP(*(SORT_NONE(.fini))) - . = ALIGN(4); - } >FLASH AT>FLASH - - PROVIDE( _etext = . ); - PROVIDE( _eitcm = . ); - - .preinit_array : - { - PROVIDE_HIDDEN (__preinit_array_start = .); - KEEP (*(.preinit_array)) - PROVIDE_HIDDEN (__preinit_array_end = .); - } >FLASH AT>FLASH - - .init_array : - { - PROVIDE_HIDDEN (__init_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.init_array.*) SORT_BY_INIT_PRIORITY(.ctors.*))) - KEEP (*(.init_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .ctors)) - PROVIDE_HIDDEN (__init_array_end = .); - } >FLASH AT>FLASH - - .fini_array : - { - PROVIDE_HIDDEN (__fini_array_start = .); - KEEP (*(SORT_BY_INIT_PRIORITY(.fini_array.*) SORT_BY_INIT_PRIORITY(.dtors.*))) - KEEP (*(.fini_array EXCLUDE_FILE (*crtbegin.o *crtbegin?.o *crtend.o *crtend?.o ) .dtors)) - PROVIDE_HIDDEN (__fini_array_end = .); - } >FLASH AT>FLASH - - .ctors : - { - KEEP (*crtbegin.o(.ctors)) - KEEP (*crtbegin?.o(.ctors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .ctors)) - KEEP (*(SORT(.ctors.*))) - KEEP (*(.ctors)) - } >FLASH AT>FLASH - - .dtors : - { - KEEP (*crtbegin.o(.dtors)) - KEEP (*crtbegin?.o(.dtors)) - KEEP (*(EXCLUDE_FILE (*crtend.o *crtend?.o ) .dtors)) - KEEP (*(SORT(.dtors.*))) - KEEP (*(.dtors)) - } >FLASH AT>FLASH - - .dlalign : - { - . = ALIGN(4); - PROVIDE(_data_lma = .); - } >FLASH AT>FLASH - - .data : - { - . = ALIGN(4); - PROVIDE(_data_vma = .); - *(.gnu.linkonce.r.*) - *(.data .data.*) - *(.gnu.linkonce.d.*) - . = ALIGN(8); - PROVIDE( __global_pointer$ = . + 0x800 ); - *(.sdata .sdata.*) - *(.gnu.linkonce.s.*) - . = ALIGN(8); - *(.srodata.cst16) - *(.srodata.cst8) - *(.srodata.cst4) - *(.srodata.cst2) - *(.srodata .srodata.*) - . = ALIGN(4); - PROVIDE( _edata = .); - } >RAM AT>FLASH - - .bss : - { - . = ALIGN(4); - PROVIDE( _sbss = .); - *(.sbss*) - *(.gnu.linkonce.sb.*) - *(.bss*) - *(.gnu.linkonce.b.*) - *(COMMON*) - . = ALIGN(4); - PROVIDE( _ebss = .); - } >RAM AT>FLASH - - PROVIDE( _end = _ebss); - PROVIDE( end = . ); - - .stack ORIGIN(RAM) + LENGTH(RAM) - __stack_size : - { - PROVIDE( _heap_end = . ); - . = ALIGN(4); - PROVIDE(_susrstack = . ); - . = . + __stack_size; - PROVIDE( _eusrstack = .); - __freertos_irq_stack_top = .; - } >RAM -} diff --git a/hw/bsp/ch58x/system_ch58x.c b/hw/bsp/ch58x/system_ch58x.c deleted file mode 100644 index 068c1a131..000000000 --- a/hw/bsp/ch58x/system_ch58x.c +++ /dev/null @@ -1,39 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 "CH58x_common.h" -#include "system_ch58x.h" - -uint32_t SystemCoreClock = FREQ_SYS; - -void SystemInit(void) { - SetSysClock(CLK_SOURCE_PLL_60MHz); - SystemCoreClock = GetSysClock(); -} - -void SystemCoreClockUpdate(void) { - SystemCoreClock = GetSysClock(); -} diff --git a/hw/bsp/ch58x/system_ch58x.h b/hw/bsp/ch58x/system_ch58x.h deleted file mode 100644 index e96741ee8..000000000 --- a/hw/bsp/ch58x/system_ch58x.h +++ /dev/null @@ -1,43 +0,0 @@ -/* - * The MIT License (MIT) - * - * Copyright (c) 2024 TinyUSB contributors - * - * 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 SYSTEM_CH58X_H_ -#define SYSTEM_CH58X_H_ - -#ifdef __cplusplus -extern "C" { -#endif - -extern uint32_t SystemCoreClock; // System Clock Frequency (Core Clock) - -extern void SystemInit(void); -extern void SystemCoreClockUpdate(void); - -#ifdef __cplusplus -} -#endif - -#endif /* SYSTEM_CH58X_H_ */ diff --git a/hw/bsp/ch58x/wch-riscv.cfg b/hw/bsp/ch58x/wch-riscv.cfg deleted file mode 100644 index 64d595d8e..000000000 --- a/hw/bsp/ch58x/wch-riscv.cfg +++ /dev/null @@ -1,17 +0,0 @@ -adapter driver wlinke -adapter speed 6000 -transport select sdi - -wlink_set_address 0x00000000 -set _CHIPNAME wch_riscv -sdi newtap $_CHIPNAME cpu -irlen 5 -expected-id 0x00001 - -set _TARGETNAME $_CHIPNAME.cpu - -target create $_TARGETNAME.0 wch_riscv -chain-position $_TARGETNAME -$_TARGETNAME.0 configure -work-area-phys 0x20000000 -work-area-size 0x8000 -work-area-backup 1 -set _FLASHNAME $_CHIPNAME.flash - -flash bank $_FLASHNAME wch_riscv 0x00000000 0 0 0 $_TARGETNAME.0 - -echo "Ready for Remote Connections" diff --git a/src/common/tusb_mcu.h b/src/common/tusb_mcu.h index f2a2d92a5..b5390a59d 100644 --- a/src/common/tusb_mcu.h +++ b/src/common/tusb_mcu.h @@ -659,7 +659,7 @@ #define TUP_DCD_EDPT_CLOSE_API #endif -#elif TU_CHECK_MCU(OPT_MCU_CH58X) +#elif TU_CHECK_MCU(OPT_MCU_CH583) // CH582/583 USBFS: older WCH USBFS IP with a single combined per-endpoint control register // (like CH32V103), driven by the shared dcd_ch32_usbfs.c on USB0 (rhport 0). Device only: // the shared hcd_ch32_usbfs.c is CH32V20x-specific and does not support CH58x, so host / diff --git a/src/portable/wch/ch32_usbfs_reg.h b/src/portable/wch/ch32_usbfs_reg.h index 90a477b79..415a015dc 100644 --- a/src/portable/wch/ch32_usbfs_reg.h +++ b/src/portable/wch/ch32_usbfs_reg.h @@ -130,7 +130,7 @@ #elif CFG_TUSB_MCU == OPT_MCU_CH32V307 #include #define USBHD_IRQn OTG_FS_IRQn -#elif CFG_TUSB_MCU == OPT_MCU_CH58X +#elif CFG_TUSB_MCU == OPT_MCU_CH583 #include "CH58x_common.h" // CH582/583 USBFS device controller: same combined per-endpoint control register as // CH32V103 (IN response bits[1:0], OUT response bits[3:2]) but a different register map - diff --git a/src/portable/wch/dcd_ch32_usbfs.c b/src/portable/wch/dcd_ch32_usbfs.c index 22c7a43fa..ece9cde07 100644 --- a/src/portable/wch/dcd_ch32_usbfs.c +++ b/src/portable/wch/dcd_ch32_usbfs.c @@ -37,7 +37,7 @@ // Struct-based EP register access (uniform layout). CH58X has a different register map and // defines EP_DMA/EP_TX_LEN/EP_CTRL itself in ch32_usbfs_reg.h. - #if CFG_TUSB_MCU == OPT_MCU_CH58X + #if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58X EP registers split into a low block (EP0-4) and a high block (EP5-7). Walk from each // block's first slot by the 4-byte slot stride (pointer arithmetic off slot 0, so the unused // ternary branch's index can't trip -Warray-bounds). EP4 has no DMA register of its own (it @@ -220,7 +220,7 @@ static void update_in(uint8_t rhport, uint8_t ep, bool force) { if (xfer->valid) { if (force || xfer->len) { size_t len = TU_MIN(xfer->max_size, xfer->len); -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // Every CH58x endpoint buffer is 64 bytes. Isochronous (which would push max_size up to 1023) // is refused in dcd_edpt_iso_alloc(), but some classes (e.g. video) ignore that result, so cap // the copy here to guarantee we never write past the buffer into a neighbouring endpoint's. @@ -256,7 +256,7 @@ static void update_out(uint8_t rhport, uint8_t ep, size_t rx_len) { struct usb_xfer *xfer = &data.xfer[ep][TUSB_DIR_OUT]; if (xfer->valid) { size_t len = TU_MIN(xfer->max_size, TU_MIN(xfer->len, rx_len)); -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 len = TU_MIN(len, 64u); // cap to the 64-byte EP buffer (see update_in) #endif memcpy(xfer->buffer, ep_out_buf(ep), len); @@ -308,7 +308,7 @@ bool dcd_init(uint8_t rhport, const tusb_rhport_init_t *rh_init) { // enable other endpoints but NAK everything USBOTG_FS->UEP4_1_MOD = 0xCC; USBOTG_FS->UEP2_3_MOD = 0xCC; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58X: a single mode register enables EP5/6/7 RX+TX (different bit layout than CH32). USBOTG_FS->UEP567_MOD = RB_UEP5_RX_EN | RB_UEP5_TX_EN | RB_UEP6_RX_EN | RB_UEP6_TX_EN | RB_UEP7_RX_EN | RB_UEP7_TX_EN; @@ -393,7 +393,7 @@ void dcd_int_handler(uint8_t rhport) { USBOTG_FS->INT_FG = USBFS_INT_FG_BUS_RST; } else if (status & USBFS_INT_FG_SUSPEND) { -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // CH58x raises this single interrupt for both suspend and resume; MIS_ST's suspend bit tells // them apart (set while suspended, clear once resumed) so tud_resume_cb() actually fires. dcd_event_t event = {.rhport = rhport, @@ -447,7 +447,7 @@ void dcd_edpt0_status_complete(uint8_t rhport, const tusb_control_request_t *req (void)rhport; if (request->bmRequestType_bit.recipient == TUSB_REQ_RCPT_DEVICE && request->bmRequestType_bit.type == TUSB_REQ_TYPE_STANDARD && request->bRequest == TUSB_REQ_SET_ADDRESS) { -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // On CH58x R8_USB_DEV_AD bit 7 is a user general-purpose flag; only bits [6:0] are the address. USBOTG_FS->DEV_ADDR = (uint8_t)((USBOTG_FS->DEV_ADDR & 0x80u) | (request->wValue & 0x7Fu)); #else @@ -485,7 +485,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet (void)rhport; (void)ep_addr; (void)largest_packet_size; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 // No isochronous support on CH58x: its 8-bit T_LEN caps a packet at 255B and the endpoints use // plain 64-byte buffers, so accepting an iso max_size (up to 1023) would let update_in()/ // update_out() run off the end of the buffer into neighbouring ones. Refuse it outright. @@ -503,7 +503,7 @@ bool dcd_edpt_iso_alloc(uint8_t rhport, uint8_t ep_addr, uint16_t largest_packet bool dcd_edpt_iso_activate(uint8_t rhport, const tusb_desc_endpoint_t *desc_ep) { (void)rhport; (void)desc_ep; -#if CFG_TUSB_MCU == OPT_MCU_CH58X +#if CFG_TUSB_MCU == OPT_MCU_CH583 return false; // CH58x has no isochronous support (see dcd_edpt_iso_alloc) #else return true; diff --git a/src/tusb_option.h b/src/tusb_option.h index 9170d1205..cb8e3f6bd 100644 --- a/src/tusb_option.h +++ b/src/tusb_option.h @@ -195,7 +195,7 @@ #define OPT_MCU_CH32F20X 2210 ///< WCH CH32F20x #define OPT_MCU_CH32V20X 2220 ///< WCH CH32V20X #define OPT_MCU_CH32V103 2230 ///< WCH CH32V103 -#define OPT_MCU_CH58X 2240 ///< WCH CH58x +#define OPT_MCU_CH583 2240 ///< WCH CH583 #define OPT_MCU_CH582 2240 ///< alias to CH58x series #define OPT_MCU_CH583 2240 ///< alias to CH58x series diff --git a/tools/get_deps.py b/tools/get_deps.py index b31f8a0cb..ebbf9b871 100755 --- a/tools/get_deps.py +++ b/tools/get_deps.py @@ -255,7 +255,7 @@ deps_optional = { 'ch32f20x'], 'hw/mcu/wch/ch583': ['https://github.com/openwch/ch583.git', 'bd508ad7ceed48377619837051412a651952857f', - 'ch58x'], + 'ch583'], 'hw/mcu/artery/at32f403a_407': ['https://github.com/ArteryTek/AT32F403A_407_Firmware_Library.git', 'f2cb360c3d28fada76b374308b8c4c61d37a090b', 'at32f403a_407'], -- cgit v1.3.1