Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
210 changes: 210 additions & 0 deletions docs/faq.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,210 @@
**************************
Frequently Asked Questions
**************************

General Questions
=================

**Q: What microcontrollers does TinyUSB support?**

TinyUSB supports 30+ MCU families including STM32, RP2040, NXP (iMXRT, Kinetis, LPC), Microchip SAM, Nordic nRF5x, ESP32, and many others. See :doc:`reference/boards` for the complete list.

**Q: Can I use TinyUSB in commercial projects?**

Yes, TinyUSB is released under the MIT license, allowing commercial use with minimal restrictions.

**Q: Does TinyUSB require an RTOS?**

No, TinyUSB works in bare metal environments. It also supports FreeRTOS, RT-Thread, and Mynewt.

**Q: How much memory does TinyUSB use?**

Typical usage: 8-20KB flash, 1-4KB RAM depending on enabled classes and configuration. The stack uses static allocation only.

Build and Setup
================

**Q: Why do I get "arm-none-eabi-gcc: command not found"?**

Install the ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` on Ubuntu/Debian, or download from ARM's website for other platforms.

**Q: Build fails with "Board 'X' not found"**

Check available boards: ``ls hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` to list all supported boards.

**Q: What are the dependencies and how do I get them?**

Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., stm32f4, rp2040). This downloads MCU-specific drivers and libraries.

**Q: Can I use my own build system instead of Make/CMake?**

Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`getting_started` for details.

**Q: Error: "tusb_config.h: No such file or directory"**

This is a very common issue. You need to create ``tusb_config.h`` in your project and ensure it's in your include path. The file must define ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS`` at minimum. Copy from ``examples/device/*/tusb_config.h`` as a starting point.

**Q: RP2040 + pico-sdk ignores my tusb_config.h settings**

The pico-sdk build system can override ``tusb_config.h`` settings. The ``CFG_TUSB_OS`` setting is often ignored because pico-sdk sets it to ``OPT_OS_PICO`` internally. Use pico-sdk specific configuration methods or modify the CMake configuration.

**Q: "multiple definition of dcd_..." errors with STM32**

This happens when multiple USB drivers are included. Ensure you're only including the correct portable driver for your STM32 family. Check that ``CFG_TUSB_MCU`` is set correctly and you don't have conflicting source files.

Device Development
==================

**Q: My USB device isn't recognized by the host**

Common causes:
- Invalid USB descriptors - validate with ``LOG=2`` build
- ``tud_task()`` not called regularly in main loop
- Incorrect ``tusb_config.h`` settings
- USB cable doesn't support data (charging-only cable)

**Q: Windows shows "Device Descriptor Request Failed"**

This typically indicates:
- Malformed device descriptor
- USB timing issues (check crystal/clock configuration)
- Power supply problems during enumeration
- Conflicting devices on the same USB hub

**Q: How do I implement a custom USB class?**

Use the vendor class interface (``CFG_TUD_VENDOR``) or implement a custom class driver. See ``src/class/vendor/`` for examples.

**Q: Can I have multiple configurations or interfaces?**

Yes, TinyUSB supports multiple configurations and composite devices. Modify the descriptors in ``usb_descriptors.c`` accordingly.

**Q: How do I change Vendor ID/Product ID?**

Edit the device descriptor in ``usb_descriptors.c``. For production, obtain your own VID from USB-IF or use one from your silicon vendor.

**Q: Device works alone but fails when connected through USB hub**

This is a known issue where some devices interfere with each other when connected to the same hub. Try:
- Using different USB hubs
- Connecting devices to separate USB ports
- Checking for power supply issues with the hub

Host Development
================

**Q: Why doesn't my host application detect any devices?**

Check:
- Power supply - host mode requires more power than device mode
- USB connector type - use USB-A for host applications
- Board supports host mode on the selected port
- Enable logging with ``LOG=2`` to see enumeration details

**Q: Can I connect multiple devices simultaneously?**

Yes, through a USB hub. TinyUSB supports multi-level hubs and multiple device connections.

**Q: Does TinyUSB support USB 3.0?**

No, TinyUSB currently supports USB 2.0 and earlier. USB 3.0 devices typically work in USB 2.0 compatibility mode.

Configuration and Features
==========================

**Q: How do I enable/disable specific USB classes?**

Edit ``tusb_config.h`` and set the corresponding ``CFG_TUD_*`` or ``CFG_TUH_*`` macros to 1 (enable) or 0 (disable).

**Q: Can I use both device and host modes simultaneously?**

Yes, with dual-role/OTG capable hardware. See ``examples/dual/`` for implementation examples.

**Q: How do I optimize for code size?**

- Disable unused classes in ``tusb_config.h``
- Use ``CFG_TUSB_DEBUG = 0`` for release builds
- Compile with ``-Os`` optimization
- Consider using only required endpoints/interfaces

**Q: Does TinyUSB support low power/suspend modes?**

Yes, TinyUSB handles USB suspend/resume. Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for custom power management.

**Q: What CFG_TUSB_MCU should I use for x86/PC platforms?**

For PC/motherboard applications, there's no standard MCU option. You may need to use a generic option or modify TinyUSB for your specific use case. Consider using libusb or other PC-specific USB libraries instead.

**Q: RP2040 FreeRTOS configuration issues**

The RP2040 pico-sdk has specific requirements for FreeRTOS integration. The ``CFG_TUSB_OS`` setting may be overridden by the SDK. Use pico-sdk specific configuration methods and ensure proper task stack sizes for the USB task.

Debugging and Troubleshooting
=============================

**Q: How do I debug USB communication issues?**

1. Enable logging: build with ``LOG=2``
2. Use ``LOGGER=rtt`` or ``LOGGER=swo`` for high-speed logging
3. Use USB protocol analyzers for detailed traffic analysis
4. Check with different host systems (Windows/Linux/macOS)

**Q: My application crashes or hard faults**

Common causes:
- Stack overflow - increase stack size in linker script
- Incorrect interrupt configuration
- Buffer overruns in USB callbacks
- Build with ``DEBUG=1`` and use a debugger

**Q: Performance is poor or USB transfers are slow**

- Ensure ``tud_task()``/``tuh_task()`` called frequently (< 1ms intervals)
- Use DMA for USB transfers if supported by your MCU
- Optimize endpoint buffer sizes
- Consider using high-speed USB if available

**Q: Some USB devices don't work with my host application**

- Not all devices follow USB standards perfectly
- Some may need device-specific handling
- Composite devices may have partial support
- Check device descriptors and implement custom drivers if needed

**Q: ESP32-S3 USB host/device issues**

ESP32-S3 has specific USB implementation challenges:
- Ensure proper USB pin configuration
- Check power supply requirements for host mode
- Some features may be limited compared to other MCUs
- Use ESP32-S3 specific examples and documentation

STM32CubeIDE Integration
========================

**Q: How do I integrate TinyUSB with STM32CubeIDE?**

1. In STM32CubeMX, enable USB_OTG_FS/HS under Connectivity, set to "Device_Only" mode
2. Enable the USB global interrupt in NVIC Settings
3. Add ``tusb.h`` include and call ``tusb_init()`` in main.c
4. Call ``tud_task()`` in your main loop
5. In the generated ``stm32xxx_it.c``, modify the USB IRQ handler to call ``tud_int_handler(0)``
6. Create ``tusb_config.h`` and ``usb_descriptors.c`` files

**Q: STM32CubeIDE generated code conflicts with TinyUSB**

Don't use STM32's built-in USB middleware (USB Device Library) when using TinyUSB. Disable USB code generation in STM32CubeMX and let TinyUSB handle all USB functionality.

**Q: STM32 USB interrupt handler setup**

Replace the generated USB interrupt handler with a call to TinyUSB:

.. code-block:: c

void OTG_FS_IRQHandler(void) {
tud_int_handler(0);
}

**Q: Which STM32 families work best with TinyUSB?**

STM32F4, F7, and H7 families have the most mature TinyUSB support. STM32F0, F1, F3, L4 families are also supported but may have more limitations. Check the supported boards list for your specific variant.
171 changes: 171 additions & 0 deletions docs/getting_started.rst
Original file line number Diff line number Diff line change
@@ -0,0 +1,171 @@
***************
Getting Started
***************

This guide will get you up and running with TinyUSB quickly. We'll start with working examples, then show you how to integrate TinyUSB into your own projects.

Quick Start Examples
====================

The fastest way to understand TinyUSB is to see it working. These examples demonstrate core functionality and can be built immediately.

We'll assume you are using the stm32f407disco board. For other boards, see ``Board Support Packages`` below.

Simple Device Example
---------------------

The `cdc_msc <https://github.com/hathach/tinyusb/tree/master/examples/device/cdc_msc>`_ example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC).

**What it does:**
* Appears as a serial port that echoes back any text you send
* Appears as a small USB drive with a README.TXT file
* Blinks an LED to show activity

**Build and run:**

.. code-block:: bash

$ git clone https://github.com/hathach/tinyusb tinyusb
$ cd tinyusb
$ python tools/get_deps.py stm32f4 # download dependencies, note ESP and RP2 need their SDKs, too
$ cd examples/device/cdc_msc
$ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows
$ cmake --build build # add "--target cdc_msc-jlink" for flashing using J-Link, "--target help" to list targets

Connect the device to your computer and you'll see both a new serial port and a small USB drive appear.

Simple Host Example
-------------------

The `cdc_msc_hid <https://github.com/hathach/tinyusb/tree/master/examples/host/cdc_msc_hid>`_ example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces.

**What it does:**
* Detects and enumerates connected USB devices
* Communicates with CDC devices (like USB-to-serial adapters)
* Reads from MSC devices (like USB drives)
* Receives input from HID devices (like keyboards and mice)

**Build and run:**

.. code-block:: bash

$ # initial setup see previous example
$ cd examples/host/cdc_msc_hid
$ cmake -DBOARD=stm32f407disco -B build # add "-G Ninja ." on Windows
$ cmake --build build # add "--target cdc_msc_hid-jlink" for flashing using J-Link, "--target help" to list targets

Connect USB devices to see enumeration messages and device-specific interactions in the serial output.

Project Structure
-----------------

TinyUSB separates example applications from board-specific hardware configurations:

* **Example applications**: Located in `examples/device/ <https://github.com/hathach/tinyusb/tree/master/examples/device>`_, `examples/host/ <https://github.com/hathach/tinyusb/tree/master/examples/host>`_, and `examples/dual/ <https://github.com/hathach/tinyusb/tree/master/examples/dual>`_ directories
* **Board Support Packages (BSP)**: Located in ``hw/bsp/FAMILY/boards/BOARD_NAME/`` with hardware abstraction including pin mappings, clock settings, and linker scripts

For example, raspberry_pi_pico is located in `hw/bsp/rp2040/boards/raspberry_pi_pico <https://github.com/hathach/tinyusb/tree/master/hw/bsp/rp2040/boards/raspberry_pi_pico>`_ where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build with ``BOARD=raspberry_pi_pico``, the build system automatically finds the corresponding BSP using the FAMILY.

Add TinyUSB to Your Project
============================

Once you've seen TinyUSB working, here's how to integrate it into your own project:

Integration Steps
-----------------

1. **Get TinyUSB**: Copy this repository or add it as a git submodule to your project at ``your_project/tinyusb``

2. **Add source files**: Add all ``.c`` files from ``tinyusb/src/`` to your project

3. **Configure include paths**: Add ``your_project/tinyusb/src`` to your include path. Ensure your include path contains ``tusb_config.h``

4. **Configure TinyUSB**: Create ``tusb_config.h`` with required macros like ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. Copy from ``examples/device/*/tusb_config.h`` as a starting point

5. **Implement USB descriptors**: For device stack, implement all ``tud_descriptor_*_cb()`` callbacks

6. **Initialize TinyUSB**: Add ``tusb_init()`` to your initialization code

7. **Handle interrupts**: Call ``tusb_int_handler()`` from your USB IRQ handler

8. **Run USB tasks**: Call ``tud_task()`` (device) or ``tuh_task()`` (host) periodically in your main loop

9. **Implement class callbacks**: Implement callbacks for enabled USB classes

Simple Integration Example
--------------------------

.. code-block:: c

#include "tusb.h"

int main(void) {
board_init(); // Your board initialization

tusb_rhport_init_t dev_init = {
.role = TUSB_ROLE_DEVICE,
.speed = TUSB_SPEED_AUTO
};
// tud_descriptor_* callbacks omitted here
tusb_init(0, &dev_init);

while(1) {
tud_task(); // TinyUSB device task
your_application(); // Your application code
}
}

void USB_IRQHandler(void) {
tusb_int_handler(0, true);
}

.. note::
Unlike many libraries, TinyUSB callbacks don't need to be explicitly registered. The stack automatically calls functions with specific names (e.g., ``tud_cdc_rx_cb()``) when events occur. Simply implement the callbacks you need.

.. note::
TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`reference/glossary` for more details.

Development Tips
================

**Debug builds and logging:**

.. code-block:: bash

$ cmake -DBOARD=stm32f407disco -DDEBUG=1 ... # Debug build
$ cmake -DBOARD=stm32f407disco -DLOG=2 ... # Enable detailed logging

**IAR Embedded Workbench:**

For IAR users, project connection files are available. Import `tools/iar_template.ipcf <https://github.com/hathach/tinyusb/tree/master/tools/iar_template.ipcf>`_ or use native CMake support (IAR 9.50.1+). See `tools/iar_gen.py <https://github.com/hathach/tinyusb/tree/master/tools/iar_gen.py>`_ for automated project generation.

Common Issues and Solutions
===========================

**Build Errors**

* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi``
* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l``
* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board

**Runtime Issues**

* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings
* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors
* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation

**Linux Permissions**

Some examples require udev permissions to access USB devices:

.. code-block:: bash

$ cp `examples/device/99-tinyusb.rules <https://github.com/hathach/tinyusb/tree/master/examples/device/99-tinyusb.rules>`_ /etc/udev/rules.d/
$ sudo udevadm control --reload-rules && sudo udevadm trigger

Next Steps
==========

* Check :doc:`reference/boards` for board-specific information
* Explore more examples in `examples/device/ <https://github.com/hathach/tinyusb/tree/master/examples/device>`_ and `examples/host/ <https://github.com/hathach/tinyusb/tree/master/examples/host>`_ directories
* Read :doc:`reference/usb_concepts` to understand USB fundamentals
Loading