hub: add hub_port_get_status_local(), ignore resp in hub_port_get_status(pot != 0)
usbh properly deboucning with hub/rootport accordingly to usb specs, also add 10ms of reset recovery
replace dev0.enumerating by enumerating_daddr for better clean up on unplugging while enumerating
move controller_id & enumerating_daddr into _usbh_data struct
- if a previous enumeration failed _ctrl_xfer status could stuck, it needs to be cleared before next attempt.
- after _dev0.enumerating is reset in hcd_event_handler(), if an attach event arrived before _ctrl_xfer clean up in remove event, a racing condition will happen.
Signed-off-by: HiFiPhile <admin@hifiphile.com>
While there is a define for the port, the clock enable is hardcoded for
GPIOA, so setting a different port than GPIOA doesn't work. This fixes
it by adding a define for enabling the port clock.
It also adds a define for the pin mode, because not all boards have the
LED connected in a way that open drain works with it.
- Added missing inline literals (double backticks) to any reference of symbol
names and macros
- Added language specifier to "code-block" directives to enable syntax
highlighting when rendered.
"code_of_conduct.rst" and "contributors.rst" both contain RST include
directives, but their file types are symoblic links. This commit turns them
into proper files.
change tuh_midi_rx/tx_cb() to have xferred_bytes
rename tuh_midi_get_num_rx/tx_cables() to tuh_midi_get_rx/tx_cable_count()
use default empty callback instead of weak null to be compatible with keil compiler
Default is still high speed, but setting
SPEED=high|full work as expected.
`make BOARD=same70_xplained SPEED=full`
Tested with examples/device/cdc_msc
```preformatted
lsusb -v
...
TinyUSB Device:
Product ID: 0x4003
Vendor ID: 0xcafe
Version: 1.00
Serial Number: 0123456789ABCDEF
Speed: Up to 12 Mb/s <------ full speed here
Manufacturer: TinyUSB
Location ID: 0x03142130 / 12
Current Available (mA): 500
Current Required (mA): 100
Extra Operating Current (mA): 0
Media:
Mass Storage:
Capacity: 8 KB (8,192 bytes)
Removable Media: Yes
BSD Name: disk5
Logical Unit: 0
Partition Map Type: Unknown
S.M.A.R.T. status: Verified
USB Interface: 2
```
In case we received invalid datagram, we silently fail
a the buffer was not returned to empty list -> it was lost.
If this happened more than CFG_TUD_NCM_OUT_NTB_N times, we run out of
NTBs and all OUT transfers are NACKed.
Closes https://github.com/espressif/esp-usb/issues/107
* try to run arm-iar with circleci with new token
* limit iar ci parallel build to 4 for medium+ and 6 for large
* add hil-hfp to compile and test with IAR
fix duplicated device attach for some devices which cause "USBH Defer Attach until current enumeration complete"
include dev0 for tuh_edpt_abort_xfer()
* update build.py script to work with circleci
* build make with circle ci
* build vm for esp only
* nrf imxrt with large resource
* nrf imxrt with large resource
* remove 2 of nrf boards
- skip DIR and use CTR TX/RX to handle complete transfer
- clear CTR first, except for setup which we need to get data first
- separate handle_ctr_setup()
Combined the new MAX32 MUSB implementation with the existing (TI) implementation to provide generic code base for working the MUSB DCD peripheral.
- Added abstraction calls for FIFO setup, EP registers, Ctrl registers and interrupt setup.
- Combined TM4C and MSP432E into a single header file.
- Created musb_max32.h, and removed the MAX32 specific C implementation.
- Updated MAX32 build system to use dcd_musb.c.
- Added MAX32 conditions for cdc_dual_ports example descriptors missed during first testing.
compiler for the callback functions:
* tud_descriptor_bos_cb()
* tud_vendor_control_xfer_cb()
* tud_mount_cb()
* tud_umount_cb()
* tud_suspend_cb()
* tud_resume_cb()
Without the fix for the first two functions, the USB device won't enumerate properly, if
the device makes use of a BOS description. For example when using a Microsoft OS 2.0
platform capability descriptor to set a specific Device Interface GUID for WinUSB.
The fix for the other four functions were added, because it's probably just a matter of
time before someone runs into the same problem with those callback functions.
- rename tud_hid_report_fail_cb() to tud_hid_report_failed_cb() and change its signature
- use default implementation for hid callbacks to be compatible with keil compiler
- code format
- all dwc2 ip seems to support test mode in both fs/hs -> remove TUP_USBIP_DWC2_TEST_MODE
- remove dcd_check_test_mode_support(), all should be supported
- move enum tusb_feature_test_mode_t to tusb_types.h
- Added MSDK flash rules for CMake
- Removed partial IAR support. Uniform GCC support across MAX32 parts
- Updated build scripts for correctly signing the MAX32651
- Added README files for the BSPs to describe flashing and limitiations
Added support for the MAX32650/1/2 series parts
- MAX32650FTHR, MAX32650EvKit, MAX32651EvKit
- Added special flash rule for MAX32651 due to signing required
- Added depencies to flash-msdk rules for executable
Updated MAX32690 and MAX78002 linker and cmake scripts to work with CMake + Ninja build system. Verified all example projects build with the tools/build.py script for both board, and both make and cmake build systems.
Initial commit for the port of TUSB to MAX32xxx parts, staring with MAX32690
- Added dcd_max32.c (based on dcd_musb.c) for interfacing with the peripheral
- Added MAX32690 part family support
- Added max32690evkit board support
- Updated examples for unique EP number requirement
- Updated get_deps.py to fetch the MSDK
Known Issues / Additional Testing Required
- msc_dual_lun only shown 1 volume on Windows
- USBTMC does not have a valid Windowsdriver
- DFU does not have a valid Windows driver
- WebUSB is "Device not Recognized"
- Need to test build scripts with IAR and Clang
fix error
~/dsp/libs/tinyusb/src/class/audio/audio.h:643:53: error: ISO C restricts enumerator values to range of 'int' before C23 [-Werror=pedantic]
643 | AUDIO_CHANNEL_CONFIG_RAW_DATA = 0x80000000, // TODO
| ^~~~~~~~~~
compilation terminated due to -Wfatal-errors.
Closes: https://github.com/hathach/tinyusb/issues/2690
Fix the following error
~/libs/tinyusb/src/class/audio/audio_device.c:1493:23: error: assuming pointer wraparound does not occur when comparing P +- C1 with P +- C2 [-Werror=strict-overflow]
1493 | while (p_desc < p_desc_end)
| ~~~~~~~^~~~~~~~~~~~
compilation terminated due to -Wfatal-errors.
* Build arm-clang using circle ci (only on PR): cache most of mandatory deps, clang toolchain
* update get_deps.py to include CMSIS_5 with --print + no arguments, prevent duplicated deps
- enable --one-per-family to build 1 board per family, also skip family if board specified in -b also present
- minimize ci run for push event
- only build one board per family
- skip hil test on both pi4 and hfp
- full build will be runn for PR event
- IAR always build 1 board per family regardless of event
- update build.py to optimize make
- remove all setup python since we don't really need it
* Circi use small docker
* caching espressif docker image
* only run make job on pull request or push to master
* hw test run on pull request only, rename build_cmake to build.yml
* enable all ci build, cmake(clang) and make(*) only run with pull_request or push to master
* change concurrency group to ${{ github.workflow }}-${{ github.ref }}
* use argparse for build.py hil_test.py, remove the need to install click
* move ci win/mac to build_cmake.yml
* rename build_family.yml to build_util.yml
* build_util.yml support esp32
* integrate build-espressif into build.yml
* build.py support make with --board option
* add get_deps action
* update hil test to reuse action
* add name field to usbd_class_driver_t
* ci: use set matrix py script
* add riscv32 and cmake support for ch32v307, fomu, gd32vf103
* update build_cmake.py to take --family --board --toolchain
* separate hil test to its own workflow
* move esp32 board into separated hil json
* add make build to ci
* remov build_make.py
* build.py support esp32 board
* setup toolchain support esp-idf
* fix missing click
* merge family in matrix build to reduce jobs
* skip cifuzz since it still has issue with get_deps and click
The send break capability bit is needed for serial break support with Linux and possibly MacOS hosts. [A recent Linux kernel patch made it check the ACM capability bits before sending a serial break](19e321c3ee).
Implemented changes suggested in the review:
- restored original name of SystemClock_Config() function
- some GPIO clocks are only enabled if macros are defined
- moved GPIO clocks init back to family.c
- added support for STM32H503RB on H503RB-NUCLEO board
- modified H5 family.c file to allow portability between H503 and H565/H573
- redefined USB_DRD_BASE to USB_DRD_FS_BASE if STM32H503xx is used
- Define EP_ALLOCREQ
- Define EP_FREEREQ
- Define EP_ALLOCBUFFER
- Define EP_FREEBUFFER
Those were previously defined in spresense-exported-sdk, but now have been removed.
- usbh: abort all pending xfer when SET_CONFIGURATION is complete
- use tu_edpt_release in tuh_edpt_abort_xfer instead of usbh_edpt_release
- rename _xfer_complete -> _control_xfer_complete
RP2040 device controller does not seem to clear pending transactions
configured in EP0 buffer controls when the host aborts a control
transfer. This causes assertion failures, including when a buffer
AVAILABLE flag set for a previous transfer causes an unexpected
transaction completion.
The ep_int_in is already used for responding to USB488
READ_STATUS_BYTE requests, but that EP is defined for all of USBTMC.
This extends the functionality to let callers send notifications and
receive ACKs.
NRF5x USB controller can detect ISO OUT CRC errors.
In such case USBEVENT is signaled with EVENTCAUSE_ISOOUTCRC set.
Even if controller detects corrupted ISO OUT packet it allows
to data transfer from ednpoint to RAM however packet is corrupted
and code could just as well drop packet altogether.
With current implementation incoming ISO OUT packets were put in
FIFO and exact information how much data already in FIFO is correct
was hard to keep track of.
If was observed that on certain configurations HS hub when FS device
was connected occasionally sent invalid (short) packet. In such case
if packet length was reported odd audio stream was not recognizable any
more.
With this change corrupted packets are not passed to upper layers
and are silently dropped.
In some configurations local variable p_desc_parse_for_params
is declared and never used resulting in warning that can
be escalated to build error (for mynewt)
Now variable is surrounded with same preprocessor condition
as function that uses it audiod_parse_for_AS_params()
The _msc_scsi_cmd_lookup and _msc_scsi_cmd_table variables are needed
when logging is enabled for the MSC device via CFG_TUD_MSC_LOG_LEVEL.
Update the preprocessor check around them to use that definition when
deciding whether to define those variables.
Closes#2419
- fix warnings build hcd max3421 with rp2040
- add tinyusb_host_max3421 target for rp2040 cmake, -DMAX3421_HOST=1
will enable this
- add max3421 driver implementation for rp2040 family
- update tusb_config for host to allow easy enable host selection for
rp2040 (default/pio-usb/max3421)
When ISO endpoint handling was introduced two lines that
clear stall and data toggle bit were left unchanged and they
were effective for ISO enadpoint as well.
This is incorrect behavior since EPSTALL and DTOGGLE registers
have only 3 bits for address.
Leaving code that clears toggle bit results in endpoint 0 toggle bit
being reset when iso endpoint (8) is opened.
Now code that clears stall and toggle bit is applied to non-iso endpoint only
as it was done before iso handling was introduced.
These are intended to allow bare metal platforms with one-shot scheduling
capabilities to schedule the TinyUSB task handlers whenever they know there is
work for them to do.
Signed-off-by: Angus Gratton <angus@redyak.com.au>
This adds bsp for ST nucleo-g491re board.
This is mostly copy of nucleo-f474 only differences being:
- PLL configured to 170MHz (not affecting USB which runs on HSI48)
- Linker script freshly generated from STM32CubeIDE (smaller RAM)
Signed-off-by: Jerzy Kasenberg <jerzy.kasenberg@codecoup.pl>
Add CodeQL Workflow for Code Security Analysis
This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.
We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.
Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.
Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.
Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).
Signed-off-by: Brian <bayuan@purdue.edu>
Add CodeQL Workflow for Code Security Analysis
This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.
We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.
Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.
Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.
Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).
Signed-off-by: Brian <bayuan@purdue.edu>
Add CodeQL Workflow for Code Security Analysis
This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.
We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every pull request (functionality to run on every push to main branches is included as a comment for convenience).
- Runs daily.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for git submodules, focusing only on our own codebase.
Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.
Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.
Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation (https://codeql.github.com/ and https://codeql.github.com/docs/).
Signed-off-by: Brian <bayuan@purdue.edu>
Add CodeQL Workflow for Code Security Analysis
This pull request introduces a CodeQL workflow to enhance the security analysis of our repository. CodeQL is a powerful static analysis tool that helps identify and mitigate security vulnerabilities in our codebase. By integrating this workflow into our GitHub Actions, we can proactively identify and address potential issues before they become security threats.
We added a new CodeQL workflow file (.github/workflows/codeql.yml) that
- Runs on every push and pull request to the main branch.
- Excludes queries with a high false positive rate or low-severity findings.
- Does not display results for third-party code, focusing only on our own codebase.
Testing:
To validate the functionality of this workflow, we have run several test scans on the codebase and reviewed the results. The workflow successfully compiles the project, identifies issues, and provides actionable insights while reducing noise by excluding certain queries and third-party code.
Deployment:
Once this pull request is merged, the CodeQL workflow will be active and automatically run on every push and pull request to the main branch. To view the results of these code scans, please follow these steps:
1. Under the repository name, click on the Security tab.
2. In the left sidebar, click Code scanning alerts.
Additional Information:
- You can further customize the workflow to adapt to your specific needs by modifying the workflow file.
- For more information on CodeQL and how to interpret its results, refer to the GitHub documentation and the CodeQL documentation.
Signed-off-by: Brian <bayuan@purdue.edu>
This fixes a problem found on MSD class where data read from from disks were sometimes partially overwritten by the status MSD message ("USBS...").
The function introduced wait for the hw fifo pipe to be empty, that prevent that new writing in the fife overwrite data which are not yet be transmitted by hw.
The Keil compiler seems to have different semantics and the defined function was never called.
The same is probably true for the other weak functions. I can change those too.
- merge addr0 ep to pool
- add control status to xact in/out
- use atomic flag busy to ensure only 1 transfer is active at any time
- execute pending transfer after one is complete (or clear busy flag)
- change rtt mode to block if full
previosuly users of TinyUSB (e.g. pico-examples) would have to decide this for themselves. This function couples
the check closer with the actual version of Pico-PIO-USB used (since TinyUSB picks)
* include_guard requires GLOBAL as family.cmake is included in multiple non child places
* the following recently added check is suprfluous (family_configure_host_example for rp2040 should do this already),
and breaks if pico_pio_usb is not avaialble, so i have removed
# Add pico-pio-usb for rp2040 since user can choose to run on bit-banging host
if(FAMILY STREQUAL "rp2040")
family_add_pico_pio_usb(${PROJECT})
endif()
* added new familt_example_missing_dependency functino to print missing dependency warning, so
pico-examples can override it to be less in your face, and also more contextual to pico-examples
There were typos in symlinks target names resulting in following
warrning on checkout (at least in Mynewt newt tool):
* Warning: stat mynewt/repos/tinyusb/docs/contributing/code_of_conduct.rst: no such file or directory
* Warning: stat mynewt/repos/tinyusb/docs/info/contributors.rst: no such file or directory
Due to a missed optimization in the compiler, code for constant address
handling is being included in all builds. This change splits the code
in different functions to avoid that.
During enumeration, when there are multiple devices attached to the
hub as it's plugged into the Pi Pico, enumeration hangs, because we
get a "status change" callback with value zero. With this patch, we
retry several times on "zero" status change callbacks, until
eventually we succeed.
This is the cheapo hub that exhibits this behavior, but I assume it's
not the only one: https://www.amazon.com/gp/product/B083RQMC7S.
While debugging this, I consulted the implementation in the Linux
kernel. There, hub setup explicitly checks each port individually,
before starting to depend on "status change" interrupts:
https://elixir.bootlin.com/linux/latest/source/drivers/usb/core/hub.c#L1133.
We probably should do something like that here, but it's a much bigger
change.
* update chipidea dcd, remove manual ep_count and use DCCPARAMS to get number of endpoint instead
* add dcd dcache for chipidea
* add cmake for lpc18
* add makefile build for mcx
* use fork of mcu sdk
* fix ci build with nrf
* flash rp2040 with openocd
- change CFG_TUH_ENDPOINT_MAX to 16 (max endpoint pair per device) if
not defined
- change QHD_MAX for EHCI, should be user configurable and more
optimized in the future
This is needed in order to always be able to fit a packet in the fifo.
Writing to the fifo is done from an interrupts that fires when the fifo is
half-empty, so the fifo must be twice the packet size.
While calling tud_cdc_n_get_line_coding, the structure is copied into
the destination.
Dump of assembler code for function tud_cdc_n_get_line_coding:
0x000193f4 <+0>: mov.w r2, #2112 @ 0x840
0x000193f8 <+4>: ldr r3, [pc, #20] @ (0x19410
<tud_cdc_n_get_line_coding+28>)
0x000193fa <+6>: mla r0, r2, r0, r3
=> 0x000193fe <+10>: ldr.w r3, [r0, #6]
0x00019402 <+14>: str r3, [r1, #0]
On some platform (tested on LPC55S28), the address needs to be 4-bytes
aligned. Without this, the address is
(gdb) p &_cdcd_itf.line_coding
$3 = (cdc_line_coding_t *) 0x40100006 <_cdcd_itf+6>
which leads to a HardFault. With this fix
(gdb) p &_cdcd_itf.line_coding
$5 = (cdc_line_coding_t *) 0x40100008 <_cdcd_itf+8>
and the function can be called properly
Signed-off-by: Jean-Baptiste Theou <jb@thing.com>
add per family freeRTOSConfig.h also make changes to build with
freertos_kernel cmake
- hard coded configPRIO_BITS based on family
- change configSUPPORT_STATIC_ALLOCATION to 0,
configSUPPORT_DYNAMIC_ALLOCATION to 1
- enable configRECORD_STACK_HIGH_ADDRESS for tracing
- enable INCLUDE_xTaskGetCurrentTaskHandle which is required to compile
stream_buffer (although we don't use it).
This commit makes it so that when setting the START_TRANS bit in the
SIE_CTRL register, along with some other bits, we first set all the
other bits, then wait some cycles, and then set the START_TRANS bit.
Doing so protects against a situation where the USB controller is
reading the register at the same time and gets an incorrect value.
This mirrors the procedure already applied to buffer control
registers.
- previously CFG_TUH_HID is max number of interfaces per device which is
rather limited and consume more resources than needed.
- change hid host instance in API to index
For incoming ISO OUT packets it was possible to start
DMA from endpoint to RAM before transfer was started
resulting in unrelated memory corruption.
This is scenario that causes memory corruption:
- ISO OUT packet is received
- Packet is transferred by DMA to transfer buffer
- xfer->started is cleared and xfer->buffer is updated as
it is in every case
- Application takes to long to handle it (it happens when debugger
is connected breakpoint is hit slowing down software).
- Next ISO OUT packet arrives
At this point there was no check if transfer was started and packet
was copied by DMA to location beyond previous data, possibly overwriting
unrelated memory.
This solves the issue by checking that transfer was
started and there is buffer ready for incoming packet.
SOF is not a flag of the GOTGINT register but of the GINTSTS register. Therefore the flag must be written in the GINTSTS register instead of the GOTGINT register to clear the interrupt.
This fixes https://github.com/hathach/tinyusb/issues/1894. I'm not really
sure if this is the correct way to fix it, and I have not tested on all the
rest of the family members, however, this lets the i.MX1010 work again.
The problem: the latest SDK update does not enable the data cache by default
This causes an assert in board_init() when attemping to control clock
gating. I haven't investigated further as to *why* it's a problem, but it
is a problem.
Introduces a new function tu_memcpy_s, which is effectively
a backport of memcpy_s. The change also refactors calls
to memcpy over to the more secure tu_memcpy_s.
IAR generates warning Pa167 'the "fallthrough" attribute is not supported'.
It doesn't generate warnings when one switch case falls through to another,
so simply make TU_ATTR_FALLTHROUGH expand to an empty string.
Also replace one instance of __attribute__ with the macro.
This affects struct rspMsg in usbtmc_app.c (unconditionally) and uint8_t
termChar in usbtmc_device.c (when NDEBUG is defined). IAR generates warning
Pe550 'variable was set but never used'.
IAR generates warning Pe111 'statement is unreachable'. In a couple of
cases, replace return statements with TU_ATTR_FALLTHROUGH; because some
compilers apparently can't figure out that the return statements are
unreachable but do whinge about an imagined fall-through without them!
This is a GCC extension, illegal in ISO C. IAR generates errors Pa152
'these operand types cannot be used here' and Pe852 'expression must be a
pointer to a complete object type'.
Replace with uint8_t*.
Some compilers don't support the GNU extension `typeof` so their definitions
of `hw_set_alias` can't inherit their type from their argument, and the best
we can do is have `hw_set_alias` act the same as `hw_set_alias_untyped`.
This requires an explicit cast when the macro is used instead, otherwise
IAR generates error Pe132 'expression must have pointer-to-struct-or-union
type but it has type "void *"'.
The same goes for `hw_clear_alias`.
strings.h is not an ISO header file, so IAR generates fatal error Pe1696
'cannot open source file "strings.h"'. Even though strncasecmp isn't an
ISO C library function, IAR's runtime library defines it, though it
declares it in string.h instead.
this allows ports to specify a freertos port outside the FreeRTOS-Kernel lib directory, which would otherwise not be possible
Signed-off-by: Rafael Silva <rafaelsilva@ajtec.pt>
create local register access struct and move mcu specific code
in preparation of support for other mcu families that use the LINK usb core
Signed-off-by: Rafael Silva <rafaelsilva@ajtec.pt>
# Use only 'java-kotlin' to analyze code written in Java, Kotlin or both
# Use only 'javascript-typescript' to analyze code written in JavaScript, TypeScript or both
# Learn more about CodeQL language support at https://aka.ms/codeql-docs/language-support
steps:
- name:Checkout repository
uses:actions/checkout@v4
- name:Setup Toolchain
uses:./.github/actions/setup_toolchain
with:
toolchain:'arm-gcc'
# Initializes the CodeQL tools for scanning.
- name:Initialize CodeQL
uses:github/codeql-action/init@v2
with:
languages:${{ matrix.language }}
# If you wish to specify custom queries, you can do so here or in a config file.
# By default, queries listed here will override any specified in a config file.
# Prefix the list here with "+" to use these queries and those in the config file.
# For more details on CodeQL's query packs, refer to: https://docs.github.com/en/code-security/code-scanning/automatically-scanning-your-code-for-vulnerabilities-and-errors/configuring-code-scanning#using-queries-in-ql-packs
# queries: security-extended,security-and-quality
queries:security-and-quality
# Autobuild attempts to build any compiled languages (C/C++, C#, Go, Java, or Swift).
# If this step fails, then you should remove it and run the build manually (see below)
#- name: Autobuild
# uses: github/codeql-action/autobuild@v2
# ℹ️ Command-line programs to run using the OS shell.
# 📚 See https://docs.github.com/en/actions/using-workflows/workflow-syntax-for-github-actions#jobsjob_idstepsrun
# If the Autobuild fails above, remove it and uncomment the following three lines.
# modify them (or add more) to build your code if your project, please refer to the EXAMPLE below for guidance.
- run:|
./.github/workflows/codeql-buildscript.sh
- name:Perform CodeQL Analysis
uses:github/codeql-action/analyze@v2
with:
category:"/language:${{matrix.language}}"
upload:false
id:step1
# Filter out rules with low severity or high false positive rate
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.
Please take a look at the online `documentation <https://docs.tinyusb.org/>`__.
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 <https://docs.tinyusb.org/>`__ for more details.
..figure:: docs/assets/stack.svg
:width:500px
@ -18,45 +25,28 @@ Please take a look at the online `documentation <https://docs.tinyusb.org/>`__.
.
├── docs # Documentation
├── examples # Sample with Makefile build support
├── examples # Examples with make and cmake build system
Check out `Getting Started`_ guide for adding TinyUSB to your project or building the examples. If you are new to TinyUSB, we recommend starting with the ``cdc_msc`` example. There is a handful of `Supported Boards`_ that should work out of the box.
We use `GitHub Discussions <https://github.com/hathach/tinyusb/discussions>`_ as our forum. It is a great place to ask questions and advice from the community or to discuss your TinyUSB-based projects.
Here is the list of `Supported Devices`_ that can be used with provided examples.
For bugs and feature requests, please `raise an issue <https://github.com/hathach/tinyusb/issues>`_ and follow the templates there.
See `Porting`_ guide for adding support for new MCUs and boards.
Device Stack
============
@ -76,15 +66,26 @@ Supports multiple device configurations by dynamically changing USB descriptors,
- Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file.
- `WebUSB <https://github.com/WICG/webusb>`__ with vendor-specific class
If you have a special requirement, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`_
If you have a special requirement, ``usbd_app_driver_get_cb()`` can be used to write your own class driver without modifying the stack. Here is how the RPi team added their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`_
Host Stack
==========
- Human Interface Device (HID): Keyboard, Mouse, Generic
- Mass Storage Class (MSC)
- Communication Device Class: CDC-ACM
- 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.
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
====================
@ -95,39 +96,153 @@ 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 <https://github.com/hathach/mynewt-tinyusb-example>`_
@ -9,7 +9,7 @@ data transactions on different endpoints. Porting is the process of adding low-l
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.
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
-------------
@ -18,25 +18,27 @@ The first step to adding support is including the register definitions and start
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/<vendor>/<chip_family>`` directory.
Once this is done, create a directory in ``hw/bsp/<your board name>`` 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.
Once this is done, create a directory in ``hw/bsp/<your board name>`` 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:
``make -C examples/device/cdc_msc BOARD=<board>``
..code-block:: bash
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.
make -C examples/device/cdc_msc BOARD=<board>
One of the first things to change is the ``-DCFG_TUSB_MCU`` cflag 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 CFLAG to match.
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.
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/<vendor>/<chip_family>`` and delete all of the implementation internals. We'll cover what everything there does later. For now, get it compiling.
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/<vendor>/<chip_family>`` 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.
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)
^^^^^^^^^^^^^^^^^^^
@ -45,67 +47,67 @@ The board support code is only used for self-contained examples and testing. It
It is located in ``hw/bsp/<board name>/board_<board name>.c``.
board_init
~~~~~~~~~~
``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.
``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
~~~~~~~~~~~~~~~
``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 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``.
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.
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/<vendor>/<chip family>/dcd_<chip family>.c``.
Device Setup
~~~~~~~~~~~~
dcd_init
""""""""
``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
""""""""""""""""""""""""""""""""
``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
"""""""""""""""
``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
"""""""""""""""
``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
"""""""""""""""""
``dcd_remote_wakeup()``
"""""""""""""""""""""""
Called to remote wake up host when suspended (e.g hid keyboard)
dcd_connect / dcd_disconnect
""""""""""""""""""""""""""""
``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.)
@ -114,8 +116,8 @@ 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
""""""""""""""""""""
``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.
@ -125,51 +127,51 @@ There are a number of events that your peripheral may communicate about the stat
The first ``0`` is the USB peripheral number. Statically saying 0 is common for single USB device MCUs.
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
""""""""""""""""""
``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::
..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.
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.
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::
..code-block:: c
uint8_t epnum = tu_edpt_number(ep_addr);
uint8_t dir = tu_edpt_dir(ep_addr);
dcd_edpt_open
"""""""""""""
``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
""""""""""""""
``dcd_edpt_close()``
""""""""""""""""""""
Close an endpoint. his function is used for implementing alternate settings.
@ -177,10 +179,10 @@ After calling this, the device should not respond to any packets directed toward
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()``
"""""""""""""""""""
``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.
``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
@ -195,21 +197,21 @@ Others (like the nRF52) may need each USB packet queued individually. To make th
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.
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.
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).
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
"""""""""""""""""
``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:
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:
* the actual length of the transfer. (OUT transfers may be smaller than the buffer given in ``dcd_edpt_xfer``\ )
* 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
"""""""""""""""""""""""""""""""""""""
``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.
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.
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 <https://www.wireshark.org/>`_ or `a Beagle <https://www.totalphase.com/protocols/usb/>`_ 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.
* 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.
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 being deferred and then handled in the non-ISR task function.
- 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.
Device Stack
------------
- Add ``tud_deinit()`` and ``class driver deinit()`` to deinitialize TinyUSB device stack.
- Add the capability for video class to handle a bulk endpoint in the streaming interface.
Host Stack
----------
- USBH
- Add new APIs: ``tuh_interface_set()``, ``tuh_task_event_ready()``, ``tuh_edpt_abort_xfer()``, ``tuh_rhport_reset_bus()``, ``tuh_rhport_is_active()``
- Fix issue when device generate multiple attach/detach/attach when plugging in
- Prefer application callback over built-in driver on transfer complete event
- Correct ``hcd_edpt_clear_stall()`` API signature
- Separate bus reset delay and contact debouncing delay in enumeration
- Support ``usbh_app_driver_get_cb()`` for application drivers
- Fix usbh enumeration removal race condition
- Add optional hooks ``tuh_event_hook_cb()``
- CDC
- Breaking: change ``tuh_cdc_itf_get_info()`` to use tuh_itf_info_t instead of tuh_cdc_info_t
- Fix cdc host enumeration issue when device does not support line request
- Add support for vendor usb2uart serial: ftdi, cp210x, ch9102f
- Improve sync control API e.g ``tuh_cdc_set_control_line_state()``, ``tuh_cdc_set_line_coding()``
- HID
- Add new APIs ``tuh_hid_send_report()``, ``tuh_hid_itf_get_info()``, ``tuh_hid_receive_ready()``, ``tuh_hid_send_ready()``, ``tuh_hid_set_default_protocol()``
- Change meaning of CFG_TUH_HID to total number of HID interfaces supported. Previously ``CFG_TUH_HID`` is max number of interfaces per device which is rather limited and consume more resources than needed.
- HUB
- Fix handling of empty "status change" interrupt
- Fix issue with hub status_change is not aligned
- MSC
- Fix bug in ``tuh_msc_ready()``
- Fix host msc get maxlun not using aligned section memory
0.15.0
======
@ -30,7 +385,7 @@ Controller Driver (DCD & HCD)
- [rp2040]
- [dcd] Implement workaround for Errata 15. This enable SOF when bulk-in endpoint is in use and reduce its bandwidth to only 80%
- [hcd] Fix shared irq slots filling up when hcd_init() is called multiple times
- [hcd] Fix shared irq slots filling up when ``hcd_init()`` is called multiple times
- [hcd] Support host bulk endpoint using hw "interrupt" endpoint. Note speed limit is 64KB/s
- [samd][dcd] Add support for ISO endpoint
@ -55,12 +410,12 @@ Device Stack
- [HID]
- Add FIDO descriptor template
- change length in tud_hid_report_complete_cb() from uint8 to uint16
- change length in ``tud_hid_report_complete_cb()`` from ``uint8_t`` to ``uint16_t``
- [CDC]
- Fix autoflush for FIFO < MPS
- Fix tx fifo memory overflown when DTR is not set and tud_cdc_write() is called repeatedly with large enough data
- Fix tx fifo memory overflown when DTR is not set and ``tud_cdc_write()`` is called repeatedly with large enough data
- [USBTMC] Fix packet size with highspeed
@ -68,7 +423,7 @@ Host Stack
----------
- Retry a few times with transfers in enumeration since device can be unstable when starting up
- [MSC] Rework host masstorage API. Add new **host/msc_file_explorer** example
- [MSC] Rework host masstorage API. Add new ``host/msc_file_explorer`` example
- [CDC]
- Add support for host cdc
@ -78,22 +433,22 @@ Host Stack
======
- Improve compiler support for CCRX and IAR
- Add timeout to osal_queue_receive()
- Add tud_task_ext(timeout, in_isr) as generic version of tud_task(). Same as tuh_task_ext(), tuh_task()
- Enable more warnings -Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls -Wconversion
- Add timeout to ``osal_queue_receive()``
- Add ``tud_task_ext(timeout, in_isr)`` as generic version of ``tud_task()``. Same as ``tuh_task_ext()``, ``tuh_task()``
- Enable more warnings ``-Wnull-dereference -Wuninitialized -Wunused -Wredundant-decls -Wconversion``
- Add new examples
- host/bare_api to demonstrate generic (app-level) enumeration and endpoint transfer
- dual/host_hid_to_device_cdc to run both device and host stack concurrently, get HID report from host and print out to device CDC. This example only work with multiple-controller MCUs and rp2040 with the help of pio-usb as added controller.
- ``host/bare_api`` to demonstrate generic (app-level) enumeration and endpoint transfer
- ``dual/host_hid_to_device_cdc`` to run both device and host stack concurrently, get HID report from host and print out to device CDC. This example only work with multiple-controller MCUs and rp2040 with the help of pio-usb as added controller.
Controller Driver (DCD & HCD)
-----------------------------
- Enhance rhports management to better support dual roles
- CFG_TUD_ENABLED/CFG_TUH_ENABLED, CFG_TUD_MAX_SPEED/CFG_TUH_MAX_SPEED can be used to replace CFG_TUSB_RHPORT0_MODE/CFG_TUSB_RHPORT1_MODE
- tud_init(rphort), tuh_init(rhport) can be used to init stack on specified roothub port (controller) instead of tusb_init(void)
- Add dcd/hcd port specific defines TUP_ (stand for tinyusb port-specific)
- ``CFG_TUD_ENABLED``/``CFG_TUH_ENABLED``, ``CFG_TUD_MAX_SPEED``/``CFG_TUH_MAX_SPEED`` can be used to replace ``CFG_TUSB_RHPORT0_MODE``/``CFG_TUSB_RHPORT1_MODE``
- ``tud_init(rphort)``, ``tuh_init(rhport)`` can be used to init stack on specified roothub port (controller) instead of ``tusb_init(void)``
- Add dcd/hcd port specific defines ``TUP_`` (stand for tinyusb port-specific)
- [dwc2]
- Update to support stm32 h72x, h73x with only 1 otg controller
@ -114,10 +469,10 @@ Device Stack
- [Audio] Add support for feedback endpoint computation
- New API tud_audio_feedback_params_cb(), tud_audio_feedback_interval_isr().
- New API ``tud_audio_feedback_params_cb()``, ``tud_audio_feedback_interval_isr()``.
- Supported computation method are: frequency with fixed/float or power of 2. Feedback with fifo count is not yet supported.
- Fix nitfs (should be 3) in TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR
- Fix typo in audiod_rx_done_cb()
- Fix nitfs (should be 3) in ``TUD_AUDIO_HEADSET_STEREO_DESCRIPTOR``
- Fix typo in ``audiod_rx_done_cb()``
- [DFU] Fix coexistence with other interfaces BTH, RNDIS
- [MSC] Fix inquiry response additional length field
@ -126,23 +481,23 @@ Device Stack
Host Stack
----------
- Add new API tuh_configure(rhport, cfg_id, cfg_param) for dynamnic port specific behavior configuration
- Add new API ``tuh_configure(rhport, cfg_id, cfg_param)`` for dynamnic port specific behavior configuration
- [HID] Open OUT endpoint if available
- [Hub] hub clear port and device interrupts
- [USBH] Major improvement
- Rework usbh control transfer with complete callback. New API tuh_control_xfer() though still only carry 1 usbh (no queueing) at a time.
- Add generic endpoint transfer with tuh_edpt_open(), tuh_edpt_xfer(). Require `CFG_TUH_API_EDPT_XFER=1`
- Rework usbh control transfer with complete callback. New API ``tuh_control_xfer()`` though still only carry 1 usbh (no queueing) at a time.
- Add generic endpoint transfer with ``tuh_edpt_open()``, ``tuh_edpt_xfer()``. Require ``CFG_TUH_API_EDPT_XFER=1``
- Add ``CFG_TUH_MSC_MAXLUN`` (default to 4) to hold lun capacities
Others
------
- Add basic support for rt-thread OS
- Change zero bitfield length to more explicit padding
- Build example now fetch required submodules on the fly while running `make` without prio submodule init for mcu drivers
- Build example now fetch required submodules on the fly while running ``make`` without prior submodule init for mcu drivers
- Update pico-sdk to v1.1.0
**New Boards**
@ -525,7 +880,7 @@ Device Controller Driver
- Added new device support for Raspberry Pi RP2040
- Added new device support for NXP Kinetis KL25ZXX
- Use dcd_event_bus_reset() with link speed to replace bus_signal
- Use ``dcd_event_bus_reset()`` with link speed to replace bus_signal
- ESP32-S2:
- Add bus suspend and wakeup support
@ -547,8 +902,8 @@ USB Device
**USBD**
- Rework usbd control transfer to have additional stage parameter for setup, data, status
- Fix tusb_init() return true instead of TUSB_ERROR_NONE
- Added new API tud_connected() that return true after device got out of bus reset and received the very first setup packet
- Fix ``tusb_init()`` return true instead of ``TUSB_ERROR_NONE``
- Added new API ``tud_connected()`` that return true after device got out of bus reset and received the very first setup packet
**Class Driver**
@ -556,22 +911,22 @@ USB Device
- 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
- 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.
- 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**
- Support make from windows cmd.exe
- Add HID Consumer Control (media keys) to hid_composite & hid_composite_freertos examples
- Support make from windows ``cmd.exe``
- Add HID Consumer Control (media keys) to ``hid_composite`` & ``hid_composite_freertos`` examples
USB Host
@ -612,28 +967,28 @@ Device Controller Driver
- 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)
- Add ISO transfer, fix odd/even frame
- Fix FIFO flush during stall
- Implement dcd_edpt_close() API
- Implement ``dcd_edpt_close()`` API
- Support F105, F107
- Enhance STM32 fsdev
- Improve dcd fifo allocation
- Fix ISTR race condition
- Support remap USB IRQ on supported MCUs
- Implement dcd_edpt_close() API
- Implement ``dcd_edpt_close()`` API
- 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`
- Add SAMD11 option ``OPT_MCU_SAMD11``
- Add SAME5x option ``OPT_MCU_SAME5X``
- Fix SAMG control data toggle and stall race condition
- Enhance nRF
- Fix hanged when tud_task() is called within critical section (disabled interrupt)
- 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()
- Implement ISO transfer and ``dcd_edpt_close()``
USB Device
@ -642,26 +997,26 @@ USB Device
**USBD**
- Add new class driver for **Bluetooth HCI** class driver with example can be found in [mynewt-tinyusb-example](https://github.com/hathach/mynewt-tinyusb-example) since it needs mynewt OS to run with.
- Fix USBD endpoint usage racing condition with `usbd_edpt_claim()/usbd_edpt_release()`
- Added `tud_task_event_ready()` and `osal_queue_empty()`. This API is needed to check before enter low power mode with WFI/WFE
- Rename USB IRQ Handler to `dcd_int_handler()`. Application must define IRQ handler in which it calls this API.
- Add `dcd_connect()` and `dcd_disconnect()` to enable/disable internal pullup on D+/D- on supported MCUs.
- Add `usbd_edpt_open()`
- Remove `dcd_set_config()`
- Add *OPT_OS_CUMSTOM* as hook for application to overwrite and/or add their own OS implementation
- Fix USBD endpoint usage racing condition with ``usbd_edpt_claim()``/``usbd_edpt_release()``
- Added ``tud_task_event_ready()`` and ``osal_queue_empty()``. This API is needed to check before enter low power mode with WFI/WFE
- Rename USB IRQ Handler to ``dcd_int_handler()``. Application must define IRQ handler in which it calls this API.
- Add ``dcd_connect()`` and ``dcd_disconnect()`` to enable/disable internal pullup on D+/D- on supported MCUs.
- Add ``usbd_edpt_open()``
- Remove ``dcd_set_config()``
- Add ``OPT_OS_CUMSTOM`` as hook for application to overwrite and/or add their own OS implementation
- Support SET_INTERFACE, GET_INTERFACE request
- Add Logging for debug with optional uart/rtt/swo printf retarget or `CFG_TUSB_DEBUG_PRINTF` hook
- Add Logging for debug with optional uart/rtt/swo printf retarget or ``CFG_TUSB_DEBUG_PRINTF`` hook
- Add IAR compiler support
- Support multiple configuration descriptors. `TUD_CONFIG_DESCRIPTOR()` template has extra config_num as 1st argument
- Improve USB Highspeed support with actual link speed detection with `dcd_event_bus_reset()`
- Support multiple configuration descriptors. ``TUD_CONFIG_DESCRIPTOR()`` template has extra config_num as 1st argument
- 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()`
- ``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()``
espressif_p4_function_ev Espresif P4 Function EV espressif https://docs.espressif.com/projects/esp-dev-kits/en/latest/esp32p4/esp32-p4-function-ev-board/index.html
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
da1469x_dk_pro DA1469x Development Kit Pro da1469x https://lpccs-docs.renesas.com/um-b-090-da1469x_getting_started/DA1469x_The_hardware/DA1469x_The_hardware.html
portenta_c33 Arduino Portenta C33 ra https://www.arduino.cc/pro/hardware-product-portenta-c33/
ra2a1_ek RA2A1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra2a1-evaluation-kit-ra2a1-mcu-group
ra4m1_ek RA4M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m1-evaluation-kit-ra4m1-mcu-group
ra4m3_ek RA4M3 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra4m3-evaluation-kit-ra4m3-mcu-group
ra6m1_ek RA6M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m1-evaluation-kit-ra6m1-mcu-group
ra6m5_ek RA6M5 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra6m5-evaluation-kit-ra6m5-mcu-group
ra8m1_ek RA8M1 EK ra https://www.renesas.com/en/products/microcontrollers-microprocessors/ra-cortex-m-mcus/ek-ra8m1-evaluation-kit-ra8m1-mcu-group
uno_r4 Arduino UNO R4 ra https://store-usa.arduino.cc/pages/uno-r4
It is relatively simple to incorporate tinyusb to your (existing) project
It is relatively simple 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 IDE/compiler to maintain a unique configure for all boards).
* 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 IDE/compiler 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() call to your reset initialization code.
* Call ``tud_int_handler()`` (device) and/or ``tuh_int_handler()`` (host) in your USB IRQ Handler
* 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.
* 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::
..code-block:: c
int main(void)
{
your_init_code();
tusb_init(); // initialize tinyusb stack
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
while(1) // the mainloop
{
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 `the supported boards <supported.rst>`_. 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 `the supported boards <boards.rst>`_. Firstly we need to ``git clone`` if not already
Some TinyUSB examples also requires external submodule libraries in ``/lib`` such as FreeRTOS, Lightweight IP to build. Run following command to fetch them
..code-block::
$ git submodule update --init lib
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=raspberry_pi_pico get-deps
You only need to do this once per family. Check out `complete list of dependencies and their designated path here <dependencies.rst>`_
Build
^^^^^
To build example, first change directory to an example folder.
..code-block::
..code-block:: bash
$ cd examples/device/cdc_msc
Before building, we need to download MCU driver submodule to provide low-level MCU peripheral's driver first. Run the ``get-deps`` target in one of the example folder as follow. You only need to do this once per mcu
Then compile with ``make BOARD={board_name} all`` , for example
..code-block::
..code-block:: bash
$ make BOARD=feather_nrf52840_express get-deps
$ make BOARD=raspberry_pi_pico all
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
Some modules (e.g. RP2040 and ESP32s2) require the project makefiles to be customized using CMake. If necessary apply any setup steps for the platform's SDK.
..code-block:: bash
Then compile with ``make BOARD=[board_name] all``\ , for example
$ sudo udevadm control --reload-rules && sudo udevadm trigger
..code-block::
$ make BOARD=feather_nrf52840_express all
Note: ``BOARD`` can be found as directory name in ``hw/bsp``\ , either in its family/boards or directly under bsp (no family).
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 ``/examples/device/99-tinyusb.rules`` file to /etc/udev/rules.d/ then run ``sudo udevadm control --reload-rules && sudo udevadm trigger`` is good enough.
Port Selection
~~~~~~~~~~~~~~
RootHub Port Selection
~~~~~~~~~~~~~~~~~~~~~~
If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``PORT=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use:
..code-block::
..code-block:: bash
$ make BOARD=stm32f746disco PORT=1 all
@ -93,16 +115,16 @@ 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 ``SPEED=full/high`` e.g To force F723 operate at full instead of default high speed
..code-block::
..code-block:: bash
$ make BOARD=stm32f746disco SPEED=full all
Size Analysis
~~~~~~~~~~~~~
First install `linkermap tool <https://github.com/hathach/linkermap>`_ 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.
First install `linkermap tool <https://github.com/hathach/linkermap>`_ 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::
..code-block:: bash
$ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap
@ -111,16 +133,16 @@ Debug
To compile for debugging add ``DEBUG=1``\ , for example
..code-block::
..code-block:: bash
$ make BOARD=feather_nrf52840_express DEBUG=1 all
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.
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::
..code-block:: bash
$ make BOARD=feather_nrf52840_express LOG=2 all
@ -142,7 +164,7 @@ By default log message is printed via on-board UART which is slow and take lots
* Pros: should be compatible with more debugger that support SWO.
* Software viewer should be provided along with your debugger driver.
..code-block::
..code-block:: bash
$ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all
$ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all
@ -152,55 +174,70 @@ 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::
..code-block:: bash
$ make BOARD=feather_nrf52840_express flash
$ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash
Since jlink can be used with most of the boards, there is also ``flash-jlink`` target for your convenience.
..code-block::
..code-block:: bash
$ make BOARD=feather_nrf52840_express flash-jlink
Some board use uf2 bootloader for drag & drop in to mass storage device, uf2 can be generated with ``uf2`` target
..code-block::
..code-block:: bash
$ make BOARD=feather_nrf52840_express all uf2
IAR Support
^^^^^^^^^^^
-----------
Use project connection
^^^^^^^^^^^^^^^^^^^^^^
IAR Project Connection files are provided to import TinyUSB stack into your project.
* A buldable project of your MCU need to be created in advance.
* 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`.
- 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.
- ``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`
* 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,
1. (Python3 is needed) Run `iar_gen.py` to generate .ipcf files of examples:
1. (Python3 is needed) Run ``iar_gen.py`` to generate .ipcf files of examples:
..code-block::
cd C:\tinyusb\tools
python iar_gen.py
> 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`
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 (9.50.1+)
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
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.
Supports multiple device configurations by dynamically changing usb descriptors. Low power functions such like suspend, resume, and remote wakeup. Following device classes are supported:
- Audio Class 2.0 (UAC2)
- Bluetooth Host Controller Interface (BTH HCI)
- Communication Class (CDC)
- Device Firmware Update (DFU): DFU mode (WIP) and Runtinme
- Human Interface Device (HID): Generic (In & Out), Keyboard, Mouse, Gamepad etc ...
- Mass Storage Class (MSC): with multiple LUNs
- Musical Instrument Digital Interface (MIDI)
- Network with RNDIS, CDC-ECM (work in progress)
- USB Test and Measurement Class (USBTMC)
- Vendor-specific class support with generic In & Out endpoints. Can be used with MS OS 2.0 compatible descriptor to load winUSB driver without INF file.
- `WebUSB <https://github.com/WICG/webusb>`__ with vendor-specific class
If you have special need, `usbd_app_driver_get_cb()` can be used to write your own class driver without modifying the stack. Here is how RPi team add their reset interface `raspberrypi/pico-sdk#197 <https://github.com/raspberrypi/pico-sdk/pull/197>`__
Host Stack
==========
- Human Interface Device (HID): Keyboard, Mouse, Generic
- Mass Storage Class (MSC)
- Hub currently only supports 1 level of hub (due to my laziness)
OS Abstraction layer
====================
TinyUSB is completely thread-safe by pushing all ISR events into a central queue, then process it later in the non-ISR context task function. It also uses semaphore/mutex to access shared resources such as CDC FIFO. Therefore the stack needs to use some of OS's basic APIs. Following OSes are already supported out of the box.
- **No OS**
- **FreeRTOS**
- **Mynewt** Due to the newt package build system, Mynewt examples are better to be on its `own repo <https://github.com/hathach/mynewt-tinyusb-example>`__
License
=======
All TinyUSB sources in the `src` folder are licensed under MIT license. However, each file can be individually licensed especially those in `lib` and `hw/mcu` folder. Please make sure you understand all the license term for files you use in your project.
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. It is responsible for getting the MCU started and the USB peripheral clocked with minimal of on-board devices
- One LED : for status
- One Button : to get input from user
- One UART : optional for device, but required for host examples
The following boards are supported (sorted alphabetically):
Broadcom
--------
- `Raspberry Pi CM4 <https://www.raspberrypi.com/products/compute-module-4>`__
Dialog DA146xx
--------------
- `DA14695 Development Kit – USB <https://www.dialog-semiconductor.com/products/da14695-development-kit-usb>`__
- `DA1469x Development Kit – Pro <https://www.dialog-semiconductor.com/products/da14695-development-kit-pro>`__
- `LPCXpresso18S37 Development Board <https://www.nxp.com/products/processors-and-microcontrollers/arm-microcontrollers/general-purpose-mcus/lpc4000-cortex-m4/lpcxpresso18s37-development-board:OM13076>`__
Blocking a user prevents them from interacting with repositories, such as opening or commenting on pull requests or issues. Learn more about blocking a user.