diff --git a/.circleci/config2.yml b/.circleci/config2.yml index 542c3d0d04..278ff0f3b9 100644 --- a/.circleci/config2.yml +++ b/.circleci/config2.yml @@ -68,14 +68,6 @@ commands: steps: - checkout - - when: - condition: - not: - equal: [esp-idf, << parameters.toolchain >>] - steps: - - setup-toolchain: - toolchain: << parameters.toolchain >> - - run: name: Get Dependencies command: | @@ -101,6 +93,14 @@ commands: echo "export PICO_SDK_PATH=~/pico-sdk" >> $BASH_ENV fi + - when: + condition: + not: + equal: [esp-idf, << parameters.toolchain >>] + steps: + - setup-toolchain: + toolchain: << parameters.toolchain >> + - run: name: Build command: | diff --git a/.idea/cmake.xml b/.idea/cmake.xml index e8b46d468d..96ff19c89d 100644 --- a/.idea/cmake.xml +++ b/.idea/cmake.xml @@ -2,8 +2,10 @@ - - + + + + @@ -35,7 +37,7 @@ - + @@ -66,7 +68,7 @@ - + @@ -140,8 +142,8 @@ - - + + diff --git a/README.rst b/README.rst index 2ffe3823a9..502115c259 100644 --- a/README.rst +++ b/README.rst @@ -77,7 +77,7 @@ Host Stack - Human Interface Device (HID): Keyboard, Mouse, Generic - Mass Storage Class (MSC) - Communication Device Class: CDC-ACM -- Vendor serial over USB: FTDI, CP210x +- Vendor serial over USB: FTDI, CP210x, CH34x - Hub with multiple-level support 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. @@ -111,7 +111,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l +--------------+------------------------------------------------------------+ | Analog | max32: 650, 666, 690. max78002 | | | | -| | max3421e (host) | +| | max3421e (spi host) | +--------------+------------------------------------------------------------+ | Brigetek | FT90x | +--------------+------------------------------------------------------------+ @@ -143,7 +143,7 @@ Following CPUs are supported, check out `Supported Devices`_ for comprehensive l | | | | | MCX: A15, N9 | +--------------+------------------------------------------------------------+ -| Raspberry Pi | RP2040 | +| Raspberry Pi | RP2040, RP2350 | +--------------+-----+------------------------------------------------------+ | Renesas | RA: 4M1, 4M3, 6M1, 6M5 | | | | diff --git a/docs/info/changelog.rst b/docs/info/changelog.rst index f7ccb39b91..d11e1134a0 100644 --- a/docs/info/changelog.rst +++ b/docs/info/changelog.rst @@ -2,71 +2,165 @@ Changelog ********* -0.17.0 (WIP) -============ +0.17.0 +====== General ------- -- Improved continuous integration: build both cmake and make. Make use of circleci to build arm-clang - +- Improved CI: build both cmake and make. Make use of CircleCI for part of build process to speed up CI +- Add CodeQL Workflow for Code Security Analysis +- Add Clang compiler support +- Add default implementation for weak callbacks functions for better Keil compatibility +- Upgrade hardware-in-the-loop (HIL) testing with more boards and examples: including dual stack example Controller Driver (DCD & HCD) ----------------------------- +- Chipidea + + - Support MCXA + +- DWC2 + + - Fix tickless issue with stm32f7: disable ULPI clock during sleep when using internal phy + - Fix SOF interrupt handling + - Fix fifo level half/empty issue + - Add DWC2 Test Mode support. + - for esp32 force disconnect/connect using USB_WRAP otg pad override + +- FSDEV + + - Rewrite and Generalize driver to support non-stm32 mcu such as wch + - Simplify PMA, HW FIFO access and bit manipulation for different access scheme 1x16, 2x16 and 32 bit + - Add support for ch32 usbd e.g ch32v203 + - Add support for STM32G4 and STM32U5 microcontrollers. + - Fix h5 (32-bit) errata 2.15.1: Buffer description table update completes after CTR interrupt triggers + - ISO EP buffer allocation improvements, implement dcd_edpt_close_all() + + - Fix ch32v203 race condition and stability issue with + + - fix ch32v203 seems to unconditionally accept ZLP on EP0 OUT. + - fix v203 race condition between rx bufsize and RX_STAT which cause PMAOVR, occurs with WRITE10 + - correctly handle setup prepare at dcd_edpt0_status_complete(), which fixes the race condition with windows where we could miss setup packet (setup bit set, but count = 0) + +- MAX3421E + + - Add support for rp2040, esp32 (c3, c6, h2, etc..) + - Add hcd_deinit() for max3421 + - Retry NAK handling next frame to reduce CPU and SPI bus usage + - add cpuctl and pinctl to tuh_configure() option for max3421 + - Implement hcd abort transfer for Max3421 + - Properly Handle NAK Response in MAX3421E driver: correctly switch and skip writing to 2 FIFOs when NAK received. Otherwise, the driver may hang in certain conditions. + +- MSP430: support non-bus-powered + +- MUSB + + - Add support for Analoog devices: max32650, max32666, max32690, max3278002 + +- nRF + + - Fix dcd_edpt_open for iso endpoint + - Handle ISOOUT CRC errors + - Add compile support with old nordic sdk + - Fix a few race conditions + +- OHCI + + - Allow more than 16 devices + +- RP2040 + + - Correctly abort control transfer when new setup arrived. Due to RP2040-E2 only able to fix B2 or later + - Implement hcd abort transfer for rp2040 + - Add support for rp2350 + +- RUSB2 + + - Support ra2a1 pipe number scheme + - WCH CH32 - Added support for USB OTG/FS and FSDev Driver. Update CH32V307 to allow manual select FS or HS driver. - Fixed various bugs in CH32v307 usbhs driver: endpoint handling and data transfer management. -- Fixed race conditions and other bugs in dcd_nrf5x and other drivers. -- Implemented hcd abort transfer for Max3421 and rp2040 -- Added DWC2 Test Mode support. -- stm32 fsdev: ISO EP buffer allocation improvements, implement dcd_edpt_close_all() -- Added support for STM32G4 and STM32U5 microcontrollers. - Device Stack ------------ -- Added tud_deinit() to deinitialize TinyUSB device stack. -- Added support for generic SOF callback. +- Add tud_deinit() and class driver deinit() to deinitialize TinyUSB device stack. +- Add support for generic SOF callback. +- Add set address recovery time 2ms per USB spec. - Audio - Add audio_test_freertos & audio_4_channel_mic_freertos - Improved support for Audio Class 2.0 (UAC2) with various bug fixes. + - Add feedback by fifo counting. + +- Bluetooth HCI + + - Issue ZLP on ACL IN ep when transfer is multiple of endpoint max packet size + +- CDC + + - Add tud_cdc_configure_fifo() to make RX/TX buffer persistent (not clear when disconnected) + - Add missing capability bit for CDC ACM serial break support + - Enhanced CDC class with better handling of large data transmissions. + - Add missing capability bit for CDC ACM serial break support - HID - Added missing key codes for keypad - Added HID Lighting and Illumination functionality + - Fixed issues in the HID class for more reliable device enumeration. + - Support HID Mouse with absolute positioning + - Use separate buffer for control SET_REPORT, fix conflict with interrupt endpoint out -- Vendor: Added empty transfers for tud_vendor_n_write() - MSC: Added support for SCSI_CMD_PREVENT_ALLOW_MEDIUM_REMOVAL -- CDC - - - Add option to make CDC TX buffer persistent - - Add missing capability bit for CDC ACM serial break support - - Net - - Rewrite of NCM device driver + - Rewrite of NCM device driver to improve throughput - removed obsolete tud_network_link_state_cb() -- Enhanced CDC class with better handling of large data transmissions. -- Fixed issues in the HID class for more reliable device enumeration. -- Video Added support for USB Video Class (UVC) with MJPEG. - USBTMC Added notification support +- Vendor + + - Migrate to new endpoint stream API, support non-buffered TX/RX + - Add ZLP for write() when needed + +- Video + + - Enhance UVC descriptors and example + - Video Added support for USB Video Class (UVC) with MJPEG. + - Fix multiple interfaces, add an example of 2ch video capture. + - Fix race for tud_video_n_streaming check + Host Stack ---------- -- Added tuh_deinit() to deinitialize TinyUSB host stack. +- Added tuh_deinit() to de-initialize TinyUSB host stack. - Added support for new USB mass storage class APIs. -- Enhanced stability of CDC-ACM devices during enumeration. - Improved error handling and retry mechanisms for unstable devices. -- Added support for multiple interfaces in UVC. + +- CDC Serial + + - Add support for ch34x + - Allow to overwrite CFG_TUH_CDC_FTDI/CP210X/CH32X_VID_PID_LIST + - Enhanced stability of CDC-ACM devices during enumeration. + +- HID + + - Add tuh_hid_receive_abort() + - Add tuh_hid_get_report() + +- Hub + + - Prevent status request to invalid ep_num + - Fix double status xfer + - unroll hub removal 0.16.0 ====== diff --git a/docs/reference/dependencies.rst b/docs/reference/dependencies.rst index fd895519e3..65ee31f227 100644 --- a/docs/reference/dependencies.rst +++ b/docs/reference/dependencies.rst @@ -8,6 +8,7 @@ MCU low-level peripheral driver and external libraries for building TinyUSB exam Local Path Repo Commit Required by ======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== hw/mcu/allwinner https://github.com/hathach/allwinner_driver.git 8e5e89e8e132c0fd90e72d5422e5d3d68232b756 fc100s +hw/mcu/analog/max32 https://github.com/analogdevicesinc/msdk.git b20b398d3e5e2007594e54a74ba3d2a2e50ddd75 max32650 max32666 max32690 max78002 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 @@ -16,9 +17,9 @@ hw/mcu/microchip https://github.com/hathach/microchip_d 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/nuvoton https://github.com/majbthrd/nuc_driver.git 2204191ec76283371419fbcec207da02e1bc22fa nuc -hw/mcu/nxp/lpcopen https://github.com/hathach/nxp_lpcopen.git 04bfe7a5f6ee74a89a28ad618d3367dcfcfb7d83 lpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43 +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/hathach/mcux-sdk.git 144f1eb7ea8c06512e12f12b27383601c0272410 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 0f747aaa0c16f750bdfa2ba37ec25d6c8e1bc117 rp2040 +hw/mcu/raspberry_pi/Pico-PIO-USB https://github.com/sekigon-gonnoc/Pico-PIO-USB.git fe9133fc513b82cc3dc62c67cb51f2339cf29ef7 rp2040 hw/mcu/renesas/fsp https://github.com/renesas/fsp.git d52e5a6a59b7c638da860c2bb309b6e78e752ff8 ra 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 @@ -57,11 +58,12 @@ hw/mcu/st/stm32u5xx_hal_driver https://github.com/STMicroelectronics/ hw/mcu/st/stm32wbxx_hal_driver https://github.com/STMicroelectronics/stm32wbxx_hal_driver.git 2c5f06638be516c1b772f768456ba637f077bac8 stm32wb hw/mcu/ti https://github.com/hathach/ti_driver.git 143ed6cc20a7615d042b03b21e070197d473e6e5 msp430 msp432e4 tm4c hw/mcu/wch/ch32f20x https://github.com/openwch/ch32f20x.git 77c4095087e5ed2c548ec9058e655d0b8757663b ch32f20x -hw/mcu/wch/ch32v20x https://github.com/openwch/ch32v20x.git de6d68c654340d7f27b00cebbfc9aa2740a1abc2 ch32v20x -hw/mcu/wch/ch32v307 https://github.com/openwch/ch32v307.git 17761f5cf9dbbf2dcf665b7c04934188add20082 ch32v307 +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 ch32v307 lib/CMSIS_5 https://github.com/ARM-software/CMSIS_5.git 20285262657d1b482d132d20d755c8c330d55c1f imxrt kinetis_k32l2 kinetis_kl lpc51 lpc54 lpc55 mcx mm32 msp432e4 nrf ra saml2xlpc11 lpc13 lpc15 lpc17 lpc18 lpc40 lpc43stm32f0 stm32f1 stm32f2 stm32f3 stm32f4 stm32f7 stm32g0 stm32g4 stm32h5stm32h7 stm32l0 stm32l1 stm32l4 stm32l5 stm32u5 stm32wbsam3x samd11 samd21 samd51 samd5x_e5x same5x same7x saml2x samgtm4c 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 19615407727073e36d81bf239c52108ba92e7660 all +tools/uf2 https://github.com/microsoft/uf2.git c594542b2faa01cc33a2b97c9fbebc38549df80a all ======================================== ============================================================== ======================================== ========================================================================================================================================================================================================================================================================================================================== diff --git a/docs/reference/supported.rst b/docs/reference/supported.rst index 2bfa1b8d0b..b871490dcf 100644 --- a/docs/reference/supported.rst +++ b/docs/reference/supported.rst @@ -5,142 +5,132 @@ Supported Devices Supported MCUs ============== -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| 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 | | | | | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| 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 | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | -+--------------+-----+-----------------------+--------+------+-----------+-------------------+-------------------+ -| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | NUC505 | ✔ | | ✔ | nuc505 | | -+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | -| | +-------------------+--------+------+-----------+-------------------+-------------------+ -| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | -| +---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| | MCX | N9 | ✔ | | ✔ | ci_fs, ci_hs | | -+--------------+---------+-------------------+--------+------+-----------+-------------------+-------------------+ -| 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 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 105, 107 | ✔ | | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | F2 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F4 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | F7 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | G0 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | H5 | ✔ | | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | H7 | ✔ | | ✔ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L0 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L1 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | L4+ | ✔ | | ✖ | dwc2 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 575, 585 | ✔ | | ✖ | dwc2 | | -| | +------------------------+--------+------+-----------+-------------------+-------------------+ -| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | -| +----+------------------------+--------+------+-----------+-------------------+-------------------+ -| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | MSP432E4 | ✔ | | ✖ | musb | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | TM4C123 | ✔ | | ✖ | musb | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ -| WCH | CH32F20x | ✔ | | ✔ | ch32f205 | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | CH32V20x | ✔ | | ✖ | ch32v20x | | -| +-----------------------------+--------+------+-----------+-------------------+-------------------+ -| | CH32V307 | ✔ | | ✔ | ch32v307 | | -+--------------+-----------------------------+--------+------+-----------+-------------------+-------------------+ ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| 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 | | | | | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Brigetek | FT90x | ✔ | | ✔ | ft9xx | 1-dir ep | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Broadcom | BCM2711, BCM2837 | ✔ | | ✔ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Dialog | DA1469x | ✔ | ✖ | ✖ | da146xx | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Espressif | ESP32 S2, S3 | ✔ | | ✖ | dwc2 or esp32sx | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| GigaDevice | GD32VF103 | ✔ | | ✖ | dwc2 | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| 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 | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| Mind Montion | mm32 | ✔ | | ✖ | mm32f327x_otg | ci_fs variant | ++--------------+-----+-----------------------+--------+------+-----------+------------------------+-------------------+ +| NordicSemi | nRF 52833, 52840, 5340 | ✔ | ✖ | ✖ | nrf5x | only ep8 is ISO | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| Nuvoton | NUC120 | ✔ | ✖ | ✖ | nuc120 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC121/NUC125 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC126 | ✔ | ✖ | ✖ | nuc121 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | NUC505 | ✔ | | ✔ | nuc505 | | ++--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| NXP | iMXRT | RT 10xx, 11xx | ✔ | ✔ | ✔ | ci_hs | | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | Kinetis | KL | ✔ | ⚠ | ✖ | ci_fs, khci | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | K32L2 | ✔ | | ✖ | khci | ci_fs variant | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | LPC | 11u, 13, 15 | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 17, 40 | ✔ | ⚠ | ✖ | lpc17_40 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 18, 43 | ✔ | ✔ | ✔ | ci_hs | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 51u | ✔ | ✖ | ✖ | lpc_ip3511 | | +| | +-------------------+--------+------+-----------+------------------------+-------------------+ +| | | 54, 55 | ✔ | | ✔ | lpc_ip3511 | | +| +---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| | MCX | N9, A15 | ✔ | | ✔ | ci_fs, ci_hs | | ++--------------+---------+-------------------+--------+------+-----------+------------------------+-------------------+ +| 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 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | F1 | 102, 103 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 105, 107 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | F2, F4, F7, H7 | ✔ | | ✔ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | F3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | G0, H5 | ✔ | | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | G4 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L0, L1 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L4 | 4x2, 4x3 | ✔ | ✖ | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 4x5, 4x6 | ✔ | | ✖ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | L4+ | ✔ | | ✖ | dwc2 | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | L5 | ✔ | ✖ | ✖ | stm32_fsdev | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | U5 | 535, 545 | ✔ | | ✖ | stm32_fsdev | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 575, 585 | ✔ | | ✖ | dwc2 | | +| | +------------------------+--------+------+-----------+------------------------+-------------------+ +| | | 59x,5Ax,5Fx,5Gx | ✔ | | ✔ | dwc2 | | +| +----+------------------------+--------+------+-----------+------------------------+-------------------+ +| | WBx5 | ✔ | ✖ | ✖ | stm32_fsdev | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| TI | MSP430 | ✔ | ✖ | ✖ | msp430x5xx | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | MSP432E4 | ✔ | | ✖ | musb | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | TM4C123 | ✔ | | ✖ | musb | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| ValentyUSB | eptri | ✔ | ✖ | ✖ | eptri | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ +| WCH | CH32F20x | ✔ | | ✔ | ch32_usbhs | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | CH32V20x | ✔ | | ✖ | stm32_fsdev/ch32_usbfs | | +| +-----------------------------+--------+------+-----------+------------------------+-------------------+ +| | CH32V307 | ✔ | | ✔ | ch32_usbfs/hs | | ++--------------+-----------------------------+--------+------+-----------+------------------------+-------------------+ Table Legend diff --git a/examples/device/webusb_serial/src/main.c b/examples/device/webusb_serial/src/main.c index 800d435b8a..bcc33f657e 100644 --- a/examples/device/webusb_serial/src/main.c +++ b/examples/device/webusb_serial/src/main.c @@ -73,8 +73,7 @@ static uint32_t blink_interval_ms = BLINK_NOT_MOUNTED; #define URL "example.tinyusb.org/webusb-serial/index.html" -const tusb_desc_webusb_url_t desc_url = -{ +const tusb_desc_webusb_url_t desc_url = { .bLength = 3 + sizeof(URL) - 1, .bDescriptorType = 3, // WEBUSB URL type .bScheme = 1, // 0: http, 1: https @@ -86,11 +85,9 @@ static bool web_serial_connected = false; //------------- prototypes -------------// void led_blinking_task(void); void cdc_task(void); -void webserial_task(void); /*------------- MAIN -------------*/ -int main(void) -{ +int main(void) { board_init(); // init device stack on configured roothub port @@ -100,33 +97,28 @@ int main(void) board_init_after_tusb(); } - while (1) - { + while (1) { tud_task(); // tinyusb device task cdc_task(); - webserial_task(); led_blinking_task(); } } // send characters to both CDC and WebUSB -void echo_all(uint8_t buf[], uint32_t count) -{ +void echo_all(const uint8_t buf[], uint32_t count) { // echo to web serial - if ( web_serial_connected ) - { + if (web_serial_connected) { tud_vendor_write(buf, count); tud_vendor_write_flush(); } // echo to cdc - if ( tud_cdc_connected() ) - { - for(uint32_t i=0; ibmRequestType_bit.type) - { + switch (request->bmRequestType_bit.type) { case TUSB_REQ_TYPE_VENDOR: - switch (request->bRequest) - { + switch (request->bRequest) { case VENDOR_REQUEST_WEBUSB: // match vendor request in BOS descriptor // Get landing page url - return tud_control_xfer(rhport, request, (void*)(uintptr_t) &desc_url, desc_url.bLength); + return tud_control_xfer(rhport, request, (void*)(uintptr_t)&desc_url, desc_url.bLength); case VENDOR_REQUEST_MICROSOFT: - if ( request->wIndex == 7 ) - { + if (request->wIndex == 7) { // Get Microsoft OS 2.0 compatible descriptor uint16_t total_len; - memcpy(&total_len, desc_ms_os_20+8, 2); + memcpy(&total_len, desc_ms_os_20 + 8, 2); - return tud_control_xfer(rhport, request, (void*)(uintptr_t) desc_ms_os_20, total_len); - }else - { + return tud_control_xfer(rhport, request, (void*)(uintptr_t)desc_ms_os_20, total_len); + } else { return false; } default: break; } - break; + break; case TUSB_REQ_TYPE_CLASS: - if (request->bRequest == 0x22) - { + if (request->bRequest == 0x22) { // Webserial simulate the CDC_REQUEST_SET_CONTROL_LINE_STATE (0x22) to connect and disconnect. web_serial_connected = (request->wValue != 0); // Always lit LED if connected - if ( web_serial_connected ) - { + if (web_serial_connected) { board_led_write(true); blink_interval_ms = BLINK_ALWAYS_ON; tud_vendor_write_str("\r\nWebUSB interface connected\r\n"); tud_vendor_write_flush(); - }else - { + } else { blink_interval_ms = BLINK_MOUNTED; } // response with status OK return tud_control_status(rhport, request); } - break; + break; default: break; } @@ -233,32 +213,24 @@ bool tud_vendor_control_xfer_cb(uint8_t rhport, uint8_t stage, tusb_control_requ return false; } -void webserial_task(void) -{ - if ( web_serial_connected ) - { - if ( tud_vendor_available() ) - { - uint8_t buf[64]; - uint32_t count = tud_vendor_read(buf, sizeof(buf)); +void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize) { + (void) itf; - // echo back to both web serial and cdc - echo_all(buf, count); - } - } -} + echo_all(buffer, bufsize); + // if using RX buffered is enabled, we need to flush the buffer to make room for new data + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + tud_vendor_read_flush(); + #endif +} //--------------------------------------------------------------------+ // USB CDC //--------------------------------------------------------------------+ -void cdc_task(void) -{ - if ( tud_cdc_connected() ) - { +void cdc_task(void) { + if (tud_cdc_connected()) { // connected and there are data available - if ( tud_cdc_available() ) - { + if (tud_cdc_available()) { uint8_t buf[64]; uint32_t count = tud_cdc_read(buf, sizeof(buf)); @@ -270,34 +242,30 @@ void cdc_task(void) } // Invoked when cdc when line state changed e.g connected/disconnected -void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) -{ - (void) itf; +void tud_cdc_line_state_cb(uint8_t itf, bool dtr, bool rts) { + (void)itf; // connected - if ( dtr && rts ) - { + if (dtr && rts) { // print initial message when connected tud_cdc_write_str("\r\nTinyUSB WebUSB device example\r\n"); } } // Invoked when CDC interface received data from host -void tud_cdc_rx_cb(uint8_t itf) -{ - (void) itf; +void tud_cdc_rx_cb(uint8_t itf) { + (void)itf; } //--------------------------------------------------------------------+ // BLINKING TASK //--------------------------------------------------------------------+ -void led_blinking_task(void) -{ +void led_blinking_task(void) { static uint32_t start_ms = 0; static bool led_state = false; // Blink every interval ms - if ( board_millis() - start_ms < blink_interval_ms) return; // not enough time + if (board_millis() - start_ms < blink_interval_ms) return; // not enough time start_ms += blink_interval_ms; board_led_write(led_state); diff --git a/examples/device/webusb_serial/src/tusb_config.h b/examples/device/webusb_serial/src/tusb_config.h index fde732b9ec..b86ad37525 100644 --- a/examples/device/webusb_serial/src/tusb_config.h +++ b/examples/device/webusb_serial/src/tusb_config.h @@ -102,7 +102,7 @@ #define CFG_TUD_CDC_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) // Vendor FIFO size of TX and RX -// If not configured vendor endpoints will not be buffered +// If zero: vendor endpoints will not be buffered #define CFG_TUD_VENDOR_RX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) #define CFG_TUD_VENDOR_TX_BUFSIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) diff --git a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake index b8e5890f3f..2afe0f2649 100644 --- a/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake +++ b/hw/bsp/rp2040/boards/feather_rp2040_max3421/board.cmake @@ -1,3 +1,4 @@ +set(PICO_PLATFORM rp2040) set(PICO_BOARD adafruit_feather_rp2040) # Enable MAX3421E USB Host diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake b/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake index f9887c09c4..804cdb50a5 100644 --- a/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake +++ b/hw/bsp/rp2040/boards/raspberry_pi_pico/board.cmake @@ -1 +1,2 @@ +set(PICO_PLATFORM rp2040) set(PICO_BOARD pico) diff --git a/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake new file mode 100644 index 0000000000..3482e2674e --- /dev/null +++ b/hw/bsp/rp2040/boards/raspberry_pi_pico2/board.cmake @@ -0,0 +1,2 @@ +set(PICO_PLATFORM rp2350-arm-s) +set(PICO_BOARD pico2) diff --git a/hw/bsp/rp2040/family.cmake b/hw/bsp/rp2040/family.cmake index d91821ffae..8f01eac749 100644 --- a/hw/bsp/rp2040/family.cmake +++ b/hw/bsp/rp2040/family.cmake @@ -6,21 +6,32 @@ if (NOT BOARD) set(BOARD pico_sdk) endif() -if (TOOLCHAIN STREQUAL "clang") - set(PICO_COMPILER "pico_arm_clang") -else() - set(PICO_COMPILER "pico_arm_gcc") -endif() +include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) + +#if (TOOLCHAIN STREQUAL "clang") +# set(PICO_COMPILER "pico_arm_clang") +#else() +# set(PICO_COMPILER "pico_arm_gcc") +#endif() # add the SDK in case we are standalone tinyusb example (noop if already present) include(${CMAKE_CURRENT_LIST_DIR}/pico_sdk_import.cmake) # include basic family CMake functionality set(FAMILY_MCUS RP2040) -set(JLINK_DEVICE rp2040_m0_0) -set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/rp2040.cfg -c \"adapter speed 5000\"") -include(${CMAKE_CURRENT_LIST_DIR}/boards/${BOARD}/board.cmake) +if (PICO_PLATFORM STREQUAL "rp2040") + set(JLINK_DEVICE rp2040_m0_0) + set(OPENOCD_TARGET rp2040) +elseif (PICO_PLATFORM STREQUAL "rp2350-arm-s" OR PICO_PLATFORM STREQUAL "rp2350") + set(JLINK_DEVICE rp2350_m33_0) + set(OPENOCD_TARGET rp2350) +elseif (PICO_PLATFORM STREQUAL "rp2350-riscv") + set(JLINK_DEVICE rp2350_riscv_0) + set(OPENOCD_TARGET rp2350-riscv) +endif() + +set(OPENOCD_OPTION "-f interface/cmsis-dap.cfg -f target/${OPENOCD_TARGET}.cfg -c \"adapter speed 5000\"") if (NOT PICO_TINYUSB_PATH) set(PICO_TINYUSB_PATH ${TOP}) diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake new file mode 100644 index 0000000000..1cb92d7109 --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.cmake @@ -0,0 +1,8 @@ +set(MCU_VARIANT stm32u585xx) +set(JLINK_DEVICE stm32u585zi) + +function(update_board TARGET) + target_compile_definitions(${TARGET} PUBLIC + STM32U585xx + ) +endfunction() diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h new file mode 100644 index 0000000000..2f1c451db2 --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.h @@ -0,0 +1,112 @@ +/* + * The MIT License (MIT) + * + * Copyright (c) 2023, Ha Thach (tinyusb.org) + * + * Permission is hereby granted, free of charge, to any person obtaining a copy + * of this software and associated documentation files (the "Software"), to deal + * in the Software without restriction, including without limitation the rights + * to use, copy, modify, merge, publish, distribute, sublicense, and/or sell + * copies of the Software, and to permit persons to whom the Software is + * furnished to do so, subject to the following conditions: + * + * The above copyright notice and this permission notice shall be included in + * all copies or substantial portions of the Software. + * + * THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR + * IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY, + * FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE + * AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER + * LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM, + * OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN + * THE SOFTWARE. + * + * This file is part of the TinyUSB stack. + */ + +#ifndef BOARD_H_ +#define BOARD_H_ + +#ifdef __cplusplus +extern "C" +{ +#endif + +// LED GREEN +#define LED_PORT GPIOH +#define LED_PIN GPIO_PIN_7 +#define LED_STATE_ON 0 + +// BUTTON +#define BUTTON_PORT GPIOC +#define BUTTON_PIN GPIO_PIN_13 +#define BUTTON_STATE_ACTIVE 1 + +// UART Enable for STLink VCOM +#define UART_DEV USART1 +#define UART_CLK_EN __HAL_RCC_USART1_CLK_ENABLE +#define UART_GPIO_PORT GPIOA +#define UART_GPIO_AF GPIO_AF7_USART1 +#define UART_TX_PIN GPIO_PIN_9 +#define UART_RX_PIN GPIO_PIN_10 + +//--------------------------------------------------------------------+ +// RCC Clock +//--------------------------------------------------------------------+ + +static void SystemClock_Config(void) { + RCC_OscInitTypeDef RCC_OscInitStruct = { 0 }; + RCC_ClkInitTypeDef RCC_ClkInitStruct = { 0 }; + RCC_PeriphCLKInitTypeDef PeriphClkInit = { 0 }; + + /* Enable Power Clock */ + __HAL_RCC_PWR_CLK_ENABLE(); + + /** Configure the main internal regulator output voltage + */ + HAL_PWREx_ControlVoltageScaling(PWR_REGULATOR_VOLTAGE_SCALE1); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_OscInitStruct.OscillatorType = RCC_OSCILLATORTYPE_HSI48 | RCC_OSCILLATORTYPE_HSI; + RCC_OscInitStruct.HSIState = RCC_HSI_ON; + RCC_OscInitStruct.HSI48State = RCC_HSI48_ON; + RCC_OscInitStruct.HSICalibrationValue = RCC_HSICALIBRATION_DEFAULT; + RCC_OscInitStruct.PLL.PLLState = RCC_PLL_ON; + RCC_OscInitStruct.PLL.PLLSource = RCC_PLLSOURCE_HSI; + RCC_OscInitStruct.PLL.PLLMBOOST = RCC_PLLMBOOST_DIV1; + RCC_OscInitStruct.PLL.PLLM = 1; + RCC_OscInitStruct.PLL.PLLN = 10; + RCC_OscInitStruct.PLL.PLLP = 2; + RCC_OscInitStruct.PLL.PLLQ = 2; + RCC_OscInitStruct.PLL.PLLR = 1; + RCC_OscInitStruct.PLL.PLLRGE = RCC_PLLVCIRANGE_1; + RCC_OscInitStruct.PLL.PLLFRACN = 0; + HAL_RCC_OscConfig(&RCC_OscInitStruct); + + PeriphClkInit.PeriphClockSelection = RCC_PERIPHCLK_CLK48; + PeriphClkInit.IclkClockSelection = RCC_CLK48CLKSOURCE_HSI48; + + HAL_RCCEx_PeriphCLKConfig(&PeriphClkInit); + + /** Initializes the CPU, AHB and APB buses clocks + */ + RCC_ClkInitStruct.ClockType = + RCC_CLOCKTYPE_HCLK | RCC_CLOCKTYPE_SYSCLK | RCC_CLOCKTYPE_PCLK1 | RCC_CLOCKTYPE_PCLK2 | RCC_CLOCKTYPE_PCLK3; + RCC_ClkInitStruct.SYSCLKSource = RCC_SYSCLKSOURCE_PLLCLK; + RCC_ClkInitStruct.AHBCLKDivider = RCC_SYSCLK_DIV1; + RCC_ClkInitStruct.APB1CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB2CLKDivider = RCC_HCLK_DIV1; + RCC_ClkInitStruct.APB3CLKDivider = RCC_HCLK_DIV1; + + HAL_RCC_ClockConfig(&RCC_ClkInitStruct, FLASH_LATENCY_4); +} + +static void SystemPower_Config(void) { +} + +#ifdef __cplusplus +} +#endif + +#endif /* BOARD_H_ */ diff --git a/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk new file mode 100644 index 0000000000..ae63afef32 --- /dev/null +++ b/hw/bsp/stm32u5/boards/b_u585i_iot2a/board.mk @@ -0,0 +1,11 @@ +CFLAGS += \ + -DSTM32U585xx \ + +# All source paths should be relative to the top level. +LD_FILE = ${FAMILY_PATH}/linker/STM32U575xx_FLASH.ld + +SRC_S += $(ST_CMSIS)/Source/Templates/gcc/startup_stm32u575xx.s + +MCU_VARIANT = stm32u585xx +# For flash-jlink target +JLINK_DEVICE = stm32u585zi diff --git a/library.json b/library.json index 3cdd5990f2..c945d4b52f 100644 --- a/library.json +++ b/library.json @@ -1,6 +1,6 @@ { "name": "TinyUSB", - "version": "0.16.0", + "version": "0.17.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 28666d2d4c..df7895e84b 100644 --- a/repository.yml +++ b/repository.yml @@ -14,5 +14,6 @@ repo.versions: "0.14.0": "0.14.0" "0.15.0": "0.15.0" "0.16.0": "0.16.0" - "0-latest": "0.16.0" + "0.17.0": "0.17.0" + "0-latest": "0.17.0" "0-dev": "0.0.0" diff --git a/src/class/cdc/cdc_host.c b/src/class/cdc/cdc_host.c index 133a10f6ec..8717970e60 100644 --- a/src/class/cdc/cdc_host.c +++ b/src/class/cdc/cdc_host.c @@ -341,14 +341,14 @@ uint32_t tuh_cdc_write(uint8_t idx, void const* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write(&p_cdc->stream.tx, buffer, bufsize); + return tu_edpt_stream_write(p_cdc->daddr, &p_cdc->stream.tx, buffer, bufsize); } uint32_t tuh_cdc_write_flush(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_xfer(&p_cdc->stream.tx); + return tu_edpt_stream_write_xfer(p_cdc->daddr, &p_cdc->stream.tx); } bool tuh_cdc_write_clear(uint8_t idx) { @@ -362,7 +362,7 @@ uint32_t tuh_cdc_write_available(uint8_t idx) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_write_available(&p_cdc->stream.tx); + return tu_edpt_stream_write_available(p_cdc->daddr, &p_cdc->stream.tx); } //--------------------------------------------------------------------+ @@ -373,7 +373,7 @@ uint32_t tuh_cdc_read (uint8_t idx, void* buffer, uint32_t bufsize) { cdch_interface_t* p_cdc = get_itf(idx); TU_VERIFY(p_cdc); - return tu_edpt_stream_read(&p_cdc->stream.rx, buffer, bufsize); + return tu_edpt_stream_read(p_cdc->daddr, &p_cdc->stream.rx, buffer, bufsize); } uint32_t tuh_cdc_read_available(uint8_t idx) { @@ -395,7 +395,7 @@ bool tuh_cdc_read_clear (uint8_t idx) { TU_VERIFY(p_cdc); bool ret = tu_edpt_stream_clear(&p_cdc->stream.rx); - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); return ret; } @@ -677,10 +677,10 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t // invoke tx complete callback to possibly refill tx fifo if (tuh_cdc_tx_complete_cb) tuh_cdc_tx_complete_cb(idx); - if ( 0 == tu_edpt_stream_write_xfer(&p_cdc->stream.tx) ) { + if ( 0 == tu_edpt_stream_write_xfer(daddr, &p_cdc->stream.tx) ) { // If there is no data left, a ZLP should be sent if: // - xferred_bytes is multiple of EP Packet size and not zero - tu_edpt_stream_write_zlp_if_needed(&p_cdc->stream.tx, xferred_bytes); + tu_edpt_stream_write_zlp_if_needed(daddr, &p_cdc->stream.tx, xferred_bytes); } } else if ( ep_addr == p_cdc->stream.rx.ep_addr ) { #if CFG_TUH_CDC_FTDI @@ -698,7 +698,7 @@ bool cdch_xfer_cb(uint8_t daddr, uint8_t ep_addr, xfer_result_t event, uint32_t if (tuh_cdc_rx_cb) tuh_cdc_rx_cb(idx); // prepare for next transfer if needed - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(daddr, &p_cdc->stream.rx); }else if ( ep_addr == p_cdc->ep_notif ) { // TODO handle notification endpoint }else { @@ -719,9 +719,9 @@ static bool open_ep_stream_pair(cdch_interface_t* p_cdc, tusb_desc_endpoint_t co TU_ASSERT(tuh_edpt_open(p_cdc->daddr, desc_ep)); if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { - tu_edpt_stream_open(&p_cdc->stream.rx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.rx, desc_ep); } else { - tu_edpt_stream_open(&p_cdc->stream.tx, p_cdc->daddr, desc_ep); + tu_edpt_stream_open(&p_cdc->stream.tx, desc_ep); } desc_ep = (tusb_desc_endpoint_t const*) tu_desc_next(desc_ep); @@ -763,7 +763,7 @@ static void set_config_complete(cdch_interface_t * p_cdc, uint8_t idx, uint8_t i if (tuh_cdc_mount_cb) tuh_cdc_mount_cb(idx); // Prepare for incoming data - tu_edpt_stream_read_xfer(&p_cdc->stream.rx); + tu_edpt_stream_read_xfer(p_cdc->daddr, &p_cdc->stream.rx); // notify usbh that driver enumeration is complete usbh_driver_set_config_complete(p_cdc->daddr, itf_num); diff --git a/src/class/vendor/vendor_device.c b/src/class/vendor/vendor_device.c index 56ef098c7a..15829991a6 100644 --- a/src/class/vendor/vendor_device.c +++ b/src/class/vendor/vendor_device.c @@ -36,136 +36,103 @@ //--------------------------------------------------------------------+ // MACRO CONSTANT TYPEDEF //--------------------------------------------------------------------+ -#define BULK_PACKET_SIZE (TUD_OPT_HIGH_SPEED ? 512 : 64) - -typedef struct -{ +typedef struct { uint8_t itf_num; - uint8_t ep_in; - uint8_t ep_out; /*------------- From this point, data is not cleared by bus reset -------------*/ - tu_fifo_t rx_ff; - tu_fifo_t tx_ff; + // Endpoint Transfer buffer + CFG_TUD_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; + CFG_TUD_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; - uint8_t rx_ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; - uint8_t tx_ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + struct { + tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + uint8_t ff_buf[CFG_TUD_VENDOR_TX_BUFSIZE]; + #endif + }tx; - OSAL_MUTEX_DEF(rx_ff_mutex); - OSAL_MUTEX_DEF(tx_ff_mutex); + struct { + tu_edpt_stream_t stream; + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + uint8_t ff_buf[CFG_TUD_VENDOR_RX_BUFSIZE]; + #endif + } rx; - // Endpoint Transfer buffer - CFG_TUSB_MEM_ALIGN uint8_t epout_buf[CFG_TUD_VENDOR_EPSIZE]; - CFG_TUSB_MEM_ALIGN uint8_t epin_buf[CFG_TUD_VENDOR_EPSIZE]; } vendord_interface_t; -CFG_TUD_MEM_SECTION tu_static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; - -#define ITF_MEM_RESET_SIZE offsetof(vendord_interface_t, rx_ff) +CFG_TUD_MEM_SECTION static vendord_interface_t _vendord_itf[CFG_TUD_VENDOR]; +#define ITF_MEM_RESET_SIZE (offsetof(vendord_interface_t, itf_num) + sizeof(((vendord_interface_t *)0)->itf_num)) -bool tud_vendor_n_mounted (uint8_t itf) -{ - return _vendord_itf[itf].ep_in && _vendord_itf[itf].ep_out; -} +//-------------------------------------------------------------------- +// Application API +//-------------------------------------------------------------------- -uint32_t tud_vendor_n_available (uint8_t itf) -{ - return tu_fifo_count(&_vendord_itf[itf].rx_ff); -} - -bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) -{ - return tu_fifo_peek(&_vendord_itf[itf].rx_ff, u8); +bool tud_vendor_n_mounted(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + return p_itf->rx.stream.ep_addr || p_itf->tx.stream.ep_addr; } //--------------------------------------------------------------------+ // Read API //--------------------------------------------------------------------+ -static void _prep_out_transaction (vendord_interface_t* p_itf) -{ - uint8_t const rhport = 0; +uint32_t tud_vendor_n_available(uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + + return tu_edpt_stream_read_available(&p_itf->rx.stream); +} - // claim endpoint - TU_VERIFY(usbd_edpt_claim(rhport, p_itf->ep_out), ); +bool tud_vendor_n_peek(uint8_t itf, uint8_t* u8) { + TU_VERIFY(itf < CFG_TUD_VENDOR); + vendord_interface_t* p_itf = &_vendord_itf[itf]; - // Prepare for incoming data but only allow what we can store in the ring buffer. - uint16_t max_read = tu_fifo_remaining(&p_itf->rx_ff); - if ( max_read >= CFG_TUD_VENDOR_EPSIZE ) - { - usbd_edpt_xfer(rhport, p_itf->ep_out, p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); - } - else - { - // Release endpoint since we don't make any transfer - usbd_edpt_release(rhport, p_itf->ep_out); - } + return tu_edpt_stream_peek(&p_itf->rx.stream, u8); } -uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) -{ +uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint32_t num_read = tu_fifo_read_n(&p_itf->rx_ff, buffer, (uint16_t) bufsize); - _prep_out_transaction(p_itf); - return num_read; + uint8_t const rhport = 0; + + return tu_edpt_stream_read(rhport, &p_itf->rx.stream, buffer, bufsize); } -void tud_vendor_n_read_flush (uint8_t itf) -{ +void tud_vendor_n_read_flush (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, ); vendord_interface_t* p_itf = &_vendord_itf[itf]; - tu_fifo_clear(&p_itf->rx_ff); - _prep_out_transaction(p_itf); + uint8_t const rhport = 0; + + tu_edpt_stream_clear(&p_itf->rx.stream); + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); } //--------------------------------------------------------------------+ // Write API //--------------------------------------------------------------------+ -uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) -{ +uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t bufsize) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - uint16_t ret = tu_fifo_write_n(&p_itf->tx_ff, buffer, (uint16_t) bufsize); + uint8_t const rhport = 0; - // flush if queue more than packet size - if (tu_fifo_count(&p_itf->tx_ff) >= CFG_TUD_VENDOR_EPSIZE) { - tud_vendor_n_write_flush(itf); - } - return ret; + return tu_edpt_stream_write(rhport, &p_itf->tx.stream, buffer, (uint16_t) bufsize); } -uint32_t tud_vendor_n_write_flush (uint8_t itf) -{ +uint32_t tud_vendor_n_write_flush (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); vendord_interface_t* p_itf = &_vendord_itf[itf]; - - // Skip if usb is not ready yet - TU_VERIFY( tud_ready(), 0 ); - - // No data to send - if ( !tu_fifo_count(&p_itf->tx_ff) ) return 0; - uint8_t const rhport = 0; - // Claim the endpoint - TU_VERIFY( usbd_edpt_claim(rhport, p_itf->ep_in), 0 ); - - // Pull data from FIFO - uint16_t const count = tu_fifo_read_n(&p_itf->tx_ff, p_itf->epin_buf, sizeof(p_itf->epin_buf)); - - if ( count ) - { - TU_ASSERT( usbd_edpt_xfer(rhport, p_itf->ep_in, p_itf->epin_buf, count), 0 ); - return count; - }else - { - // Release endpoint since we don't make any transfer - // Note: data is dropped if terminal is not connected - usbd_edpt_release(rhport, p_itf->ep_in); - return 0; - } + return tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream); } -uint32_t tud_vendor_n_write_available (uint8_t itf) -{ - return tu_fifo_remaining(&_vendord_itf[itf].tx_ff); +uint32_t tud_vendor_n_write_available (uint8_t itf) { + TU_VERIFY(itf < CFG_TUD_VENDOR, 0); + vendord_interface_t* p_itf = &_vendord_itf[itf]; + uint8_t const rhport = 0; + + return tu_edpt_stream_write_available(rhport, &p_itf->tx.stream); } //--------------------------------------------------------------------+ @@ -177,70 +144,59 @@ void vendord_init(void) { for(uint8_t i=0; irx_ff, p_itf->rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, 1, false); - tu_fifo_config(&p_itf->tx_ff, p_itf->tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, 1, false); - - #if OSAL_MUTEX_REQUIRED - osal_mutex_t mutex_rd = osal_mutex_create(&p_itf->rx_ff_mutex); - osal_mutex_t mutex_wr = osal_mutex_create(&p_itf->tx_ff_mutex); - TU_ASSERT(mutex_rd && mutex_wr,); - - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, mutex_rd); - tu_fifo_config_mutex(&p_itf->tx_ff, mutex_wr, NULL); - #endif + uint8_t* rx_ff_buf = + #if CFG_TUD_VENDOR_RX_BUFSIZE > 0 + p_itf->rx.ff_buf; + #else + NULL; + #endif + + tu_edpt_stream_init(&p_itf->rx.stream, false, false, false, + rx_ff_buf, CFG_TUD_VENDOR_RX_BUFSIZE, + p_itf->epout_buf, CFG_TUD_VENDOR_EPSIZE); + + uint8_t* tx_ff_buf = + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + p_itf->tx.ff_buf; + #else + NULL; + #endif + + tu_edpt_stream_init(&p_itf->tx.stream, false, true, false, + tx_ff_buf, CFG_TUD_VENDOR_TX_BUFSIZE, + p_itf->epin_buf, CFG_TUD_VENDOR_EPSIZE); } } bool vendord_deinit(void) { - #if OSAL_MUTEX_REQUIRED for(uint8_t i=0; irx_ff.mutex_rd; - osal_mutex_t mutex_wr = p_itf->tx_ff.mutex_wr; - - if (mutex_rd) { - osal_mutex_delete(mutex_rd); - tu_fifo_config_mutex(&p_itf->rx_ff, NULL, NULL); - } - - if (mutex_wr) { - osal_mutex_delete(mutex_wr); - tu_fifo_config_mutex(&p_itf->tx_ff, NULL, NULL); - } + tu_edpt_stream_deinit(&p_itf->rx.stream); + tu_edpt_stream_deinit(&p_itf->tx.stream); } - #endif - return true; } -void vendord_reset(uint8_t rhport) -{ +void vendord_reset(uint8_t rhport) { (void) rhport; - for(uint8_t i=0; irx_ff); - tu_fifo_clear(&p_itf->tx_ff); + tu_edpt_stream_clear(&p_itf->rx.stream); + tu_edpt_stream_clear(&p_itf->tx.stream); } } -uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) -{ +uint16_t vendord_open(uint8_t rhport, tusb_desc_interface_t const * desc_itf, uint16_t max_len) { TU_VERIFY(TUSB_CLASS_VENDOR_SPECIFIC == desc_itf->bInterfaceClass, 0); - - uint8_t const * p_desc = tu_desc_next(desc_itf); - uint8_t const * desc_end = p_desc + max_len; + const uint8_t* p_desc = tu_desc_next(desc_itf); + const uint8_t* desc_end = p_desc + max_len; // Find available interface vendord_interface_t* p_vendor = NULL; - for(uint8_t i=0; iitf_num = desc_itf->bInterfaceNumber; - if (desc_itf->bNumEndpoints) - { + uint8_t found_ep = 0; + while (found_ep < desc_itf->bNumEndpoints) { // skip non-endpoint descriptors - while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) - { + while ( (TUSB_DESC_ENDPOINT != tu_desc_type(p_desc)) && (p_desc < desc_end) ) { p_desc = tu_desc_next(p_desc); } + if (p_desc >= desc_end) { + break; + } - // Open endpoint pair with usbd helper - TU_ASSERT(usbd_open_edpt_pair(rhport, p_desc, desc_itf->bNumEndpoints, TUSB_XFER_BULK, &p_vendor->ep_out, &p_vendor->ep_in), 0); - - p_desc += desc_itf->bNumEndpoints*sizeof(tusb_desc_endpoint_t); + const tusb_desc_endpoint_t* desc_ep = (const tusb_desc_endpoint_t*) p_desc; + TU_ASSERT(usbd_edpt_open(rhport, desc_ep)); + found_ep++; - // Prepare for incoming data - if ( p_vendor->ep_out ) - { - _prep_out_transaction(p_vendor); + if (tu_edpt_dir(desc_ep->bEndpointAddress) == TUSB_DIR_IN) { + tu_edpt_stream_open(&p_vendor->tx.stream, desc_ep); + tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); + } else { + tu_edpt_stream_open(&p_vendor->rx.stream, desc_ep); + TU_ASSERT(tu_edpt_stream_read_xfer(rhport, &p_vendor->rx.stream) > 0, 0); // prepare for incoming data } - if ( p_vendor->ep_in ) tud_vendor_n_write_flush((uint8_t)(p_vendor - _vendord_itf)); + p_desc = tu_desc_next(p_desc); } return (uint16_t) ((uintptr_t) p_desc - (uintptr_t) desc_itf); } -bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) -{ +bool vendord_xfer_cb(uint8_t rhport, uint8_t ep_addr, xfer_result_t result, uint32_t xferred_bytes) { (void) result; uint8_t itf = 0; vendord_interface_t* p_itf = _vendord_itf; - for ( ; ; itf++, p_itf++) - { - if (itf >= TU_ARRAY_SIZE(_vendord_itf)) return false; - - if ( ( ep_addr == p_itf->ep_out ) || ( ep_addr == p_itf->ep_in ) ) break; + for ( ; ; itf++, p_itf++) { + if (itf >= CFG_TUD_VENDOR) return false; + if ((ep_addr == p_itf->rx.stream.ep_addr) || (ep_addr == p_itf->tx.stream.ep_addr)) break; } - if ( ep_addr == p_itf->ep_out ) - { - // Receive new data - tu_fifo_write_n(&p_itf->rx_ff, p_itf->epout_buf, (uint16_t) xferred_bytes); + if ( ep_addr == p_itf->rx.stream.ep_addr ) { + // Received new data: put into stream's fifo + tu_edpt_stream_read_xfer_complete(&p_itf->rx.stream, xferred_bytes); // Invoked callback if any - if (tud_vendor_rx_cb) tud_vendor_rx_cb(itf); + if (tud_vendor_rx_cb) { + tud_vendor_rx_cb(itf, p_itf->epout_buf, (uint16_t) xferred_bytes); + } - _prep_out_transaction(p_itf); - } - else if ( ep_addr == p_itf->ep_in ) - { - if (tud_vendor_tx_cb) tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); - // Send complete, try to send more if possible - if ( 0 == tud_vendor_n_write_flush(itf) ) - { - // If there is no data left, a ZLP should be sent if - // xferred_bytes is multiple of EP Packet size and not zero - if ( !tu_fifo_count(&p_itf->tx_ff) && xferred_bytes && (0 == (xferred_bytes & (BULK_PACKET_SIZE-1))) ) - { - if ( usbd_edpt_claim(rhport, p_itf->ep_in) ) - { - usbd_edpt_xfer(rhport, p_itf->ep_in, NULL, 0); - } - } + tu_edpt_stream_read_xfer(rhport, &p_itf->rx.stream); + } else if ( ep_addr == p_itf->tx.stream.ep_addr ) { + // Send complete + if (tud_vendor_tx_cb) { + tud_vendor_tx_cb(itf, (uint16_t) xferred_bytes); } + + #if CFG_TUD_VENDOR_TX_BUFSIZE > 0 + // try to send more if possible + if ( 0 == tu_edpt_stream_write_xfer(rhport, &p_itf->tx.stream) ) { + // If there is no data left, a ZLP should be sent if xferred_bytes is multiple of EP Packet size and not zero + tu_edpt_stream_write_zlp_if_needed(rhport, &p_itf->tx.stream, xferred_bytes); + } + #endif } return true; diff --git a/src/class/vendor/vendor_device.h b/src/class/vendor/vendor_device.h index cd69ec7c65..149ae2d564 100644 --- a/src/class/vendor/vendor_device.h +++ b/src/class/vendor/vendor_device.h @@ -33,15 +33,24 @@ #define CFG_TUD_VENDOR_EPSIZE 64 #endif +// RX FIFO can be disabled by setting this value to 0 +#ifndef CFG_TUD_VENDOR_RX_BUFSIZE +#define CFG_TUD_VENDOR_RX_BUFSIZE 64 +#endif + +// TX FIFO can be disabled by setting this value to 0 +#ifndef CFG_TUD_VENDOR_TX_BUFSIZE +#define CFG_TUD_VENDOR_TX_BUFSIZE 64 +#endif + #ifdef __cplusplus extern "C" { #endif //--------------------------------------------------------------------+ -// Application API (Multiple Interfaces) +// Application API (Multiple Interfaces) i.e CFG_TUD_VENDOR > 1 //--------------------------------------------------------------------+ bool tud_vendor_n_mounted (uint8_t itf); - uint32_t tud_vendor_n_available (uint8_t itf); uint32_t tud_vendor_n_read (uint8_t itf, void* buffer, uint32_t bufsize); bool tud_vendor_n_peek (uint8_t itf, uint8_t* ui8); @@ -51,89 +60,73 @@ uint32_t tud_vendor_n_write (uint8_t itf, void const* buffer, uint32_t uint32_t tud_vendor_n_write_flush (uint8_t itf); uint32_t tud_vendor_n_write_available (uint8_t itf); -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str); // backward compatible #define tud_vendor_n_flush(itf) tud_vendor_n_write_flush(itf) //--------------------------------------------------------------------+ -// Application API (Single Port) +// Application API (Single Port) i.e CFG_TUD_VENDOR = 1 //--------------------------------------------------------------------+ -static inline bool tud_vendor_mounted (void); -static inline uint32_t tud_vendor_available (void); -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize); -static inline bool tud_vendor_peek (uint8_t* ui8); -static inline void tud_vendor_read_flush (void); -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize); -static inline uint32_t tud_vendor_write_str (char const* str); -static inline uint32_t tud_vendor_write_available (void); -static inline uint32_t tud_vendor_write_flush (void); -// backward compatible -#define tud_vendor_flush() tud_vendor_write_flush() - -//--------------------------------------------------------------------+ -// Application Callback API (weak is optional) -//--------------------------------------------------------------------+ - -// Invoked when received new data -TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf); -// Invoked when last rx transfer finished -TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); - -//--------------------------------------------------------------------+ -// Inline Functions -//--------------------------------------------------------------------+ - -static inline uint32_t tud_vendor_n_write_str (uint8_t itf, char const* str) -{ - return tud_vendor_n_write(itf, str, strlen(str)); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_n_write_str(uint8_t itf, char const* str) { + return tud_vendor_n_write(itf, str, strlen(str)); } -static inline bool tud_vendor_mounted (void) -{ - return tud_vendor_n_mounted(0); +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_mounted(void) { + return tud_vendor_n_mounted(0); } -static inline uint32_t tud_vendor_available (void) -{ - return tud_vendor_n_available(0); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_available(void) { + return tud_vendor_n_available(0); } -static inline uint32_t tud_vendor_read (void* buffer, uint32_t bufsize) -{ - return tud_vendor_n_read(0, buffer, bufsize); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_read(void* buffer, uint32_t bufsize) { + return tud_vendor_n_read(0, buffer, bufsize); } -static inline bool tud_vendor_peek (uint8_t* ui8) -{ - return tud_vendor_n_peek(0, ui8); +TU_ATTR_ALWAYS_INLINE static inline bool tud_vendor_peek(uint8_t* ui8) { + return tud_vendor_n_peek(0, ui8); } -static inline void tud_vendor_read_flush(void) -{ - tud_vendor_n_read_flush(0); +TU_ATTR_ALWAYS_INLINE static inline void tud_vendor_read_flush(void) { + tud_vendor_n_read_flush(0); } -static inline uint32_t tud_vendor_write (void const* buffer, uint32_t bufsize) -{ - return tud_vendor_n_write(0, buffer, bufsize); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write(void const* buffer, uint32_t bufsize) { + return tud_vendor_n_write(0, buffer, bufsize); } -static inline uint32_t tud_vendor_write_flush (void) -{ - return tud_vendor_n_write_flush(0); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_str(char const* str) { + return tud_vendor_n_write_str(0, str); } -static inline uint32_t tud_vendor_write_str (char const* str) -{ - return tud_vendor_n_write_str(0, str); +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_flush(void) { + return tud_vendor_n_write_flush(0); } -static inline uint32_t tud_vendor_write_available (void) -{ - return tud_vendor_n_write_available(0); +#if CFG_TUD_VENDOR_TX_BUFSIZE > 0 +TU_ATTR_ALWAYS_INLINE static inline uint32_t tud_vendor_write_available(void) { + return tud_vendor_n_write_available(0); } +#endif + +// backward compatible +#define tud_vendor_flush() tud_vendor_write_flush() + +//--------------------------------------------------------------------+ +// Application Callback API (weak is optional) +//--------------------------------------------------------------------+ + +// Invoked when received new data +TU_ATTR_WEAK void tud_vendor_rx_cb(uint8_t itf, uint8_t const* buffer, uint16_t bufsize); +// Invoked when last rx transfer finished +TU_ATTR_WEAK void tud_vendor_tx_cb(uint8_t itf, uint32_t sent_bytes); + +//--------------------------------------------------------------------+ +// Inline Functions +//--------------------------------------------------------------------+ + //--------------------------------------------------------------------+ // Internal Class Driver API diff --git a/src/common/tusb_private.h b/src/common/tusb_private.h index 373a502564..8a479c0424 100644 --- a/src/common/tusb_private.h +++ b/src/common/tusb_private.h @@ -34,32 +34,24 @@ extern "C" { #endif -typedef struct TU_ATTR_PACKED -{ +typedef struct TU_ATTR_PACKED { volatile uint8_t busy : 1; volatile uint8_t stalled : 1; volatile uint8_t claimed : 1; }tu_edpt_state_t; typedef struct { - bool is_host; // host or device most - union { - uint8_t daddr; - uint8_t rhport; - uint8_t hwid; + struct TU_ATTR_PACKED { + uint8_t is_host : 1; // 1: host, 0: device + uint8_t is_mps512 : 1; // 1: 512, 0: 64 since stream is used for Bulk only }; uint8_t ep_addr; - uint8_t ep_speed; - - uint16_t ep_packetsize; uint16_t ep_bufsize; - // TODO xfer_fifo can skip this buffer - uint8_t* ep_buf; - + uint8_t* ep_buf; // TODO xfer_fifo can skip this buffer tu_fifo_t ff; - // mutex: read if ep rx, write if e tx + // mutex: read if rx, otherwise write OSAL_MUTEX_DEF(ff_mutexdef); }tu_edpt_stream_t; @@ -95,18 +87,15 @@ bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool ove bool tu_edpt_stream_deinit(tu_edpt_stream_t* s); // Open an stream for an endpoint -// hwid is either device address (host mode) or rhport (device mode) TU_ATTR_ALWAYS_INLINE static inline -void tu_edpt_stream_open(tu_edpt_stream_t* s, uint8_t hwid, tusb_desc_endpoint_t const *desc_ep) { +void tu_edpt_stream_open(tu_edpt_stream_t* s, tusb_desc_endpoint_t const *desc_ep) { tu_fifo_clear(&s->ff); - s->hwid = hwid; s->ep_addr = desc_ep->bEndpointAddress; - s->ep_packetsize = tu_edpt_packet_size(desc_ep); + s->is_mps512 = (tu_edpt_packet_size(desc_ep) == 512) ? 1 : 0; } TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_close(tu_edpt_stream_t* s) { - s->hwid = 0; s->ep_addr = 0; } @@ -121,40 +110,40 @@ bool tu_edpt_stream_clear(tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ // Write to stream -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const *buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_write_xfer(uint8_t hwid, tu_edpt_stream_t* s); // Start an zero-length packet if needed -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes); +bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes); -// Get the number of bytes available for writing -TU_ATTR_ALWAYS_INLINE static inline -uint32_t tu_edpt_stream_write_available(tu_edpt_stream_t* s) { - return (uint32_t) tu_fifo_remaining(&s->ff); -} +// Get the number of bytes available for writing to FIFO +// Note: if no fifo, return endpoint size if not busy, 0 otherwise +uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s); //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ // Read from stream -uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); +uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize); // Start an usb transfer if endpoint is not busy -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s); +uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s); // 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) { - tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); + if (tu_fifo_depth(&s->ff)) { + tu_fifo_write_n(&s->ff, s->ep_buf, (uint16_t) xferred_bytes); + } } // Same as tu_edpt_stream_read_xfer_complete but skip the first n bytes TU_ATTR_ALWAYS_INLINE static inline void tu_edpt_stream_read_xfer_complete_offset(tu_edpt_stream_t* s, uint32_t xferred_bytes, uint32_t skip_offset) { - if (skip_offset < xferred_bytes) { + if (tu_fifo_depth(&s->ff) && (skip_offset < xferred_bytes)) { tu_fifo_write_n(&s->ff, s->ep_buf + skip_offset, (uint16_t) (xferred_bytes - skip_offset)); } } diff --git a/src/device/usbd_pvt.h b/src/device/usbd_pvt.h index 335d46cd89..90f37db3ed 100644 --- a/src/device/usbd_pvt.h +++ b/src/device/usbd_pvt.h @@ -28,6 +28,7 @@ #include "osal/osal.h" #include "common/tusb_fifo.h" +#include "common/tusb_private.h" #ifdef __cplusplus extern "C" { diff --git a/src/tusb.c b/src/tusb.c index 860e8ac350..11690b2036 100644 --- a/src/tusb.c +++ b/src/tusb.c @@ -216,13 +216,17 @@ uint16_t tu_desc_get_interface_total_len(tusb_desc_interface_t const* desc_itf, bool tu_edpt_stream_init(tu_edpt_stream_t* s, bool is_host, bool is_tx, bool overwritable, void* ff_buf, uint16_t ff_bufsize, uint8_t* ep_buf, uint16_t ep_bufsize) { - osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); - (void) new_mutex; (void) is_tx; s->is_host = is_host; tu_fifo_config(&s->ff, ff_buf, ff_bufsize, 1, overwritable); - tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); + + #if OSAL_MUTEX_REQUIRED + if (ff_buf && ff_bufsize) { + osal_mutex_t new_mutex = osal_mutex_create(&s->ff_mutexdef); + tu_fifo_config_mutex(&s->ff, is_tx ? new_mutex : NULL, is_tx ? NULL : new_mutex); + } + #endif s->ep_buf = ep_buf; s->ep_bufsize = ep_bufsize; @@ -239,43 +243,40 @@ bool tu_edpt_stream_deinit(tu_edpt_stream_t* s) { return true; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_claim(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_claim(uint8_t hwid, tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_claim(s->daddr, s->ep_addr); + return usbh_edpt_claim(hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_claim(s->rhport, s->ep_addr); + return usbd_edpt_claim(hwid, s->ep_addr); #endif } return false; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_xfer(tu_edpt_stream_t* s, uint16_t count) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_xfer(uint8_t hwid, tu_edpt_stream_t* s, uint16_t count) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_xfer(s->daddr, s->ep_addr, count ? s->ep_buf : NULL, count); + return usbh_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_xfer(s->rhport, s->ep_addr, count ? s->ep_buf : NULL, count); + return usbd_edpt_xfer(hwid, s->ep_addr, count ? s->ep_buf : NULL, count); #endif } return false; } -TU_ATTR_ALWAYS_INLINE static inline -bool stream_release(tu_edpt_stream_t* s) { +TU_ATTR_ALWAYS_INLINE static inline bool stream_release(uint8_t hwid, tu_edpt_stream_t* s) { if (s->is_host) { #if CFG_TUH_ENABLED - return usbh_edpt_release(s->daddr, s->ep_addr); + return usbh_edpt_release(hwid, s->ep_addr); #endif } else { #if CFG_TUD_ENABLED - return usbd_edpt_release(s->rhport, s->ep_addr); + return usbd_edpt_release(hwid, s->ep_addr); #endif } return false; @@ -284,83 +285,117 @@ bool stream_release(tu_edpt_stream_t* s) { //--------------------------------------------------------------------+ // Stream Write //--------------------------------------------------------------------+ -bool tu_edpt_stream_write_zlp_if_needed(tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { +bool tu_edpt_stream_write_zlp_if_needed(uint8_t hwid, tu_edpt_stream_t* s, uint32_t last_xferred_bytes) { // ZLP condition: no pending data, last transferred bytes is multiple of packet size - TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (s->ep_packetsize - 1)))); - TU_VERIFY(stream_claim(s)); - TU_ASSERT(stream_xfer(s, 0)); + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + TU_VERIFY(!tu_fifo_count(&s->ff) && last_xferred_bytes && (0 == (last_xferred_bytes & (mps - 1)))); + TU_VERIFY(stream_claim(hwid, s)); + TU_ASSERT(stream_xfer(hwid, s, 0)); return true; } -uint32_t tu_edpt_stream_write_xfer(tu_edpt_stream_t* s) { +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); - // Claim the endpoint - TU_VERIFY(stream_claim(s), 0); + TU_VERIFY(stream_claim(hwid, s), 0); // Pull data from FIFO -> EP buf uint16_t const count = tu_fifo_read_n(&s->ff, s->ep_buf, s->ep_bufsize); if (count) { - TU_ASSERT(stream_xfer(s, count), 0); + TU_ASSERT(stream_xfer(hwid, s, count), 0); return count; } else { // Release endpoint since we don't make any transfer // Note: data is dropped if terminal is not connected - stream_release(s); + stream_release(hwid, s); return 0; } } -uint32_t tu_edpt_stream_write(tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_write(uint8_t hwid, tu_edpt_stream_t* s, void const* buffer, uint32_t bufsize) { TU_VERIFY(bufsize); // TODO support ZLP - uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); - // flush if fifo has more than packet size or - // in rare case: fifo depth is configured too small (which never reach packet size) - if ((tu_fifo_count(&s->ff) >= s->ep_packetsize) || (tu_fifo_depth(&s->ff) < s->ep_packetsize)) { - tu_edpt_stream_write_xfer(s); + if (0 == tu_fifo_depth(&s->ff)) { + // no fifo for buffered + 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); + TU_ASSERT(stream_xfer(hwid, s, (uint16_t) xact_len), 0); + return xact_len; + } else { + const uint16_t ret = tu_fifo_write_n(&s->ff, buffer, (uint16_t) bufsize); + + // flush if fifo has more than packet size or + // in rare case: fifo depth is configured too small (which never reach packet size) + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + if ((tu_fifo_count(&s->ff) >= mps) || (tu_fifo_depth(&s->ff) < mps)) { + tu_edpt_stream_write_xfer(hwid, s); + } + return ret; } +} - return ret; +uint32_t tu_edpt_stream_write_available(uint8_t hwid, tu_edpt_stream_t* s) { + if (tu_fifo_depth(&s->ff)) { + return (uint32_t) tu_fifo_remaining(&s->ff); + } else { + bool is_busy = true; + if (s->is_host) { + #if CFG_TUH_ENABLED + is_busy = usbh_edpt_busy(hwid, s->ep_addr); + #endif + } else { + #if CFG_TUD_ENABLED + is_busy = usbd_edpt_busy(hwid, s->ep_addr); + #endif + } + return is_busy ? 0 : s->ep_bufsize; + } } //--------------------------------------------------------------------+ // Stream Read //--------------------------------------------------------------------+ -uint32_t tu_edpt_stream_read_xfer(tu_edpt_stream_t* s) { - uint16_t available = tu_fifo_remaining(&s->ff); - - // Prepare for incoming data but only allow what we can store in the ring buffer. - // TODO Actually we can still carry out the transfer, keeping count of received bytes - // and slowly move it to the FIFO when read(). - // This pre-check reduces endpoint claiming - TU_VERIFY(available >= s->ep_packetsize); - - // claim endpoint - TU_VERIFY(stream_claim(s), 0); - - // get available again since fifo can be changed before endpoint is claimed - available = tu_fifo_remaining(&s->ff); - - if (available >= s->ep_packetsize) { - // multiple of packet size limit by ep bufsize - uint16_t count = (uint16_t) (available & ~(s->ep_packetsize - 1)); - count = tu_min16(count, s->ep_bufsize); - - TU_ASSERT(stream_xfer(s, count), 0); - return count; +uint32_t tu_edpt_stream_read_xfer(uint8_t hwid, tu_edpt_stream_t* s) { + if (0 == tu_fifo_depth(&s->ff)) { + // no fifo for buffered + TU_VERIFY(stream_claim(hwid, s), 0); + TU_ASSERT(stream_xfer(hwid, s, s->ep_bufsize), 0); + return s->ep_bufsize; } else { - // Release endpoint since we don't make any transfer - stream_release(s); - return 0; + const uint16_t mps = s->is_mps512 ? TUSB_EPSIZE_BULK_HS : TUSB_EPSIZE_BULK_FS; + uint16_t available = tu_fifo_remaining(&s->ff); + + // Prepare for incoming data but only allow what we can store in the ring buffer. + // TODO Actually we can still carry out the transfer, keeping count of received bytes + // and slowly move it to the FIFO when read(). + // This pre-check reduces endpoint claiming + TU_VERIFY(available >= mps); + + TU_VERIFY(stream_claim(hwid, s), 0); + + // get available again since fifo can be changed before endpoint is claimed + available = tu_fifo_remaining(&s->ff); + + if (available >= mps) { + // multiple of packet size limit by ep bufsize + uint16_t count = (uint16_t) (available & ~(mps - 1)); + count = tu_min16(count, s->ep_bufsize); + TU_ASSERT(stream_xfer(hwid, s, count), 0); + return count; + } else { + // Release endpoint since we don't make any transfer + stream_release(hwid, s); + return 0; + } } } -uint32_t tu_edpt_stream_read(tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { +uint32_t tu_edpt_stream_read(uint8_t hwid, tu_edpt_stream_t* s, void* buffer, uint32_t bufsize) { uint32_t num_read = tu_fifo_read_n(&s->ff, buffer, (uint16_t) bufsize); - tu_edpt_stream_read_xfer(s); + tu_edpt_stream_read_xfer(hwid, s); return num_read; } diff --git a/test/hil/hil_test.py b/test/hil/hil_test.py index 52ec5ae1db..a569e76665 100644 --- a/test/hil/hil_test.py +++ b/test/hil/hil_test.py @@ -43,6 +43,8 @@ STATUS_FAILED = "\033[31mFailed\033[0m" STATUS_SKIPPED = "\033[33mSkipped\033[0m" +verbose = False + # get usb serial by id def get_serial_dev(id, vendor_str, product_str, ifnum): if vendor_str and product_str: @@ -111,7 +113,6 @@ def read_disk_file(uid, lun, fname): # Flashing firmware # ------------------------------------------------------------- def run_cmd(cmd): - #print(cmd) r = subprocess.run(cmd, shell=True, stdout=subprocess.PIPE, stderr=subprocess.STDOUT) if r.returncode != 0: title = f'COMMAND FAILED: {cmd}' @@ -123,6 +124,9 @@ def run_cmd(cmd): else: print(title) print(r.stdout.decode("utf-8")) + elif verbose: + print(cmd) + print(r.stdout.decode("utf-8")) return r @@ -260,14 +264,14 @@ def test_device_cdc_dual_ports(board): str1 = b"test_no1" ser1.write(str1) ser1.flush() - assert ser1.read(100) == str1.lower(), 'Port1 wrong data' - assert ser2.read(100) == str1.upper(), 'Port2 wrong data' + assert ser1.read(len(str1)) == str1.lower(), 'Port1 wrong data' + assert ser2.read(len(str1)) == str1.upper(), 'Port2 wrong data' str2 = b"test_no2" ser2.write(str2) ser2.flush() - assert ser1.read(100) == str2.lower(), 'Port1 wrong data' - assert ser2.read(100) == str2.upper(), 'Port2 wrong data' + assert ser1.read(len(str2)) == str2.lower(), 'Port1 wrong data' + assert ser2.read(len(str2)) == str2.upper(), 'Port2 wrong data' def test_device_cdc_msc(board): @@ -279,7 +283,7 @@ def test_device_cdc_msc(board): str = b"test_str" ser.write(str) ser.flush() - assert ser.read(100) == str, 'CDC wrong data' + assert ser.read(len(str)) == str, 'CDC wrong data' # Block test data = read_disk_file(uid,0,'README.TXT') @@ -447,13 +451,17 @@ def main(): """ Hardware test on specified boards """ + global verbose + parser = argparse.ArgumentParser() parser.add_argument('config_file', help='Configuration JSON file') parser.add_argument('-b', '--board', action='append', default=[], help='Boards to test, all if not specified') + parser.add_argument('-v', '--verbose', action='store_true', help='Verbose output') args = parser.parse_args() config_file = args.config_file boards = args.board + verbose = args.verbose # if config file is not found, try to find it in the same directory as this script if not os.path.exists(config_file): diff --git a/test/hil/rpi.json b/test/hil/rpi.json index 36376a8733..77919f3460 100644 --- a/test/hil/rpi.json +++ b/test/hil/rpi.json @@ -52,6 +52,16 @@ "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "52D2002470"}] } }, + { + "name": "raspberry_pi_pico2", + "uid": "560AE75E1C7152C9", + "flasher": "openocd", + "flasher_sn": "E6633861A3978538", + "flasher_args": "-f interface/cmsis-dap.cfg -f target/rp2350.cfg -c \"adapter speed 5000\"", + "tests": { + "dual_attached": [{"vid_pid": "1a86_55d4", "serial": "533D004242"}] + } + }, { "name": "stm32f072disco", "uid": "3A001A001357364230353532", diff --git a/tools/make_release.py b/tools/make_release.py index 126e072922..3e653c12dd 100644 --- a/tools/make_release.py +++ b/tools/make_release.py @@ -1,7 +1,7 @@ import re import gen_doc -version = '0.16.0' +version = '0.17.0' print('version {}'.format(version)) ver_id = version.split('.')