From 82aa46d8ea9370944440cc40b87738ebeabb9593 Mon Sep 17 00:00:00 2001 From: c1570 Date: Sat, 27 Sep 2025 00:30:24 +0200 Subject: more consolidation --- docs/explanation/architecture.rst | 296 ------------------------- docs/explanation/index.rst | 11 - docs/explanation/usb_concepts.rst | 425 ------------------------------------ docs/faq.rst | 2 +- docs/getting_started.rst | 357 +++++++++++++++++++++++++++++++ docs/index.rst | 12 +- docs/reference/architecture.rst | 291 +++++++++++++++++++++++++ docs/reference/configuration.rst | 307 -------------------------- docs/reference/index.rst | 5 +- docs/reference/usb_classes.rst | 287 ------------------------- docs/reference/usb_concepts.rst | 428 +++++++++++++++++++++++++++++++++++++ docs/tutorials/getting_started.rst | 356 ------------------------------ docs/tutorials/index.rst | 10 - 13 files changed, 1083 insertions(+), 1704 deletions(-) delete mode 100644 docs/explanation/architecture.rst delete mode 100644 docs/explanation/index.rst delete mode 100644 docs/explanation/usb_concepts.rst create mode 100644 docs/getting_started.rst create mode 100644 docs/reference/architecture.rst delete mode 100644 docs/reference/configuration.rst delete mode 100644 docs/reference/usb_classes.rst create mode 100644 docs/reference/usb_concepts.rst delete mode 100644 docs/tutorials/getting_started.rst delete mode 100644 docs/tutorials/index.rst (limited to 'docs') diff --git a/docs/explanation/architecture.rst b/docs/explanation/architecture.rst deleted file mode 100644 index aa0c76128..000000000 --- a/docs/explanation/architecture.rst +++ /dev/null @@ -1,296 +0,0 @@ -************ -Architecture -************ - -This document explains TinyUSB's internal architecture, design principles, and how different components work together. - -Design Principles -================= - -Memory Safety -------------- - -TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: - -TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. - -Thread Safety -------------- - -TinyUSB achieves thread safety through a deferred interrupt model: - -- **ISR deferral**: USB interrupts are captured and deferred to task context -- **Single-threaded processing**: All USB protocol handling occurs in task context -- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` -- **RTOS integration**: Proper semaphore/mutex usage for shared resources - -Portability ------------ - -The stack is designed to work across diverse microcontroller families: - -- **Hardware abstraction**: MCU-specific code isolated in portable drivers -- **OS abstraction**: RTOS dependencies isolated in OSAL layer -- **Modular design**: Features can be enabled/disabled at compile time -- **Standard compliance**: Strict adherence to USB specifications - -Core Architecture -================= - -Layer Structure ---------------- - -TinyUSB follows a layered architecture from hardware to application: - -.. code-block:: none - - ┌─────────────────────────────────────────┐ - │ Application Layer │ ← Your code - ├─────────────────────────────────────────┤ - │ USB Class Drivers │ ← CDC, HID, MSC, etc. - ├─────────────────────────────────────────┤ - │ Device/Host Stack Core │ ← USB protocol handling - ├─────────────────────────────────────────┤ - │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers - ├─────────────────────────────────────────┤ - │ OS Abstraction (OSAL) │ ← RTOS integration - ├─────────────────────────────────────────┤ - │ Common Utilities & FIFO │ ← Shared components - └─────────────────────────────────────────┘ - -Component Overview ------------------- - -**Application Layer**: Your main application code that uses TinyUSB APIs. - -**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. - -**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. - -**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. - -**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. - -**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. - -Device Stack Architecture -========================= - -This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). - -Core Components ---------------- - -**Device Controller Driver (DCD)**: -- MCU-specific USB device peripheral driver -- Handles endpoint configuration and data transfers -- Abstracts hardware differences between MCU families -- Located in ``src/portable/VENDOR/FAMILY/`` - -**USB Device Core (USBD)**: -- Implements USB device state machine -- Handles standard USB requests (Chapter 9) -- Manages device configuration and enumeration -- Located in ``src/device/`` - -**Class Drivers**: -- Implement USB class specifications -- Handle class-specific requests and data transfer -- Provide application APIs -- Located in ``src/class/*/`` - -Data Flow ---------- - -**Control Transfers (Setup Requests)**: - -.. code-block:: none - - USB Bus → DCD → USBD Core → Class Driver → Application - ↓ - Standard requests handled in core - ↓ - Class-specific requests → Class Driver - -**Data Transfers**: - -.. code-block:: none - - Application → Class Driver → USBD Core → DCD → USB Bus - USB Bus → DCD → USBD Core → Class Driver → Application - -Event Processing ----------------- - -TinyUSB uses a deferred interrupt model for thread safety: - -1. **Interrupt Occurs**: USB hardware generates interrupt -2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing -3. **Event Queuing**: Events queued for later processing -4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events -5. **Callback Execution**: Application callbacks executed in task context - -.. code-block:: none - - USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application - -Host Stack Architecture -======================= - -This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. - -Core Components ---------------- - -**Host Controller Driver (HCD)**: -- MCU-specific USB host peripheral driver -- Manages USB pipes and data transfers -- Handles host controller hardware -- Located in ``src/portable/VENDOR/FAMILY/`` - -**USB Host Core (USBH)**: -- Implements USB host functionality -- Manages device enumeration and configuration -- Handles pipe management and scheduling -- Located in ``src/host/`` - -**Hub Driver**: -- Manages USB hub devices -- Handles port management and device detection -- Supports multi-level hub topologies -- Located in ``src/host/`` - -Device Enumeration ------------------- - -The host stack follows USB enumeration process: - -1. **Device Detection**: Hub or root hub detects device connection -2. **Reset and Address**: Reset device, assign unique address -3. **Descriptor Retrieval**: Get device, configuration, and class descriptors -4. **Driver Matching**: Find appropriate class driver for device -5. **Configuration**: Configure device and start communication -6. **Class Operation**: Normal class-specific communication - -.. code-block:: none - - Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate - -Class Architecture -================== - -Common Class Structure ----------------------- - -All USB classes follow a similar architecture: - -**Device Classes**: -- ``*_device.c``: Device-side implementation -- ``*_device.h``: Device API definitions -- Implement class-specific descriptors -- Handle class requests and data transfer - -**Host Classes**: -- ``*_host.c``: Host-side implementation -- ``*_host.h``: Host API definitions -- Manage connected devices of this class -- Provide application interface - -Class Driver Interface ----------------------- - -**Required Functions**: -- ``init()``: Initialize class driver -- ``reset()``: Reset class state -- ``open()``: Configure class endpoints -- ``control_xfer_cb()``: Handle control requests -- ``xfer_cb()``: Handle data transfer completion - -**Optional Functions**: -- ``close()``: Clean up class resources -- ``sof_cb()``: Start-of-frame processing - -Descriptor Management ---------------------- - -Each class is responsible for: -- **Interface Descriptors**: Define class type and endpoints -- **Class-Specific Descriptors**: Additional class requirements -- **Endpoint Descriptors**: Define data transfer characteristics - -Memory Management -================= - -Static Allocation Model ------------------------ - -TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. - -Buffer Management ------------------ - -**Endpoint Buffers**: -- Allocated per endpoint at compile time -- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros -- Used for USB data transfers - -**FIFO Buffers**: -- Ring buffers for streaming data -- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros -- Separate read/write pointers - -**DMA Considerations**: -- Buffers must be DMA-accessible on some MCUs -- Alignment requirements vary by hardware -- Cache coherency handled in portable drivers - -Threading Model -=============== - -Task-Based Design ------------------ - -TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. - -RTOS Integration ----------------- - -**Bare Metal**: -- Application calls ``tud_task()`` in main loop -- No threading primitives needed -- Simplest integration method - -**FreeRTOS**: -- USB task runs at high priority -- Semaphores used for synchronization -- Queue for inter-task communication - -**Other RTOS**: -- Similar patterns with RTOS-specific primitives -- OSAL layer abstracts RTOS differences - -Interrupt Handling ------------------- - -**Interrupt Service Routine**: -- Minimal processing in ISR -- Event capture and queuing only -- Quick return to avoid blocking - -**Deferred Processing**: -- All complex processing in task context -- Thread-safe access to data structures -- Application callbacks in known context - -Memory Usage Patterns ---------------------- - -**Flash Memory**: -- Core stack: 8-15KB depending on features -- Each class: 1-4KB additional -- Portable driver: 2-8KB depending on MCU - -**RAM Usage**: -- Core stack: 1-2KB -- Endpoint buffers: User configurable -- Class buffers: Depends on configuration diff --git a/docs/explanation/index.rst b/docs/explanation/index.rst deleted file mode 100644 index 695efd9e0..000000000 --- a/docs/explanation/index.rst +++ /dev/null @@ -1,11 +0,0 @@ -*********** -Explanation -*********** - -Deep understanding of TinyUSB's design, architecture, and concepts. - -.. toctree:: - :maxdepth: 2 - - architecture - usb_concepts \ No newline at end of file diff --git a/docs/explanation/usb_concepts.rst b/docs/explanation/usb_concepts.rst deleted file mode 100644 index e3d400921..000000000 --- a/docs/explanation/usb_concepts.rst +++ /dev/null @@ -1,425 +0,0 @@ -************ -USB Concepts -************ - -This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. - -TinyUSB API Naming Conventions -=============================== - -TinyUSB uses consistent function prefixes to organize its API: - -* **tusb_**: Core stack functions (initialization, interrupt handling) -* **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) -* **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) -* **tu_**: Internal utility functions (generally not used by applications) - -This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. - -USB Protocol Basics -==================== - -Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. - -Host and Device Roles ----------------------- - -**USB Host**: The controlling side of a USB connection (typically a computer). The host: -- Initiates all communication -- Provides power to devices -- Manages the USB bus -- Enumerates and configures devices - -**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. - -**USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: -- Respond to host requests -- Cannot initiate communication -- Receive power from the host -- Must be enumerated by the host before use - -**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../tutorials/getting_started` Quick Start Examples for implementation details. - -**OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. - -USB Transfers -============= - -Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. -Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. - -USB defines four transfer types, each intended for different use cases: - -Control Transfers ------------------ - -Used for device configuration and control commands. - -**Characteristics**: -- Bidirectional (uses both IN and OUT) -- Guaranteed delivery with error detection -- Limited data size (8-64 bytes per packet) -- All devices must support control transfers on endpoint 0 - -**Usage**: Device enumeration, configuration changes, class-specific commands - -**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). - -Bulk Transfers --------------- - -Used for large amounts of data that don't require guaranteed timing. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- Guaranteed delivery with error detection -- Large packet sizes (up to 512 bytes for High Speed) -- Uses available bandwidth when no other transfers are active - -**Usage**: File transfers, large data communication, CDC serial data - -**TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. - -Interrupt Transfers -------------------- - -Used for small, time-sensitive data with guaranteed maximum latency. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- Guaranteed delivery with error detection -- Small packet sizes (up to 64 bytes for Full Speed) -- Regular polling interval (1ms to 255ms) - -**Usage**: Keyboard/mouse input, sensor data, status updates - -**TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. - -Isochronous Transfers ---------------------- - -Used for time-critical streaming data. - -**Characteristics**: -- Unidirectional (separate IN and OUT endpoints) -- No error correction (speed over reliability) -- Guaranteed bandwidth -- Real-time delivery - -**Usage**: Audio, video streaming - -**TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. - -Endpoints and Addressing -========================= - -Endpoint Basics ---------------- - -**Endpoint**: A communication channel between host and device. - -- Each endpoint has a number (0-15) and direction -- Endpoint 0 is reserved for control transfers -- Other endpoints are assigned by device class requirements - -**TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. - -**Direction**: -- **OUT**: Host to device (host sends data out) -- **IN**: Device to host (host reads data in) -- Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). - -**Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) - -Endpoint Configuration ----------------------- - -Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. - -**TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. - -Error Handling and Flow Control -------------------------------- - -**Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. - -**Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. - -**TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. - -USB Device States -================= - -A USB device progresses through several states: - -1. **Attached**: Device is physically connected -2. **Powered**: Device receives power from host -3. **Default**: Device responds to address 0 -4. **Address**: Device has been assigned a unique address -5. **Configured**: Device is ready for normal operation -6. **Suspended**: Device is in low-power state - -**TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. - -Device Enumeration Process -========================== - -When a device is connected, the host follows this process: - -1. **Detection**: Host detects device connection -2. **Reset**: Host resets the device -3. **Descriptor Requests**: Host requests device descriptors -4. **Address Assignment**: Host assigns unique address to device -5. **Configuration**: Host selects and configures device -6. **Class Loading**: Host loads appropriate drivers -7. **Normal Operation**: Device is ready for use - -**TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. - -USB Descriptors -=============== - -Descriptors are data structures that describe device capabilities: - -Device Descriptor ------------------ -Describes the device (VID, PID, USB version, etc.) - -Configuration Descriptor ------------------------- -Describes device configuration (power requirements, interfaces, etc.) - -Interface Descriptor --------------------- -Describes a functional interface (class, endpoints, etc.) - -Endpoint Descriptor -------------------- -Describes endpoint characteristics (type, direction, size, etc.) - -String Descriptors ------------------- -Human-readable strings (manufacturer, product name, etc.) - -**TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: -- ``tud_descriptor_device_cb()`` - Device descriptor -- ``tud_descriptor_configuration_cb()`` - Configuration descriptor -- ``tud_descriptor_string_cb()`` - String descriptors - -The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. - -USB Classes -=========== - -USB classes define standardized protocols for device types: - -**Class Code**: Identifies the device type in descriptors -**Class Driver**: Software that implements the class protocol -**Class Requests**: Standardized commands for the class - -**Common TinyUSB-Supported Classes**: -- **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` -- **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` -- **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` -- **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` -- **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` -- **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` -- **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` - -See :doc:`../reference/usb_classes` for detailed class information and :doc:`../reference/configuration` for configuration options. - -USB Speeds -========== - -USB supports multiple speed modes: - -**Low Speed (1.5 Mbps)**: -- Simple devices (mice, keyboards) -- Limited endpoint types and sizes - -**Full Speed (12 Mbps)**: -- Most common for embedded devices -- All transfer types supported -- Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) - -**High Speed (480 Mbps)**: -- High-performance devices -- Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) -- Requires more complex hardware - -**Super Speed (5 Gbps)**: -- USB 3.0 and later -- Not supported by TinyUSB - -**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. - -USB Controller Abstraction -=========================== - -USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. - -Controller Fundamentals ------------------------ - -**What Controllers Do**: -- Handle USB signaling and protocol timing -- Manage endpoint buffers and data transfers -- Generate interrupts for USB events -- Implement USB electrical specifications - -**Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. - -Controller Architecture Types ------------------------------ - -Different MCU vendors implement USB controllers with varying architectures. -To list a few common patterns: - -**FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): -- Shared or dedicated FIFOs for endpoint data -- Software manages FIFO allocation and data flow -- Common in higher-end MCUs with flexible configurations - -**Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): -- Fixed packet memory areas for each endpoint -- Hardware automatically handles packet placement -- Simpler programming model, common in smaller MCUs - -**Descriptor-Based Controllers** (e.g., NXP EHCI-style): -- Use descriptor chains to describe transfers -- Hardware processes transfer descriptors independently -- More complex but can handle larger transfers autonomously - -TinyUSB Controller Abstraction ------------------------------- - -TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. -These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. - -**Portable Interface** (``src/device/usbd.h``): -- Standardized function signatures for all controllers -- Common endpoint and transfer management APIs -- Unified interrupt and event handling - -**Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): -- Implement the DCD interface for specific hardware -- Handle vendor-specific register layouts and behaviors -- Manage controller-specific quirks and workarounds - -**Common DCD Functions**: -- ``dcd_init()`` - Initialize controller hardware -- ``dcd_edpt_open()`` - Configure endpoint with type and size -- ``dcd_edpt_xfer()`` - Start data transfer on endpoint -- ``dcd_int_handler()`` - Process USB interrupts -- ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection - -Host Controller Driver (HCD) ------------------------------ - -TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. - -**Portable Interface** (``src/host/usbh.h``): -- Standardized interface for all host controllers -- Common device enumeration and pipe management -- Unified transfer scheduling and completion handling - -**Common HCD Functions**: -- ``hcd_init()`` - Initialize host controller hardware -- ``hcd_port_connect_status()`` - Check device connection status -- ``hcd_port_reset()`` - Reset connected device -- ``hcd_edpt_open()`` - Open communication pipe to device endpoint -- ``hcd_edpt_xfer()`` - Transfer data to/from connected device - -**Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. - -TinyUSB Event System & Thread Safety -==================================== - -Deferred Interrupt Processing ------------------------------ - -**Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. - -**Event Flow**: - -1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) -2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue -3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events -4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks - -**Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. - -Controller Event Flow ---------------------- - -**Typical USB Event Processing**: - -1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) -2. **Interrupt Generation**: Controller generates interrupt to CPU -3. **ISR Processing**: ``dcd_int_handler()`` reads controller status -4. **Event Queuing**: Events are queued for later processing (thread safety) -5. **Task Processing**: ``tud_task()`` processes queued events -6. **Class Notification**: Appropriate class drivers handle the event -7. **Application Callback**: User code responds to the event - -USB Class Driver Architecture -============================== - -TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. - -Class Driver Pattern ---------------------- - -**Standardized Entry Points**: Each class driver implements these core functions: - -- ``*_init()`` - Initialize class driver state and buffers -- ``*_reset()`` - Reset to initial state on USB bus reset -- ``*_open()`` - Parse and configure interfaces during enumeration -- ``*_control_xfer_cb()`` - Handle class-specific control requests -- ``*_xfer_cb()`` - Handle transfer completion callbacks - -**Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: - -.. code-block:: c - - // Single instance (default instance 0) - tud_cdc_write(data, len); - - // Multiple instances - tud_cdc_n_write(0, data, len); // Instance 0 - tud_cdc_n_write(1, data, len); // Instance 1 - -**Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. - -Class Driver Types -------------------- - -TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. - -Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. - -The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. - -**Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. - -Power Management -================ - -USB provides power to devices: - -**Bus-Powered**: Device draws power from USB bus (up to 500mA) -**Self-Powered**: Device has its own power source -**Suspend/Resume**: Devices must enter low-power mode when bus is idle - -**TinyUSB Power Management**: -- Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management -- Configure power requirements in device descriptor (``bMaxPower`` field) -- Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) -- Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` - -Next Steps -========== - -- Start with :doc:`../tutorials/getting_started` for basic setup -- Review :doc:`../reference/configuration` for configuration options -- Explore :doc:`../examples` for advanced use cases diff --git a/docs/faq.rst b/docs/faq.rst index 505833316..ade51a379 100644 --- a/docs/faq.rst +++ b/docs/faq.rst @@ -38,7 +38,7 @@ Run ``python tools/get_deps.py FAMILY`` where FAMILY is your MCU family (e.g., s **Q: Can I use my own build system instead of Make/CMake?** -Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`tutorials/getting_started` for details. +Yes, just add all ``.c`` files from ``src/`` to your project and configure include paths. See :doc:`getting_started` for details. **Q: Error: "tusb_config.h: No such file or directory"** diff --git a/docs/getting_started.rst b/docs/getting_started.rst new file mode 100644 index 000000000..5e8ebd040 --- /dev/null +++ b/docs/getting_started.rst @@ -0,0 +1,357 @@ +*************** +Getting Started +*************** + +This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. + +Add TinyUSB to your project +--------------------------- + +To incorporate TinyUSB into your project: + +* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` +* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project +* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. +* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. +* If you're using the **device stack**, you need to implement all **tud descriptor** callbacks for the stack to work. +* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. +* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler +* Implement all enabled classes' callbacks. +* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions periodically. These task functions handle all callbacks and core functionality. + +.. note:: + TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. + +.. code-block:: c + + int main(void) { + tusb_rhport_init_t dev_init = { + .role = TUSB_ROLE_DEVICE, + .speed = TUSB_SPEED_AUTO + }; + // tud descriptor omitted here + tusb_init(0, &dev_init); // initialize device stack on roothub port 0 + + tusb_rhport_init_t host_init = { + .role = TUSB_ROLE_HOST, + .speed = TUSB_SPEED_AUTO + }; + tusb_init(1, &host_init); // initialize host stack on roothub port 1 + + while(1) { // the mainloop + your_application_code(); + tud_task(); // device task + tuh_task(); // host task + } + } + + void USB0_IRQHandler(void) { + tusb_int_handler(0, true); + } + + void USB1_IRQHandler(void) { + tusb_int_handler(1, true); + } + +Examples +-------- + +For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already + +.. code-block:: bash + + $ git clone https://github.com/hathach/tinyusb tinyusb + $ cd tinyusb + +Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. + +Dependencies +^^^^^^^^^^^^ + +TinyUSB separates example applications from board-specific hardware configurations (Board Support Packages, BSP). Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while BSP configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. + +Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: + +1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. + +.. code-block:: bash + + $ python tools/get_deps.py rp2040 + +2. Or run the ``get-deps`` target in one of the example folders as follows. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=feather_nrf52840_express get-deps + +You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` + +Build Examples +^^^^^^^^^^^^^^ + +Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. + +.. code-block:: bash + + $ cd examples/device/cdc_msc + +Then compile with make or cmake + +.. code-block:: bash + + $ # make + $ make BOARD=feather_nrf52840_express all + + $ # cmake + $ mkdir build && cd build + $ cmake -DBOARD=raspberry_pi_pico .. + $ make + +To list all available targets with cmake + +.. code-block:: bash + + $ cmake --build . --target help + +Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient + +.. code-block:: bash + + $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ + $ sudo udevadm control --reload-rules && sudo udevadm trigger + +RootHub Port Selection +~~~~~~~~~~~~~~~~~~~~~~ + +If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. + +Port Speed +~~~~~~~~~~ + +An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: + +.. code-block:: bash + + $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all + + $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. + +Size Analysis +~~~~~~~~~~~~~ + +First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap + +Flashing the Device +^^^^^^^^^^^^^^^^^^^ + +The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash + $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash + +Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express flash-jlink + $ make BOARD=feather_nrf52840_express flash-openocd + + $ cmake --build . --target cdc_msc-jlink + $ cmake --build . --target cdc_msc-openocd + +Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express all uf2 + + $ cmake --build . --target cdc_msc-uf2 + +Debugging +^^^^^^^^^ + +To compile for debugging add ``DEBUG=1``\ , for example + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express DEBUG=1 all + + $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. + +Enable Logging +~~~~~~~~~~~~~~ + +If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. + +Logging Performance Impact +~~~~~~~~~~~~~~~~~~~~~~~~~~ + +By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: + + +* `LOGGER=rtt`: use `Segger RTT protocol `_ + + * Cons: requires jlink as the debugger. + * Pros: work with most if not all MCUs + * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. + +* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. + + * Cons: Only works with ARM Cortex MCUs except M0 + * Pros: should be compatible with more debugger that support SWO. + * Software viewer should be provided along with your debugger driver. + +.. code-block:: bash + + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all + $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all + + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. + $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. + +IAR Support +^^^^^^^^^^^ + +IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. + +Use project connection +~~~~~~~~~~~~~~~~~~~~~~ + +IAR Project Connection files are provided to import TinyUSB stack into your project. + +* A buildable project for your MCU needs to be created in advance. + + * Take example of STM32F0: + + - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. + + - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. + +* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) + Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, + for example ``C:\\tinyusb`` + +**Import stack only** + +Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. + +**Run examples** + +1. Run ``iar_gen.py`` to generate .ipcf files of examples: + + .. code-block:: + + > cd C:\tinyusb\tools + > python iar_gen.py + +2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. + For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` + +Native CMake support +~~~~~~~~~~~~~~~~~~~~ + +With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. + +Following these steps: + +1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. +2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. +3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. +4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. + +Common Issues and Solutions +--------------------------- + +**Build Errors** + +* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` +* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` +* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board + +**Runtime Issues** + +* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings +* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors +* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation + +Quick Start Examples +-------------------- + +Now that you have TinyUSB set up, you can try these examples to see it in action. + +Simple Device Example +^^^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. + +**What it does:** +* Appears as a serial port that echoes back any text you send +* Appears as a small USB drive with a README.TXT file +* Blinks an LED to show activity + +**Build and run:** + +.. code-block:: bash + + $ cd examples/device/cdc_msc + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tud_task()`` loop +* ``src/usb_descriptors.c`` - USB device descriptors +* ``src/msc_disk.c`` - Mass storage implementation + +**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. + +Simple Host Example +^^^^^^^^^^^^^^^^^^^ + +The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. + +**What it does:** +* Detects and enumerates connected USB devices +* Communicates with CDC devices (like USB-to-serial adapters) +* Reads from MSC devices (like USB drives) +* Receives input from HID devices (like keyboards and mice) + +**Build and run:** + +.. code-block:: bash + + $ cd examples/host/cdc_msc_hid + $ make BOARD=stm32f407disco all + $ make BOARD=stm32f407disco flash + +**Key files:** +* ``src/main.c`` - Main application with ``tuh_task()`` loop +* ``src/cdc_app.c`` - CDC host functionality +* ``src/msc_app.c`` - Mass storage host functionality +* ``src/hid_app.c`` - HID host functionality + +**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. + +Next Steps +^^^^^^^^^^ + +* Check :doc:`reference/boards` for board-specific information +* Explore more examples in ``examples/device/`` and ``examples/host/`` directories diff --git a/docs/index.rst b/docs/index.rst index 3a70f2471..ac10dbfd7 100644 --- a/docs/index.rst +++ b/docs/index.rst @@ -18,10 +18,8 @@ TinyUSB provides a complete USB stack implementation supporting both device and **Quick Navigation:** -* New to TinyUSB? Start with :doc:`tutorials/getting_started` -* Need to solve a specific problem? Check :doc:`guides/index` -* Looking for API details? See :doc:`reference/index` -* Want to understand the design? Read :doc:`explanation/architecture` +* New to TinyUSB? Start with :doc:`getting_started` and :doc:`reference/glossary` +* Want to understand the design? Read :doc:`reference/architecture` and :doc:`reference/usb_concepts` * Having issues? Check :doc:`faq` and :doc:`troubleshooting` Documentation Structure @@ -31,12 +29,10 @@ Documentation Structure :maxdepth: 2 :caption: Information - explanation/index - tutorials/index - guides/index - reference/index + getting_started faq troubleshooting + reference/index .. toctree:: :maxdepth: 1 diff --git a/docs/reference/architecture.rst b/docs/reference/architecture.rst new file mode 100644 index 000000000..ab451a91a --- /dev/null +++ b/docs/reference/architecture.rst @@ -0,0 +1,291 @@ +************ +Architecture +************ + +This document explains TinyUSB's internal architecture, design principles, and how different components work together. + +Design Principles +================= + +Memory Safety +------------- + +TinyUSB is designed for resource-constrained embedded systems with strict memory requirements: + +TinyUSB uses **no dynamic allocation** - all memory is statically allocated at compile time for predictability. All buffers have bounded, compile-time defined sizes to prevent overflow issues. The TinyUSB core avoids heap allocation, resulting in **predictable memory usage** where consumption is fully deterministic. + +Thread Safety +------------- + +TinyUSB achieves thread safety through a deferred interrupt model: + +- **ISR deferral**: USB interrupts are captured and deferred to task context +- **Single-threaded processing**: All USB protocol handling occurs in task context +- **Queue-based design**: Events are queued from ISR and processed in ``tud_task()`` +- **RTOS integration**: Proper semaphore/mutex usage for shared resources + +Portability +----------- + +The stack is designed to work across diverse microcontroller families: + +- **Hardware abstraction**: MCU-specific code isolated in portable drivers +- **OS abstraction**: RTOS dependencies isolated in OSAL layer +- **Modular design**: Features can be enabled/disabled at compile time +- **Standard compliance**: Strict adherence to USB specifications + +Core Architecture +================= + +Layer Structure +--------------- + +TinyUSB follows a layered architecture from hardware to application: + +.. code-block:: none + + ┌─────────────────────────────────────────┐ + │ Application Layer │ ← Your code + ├─────────────────────────────────────────┤ + │ USB Class Drivers │ ← CDC, HID, MSC, etc. + ├─────────────────────────────────────────┤ + │ Device/Host Stack Core │ ← USB protocol handling + ├─────────────────────────────────────────┤ + │ Hardware Abstraction (DCD/HCD) │ ← MCU-specific drivers + ├─────────────────────────────────────────┤ + │ OS Abstraction (OSAL) │ ← RTOS integration + ├─────────────────────────────────────────┤ + │ Common Utilities & FIFO │ ← Shared components + └─────────────────────────────────────────┘ + +Component Overview +------------------ + +**Application Layer**: Your main application code that uses TinyUSB APIs. + +**Class Drivers**: Implement specific USB device classes (CDC, HID, MSC, etc.) and handle class-specific requests. + +**Device/Host Core**: Implements USB protocol state machines, endpoint management, and core USB functionality. + +**Hardware Abstraction**: MCU-specific code that interfaces with USB peripheral hardware. + +**OS Abstraction**: Provides threading primitives and synchronization for different RTOS environments. + +**Common Utilities**: Shared code including FIFO implementations, binary helpers, and utility functions. + +Device Stack Architecture +========================= + +This section is concerned with the **Device Stack**, i.e., the component of TinyUSB used in USB devices (that talk to a USB host). + +Core Components +--------------- + +**Device Controller Driver (DCD)**: +- MCU-specific USB device peripheral driver +- Handles endpoint configuration and data transfers +- Abstracts hardware differences between MCU families +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Device Core (USBD)**: +- Implements USB device state machine +- Handles standard USB requests (Chapter 9) +- Manages device configuration and enumeration +- Located in ``src/device/`` + +**Class Drivers**: +- Implement USB class specifications +- Handle class-specific requests and data transfer +- Provide application APIs +- Located in ``src/class/*/`` + +Data Flow +--------- + +**Control Transfers (Setup Requests)**: + +.. code-block:: none + + USB Bus → DCD → USBD Core → Class Driver → Application + ↓ + Standard requests handled in core + ↓ + Class-specific requests → Class Driver + +**Data Transfers**: + +.. code-block:: none + + Application → Class Driver → USBD Core → DCD → USB Bus + USB Bus → DCD → USBD Core → Class Driver → Application + +Event Processing +---------------- + +TinyUSB uses a deferred interrupt model for thread safety: + +1. **Interrupt Occurs**: USB hardware generates interrupt +2. **ISR Handler**: ``dcd_int_handler()`` captures event, minimal processing +3. **Event Queuing**: Events queued for later processing +4. **Task Processing**: ``tud_task()`` (called by application code) processes queued events +5. **Callback Execution**: Application callbacks executed in task context + +.. code-block:: none + + USB IRQ → ISR → Event Queue → tud_task() → Class Callbacks → Application + +Host Stack Architecture +======================= + +This section is concerned with the **Host Stack**, i.e., the component of TinyUSB used in USB hosts, managing connected USB devices. + +Core Components +--------------- + +**Host Controller Driver (HCD)**: +- MCU-specific USB host peripheral driver +- Manages USB pipes and data transfers +- Handles host controller hardware +- Located in ``src/portable/VENDOR/FAMILY/`` + +**USB Host Core (USBH)**: +- Implements USB host functionality +- Manages device enumeration and configuration +- Handles pipe management and scheduling +- Located in ``src/host/`` + +**Hub Driver**: +- Manages USB hub devices +- Handles port management and device detection +- Supports multi-level hub topologies +- Located in ``src/host/`` + +Device Enumeration +------------------ + +The host stack follows USB enumeration process: + +1. **Device Detection**: Hub or root hub detects device connection +2. **Reset and Address**: Reset device, assign unique address +3. **Descriptor Retrieval**: Get device, configuration, and class descriptors +4. **Driver Matching**: Find appropriate class driver for device +5. **Configuration**: Configure device and start communication +6. **Class Operation**: Normal class-specific communication + +.. code-block:: none + + Device Connect → Reset → Get Descriptors → Load Driver → Configure → Operate + +Class Architecture +================== + +Common Class Structure +---------------------- + +All USB classes follow a similar architecture: + +**Device Classes**: +- ``*_device.c``: Device-side implementation +- ``*_device.h``: Device API definitions +- Implement class-specific descriptors +- Handle class requests and data transfer + +**Host Classes**: +- ``*_host.c``: Host-side implementation +- ``*_host.h``: Host API definitions +- Manage connected devices of this class +- Provide application interface + +Class Driver Interface +---------------------- + +**Required Functions**: +- ``init()``: Initialize class driver +- ``reset()``: Reset class state +- ``open()``: Configure class endpoints +- ``control_xfer_cb()``: Handle control requests +- ``xfer_cb()``: Handle data transfer completion + +**Optional Functions**: +- ``close()``: Clean up class resources +- ``sof_cb()``: Start-of-frame processing + +Descriptor Management +--------------------- + +Each class is responsible for: +- **Interface Descriptors**: Define class type and endpoints +- **Class-Specific Descriptors**: Additional class requirements +- **Endpoint Descriptors**: Define data transfer characteristics + +Memory Management +================= + +Static Allocation Model +----------------------- + +TinyUSB uses only static memory allocation; it allocates fixed-size endpoint buffers for each configured endpoint, static buffers for class-specific data handling, a fixed buffer dedicated to control transfers, and static event queues for deferred interrupt processing. + +Buffer Management +----------------- + +**Endpoint Buffers**: +- Allocated per endpoint at compile time +- Size defined by ``CFG_TUD_*_EP_BUFSIZE`` macros +- Used for USB data transfers + +**FIFO Buffers**: +- Ring buffers for streaming data +- Size defined by ``CFG_TUD_*_RX/TX_BUFSIZE`` macros +- Separate read/write pointers + +Threading Model +=============== + +Task-Based Design +----------------- + +TinyUSB uses a cooperative task model; it provides main tasks - ``tud_task()`` for device and ``tuh_task()`` for host operation. These tasks must be called regularly (typically less than 1ms intervals) to ensure all USB events are processed in task context, where application callbacks also execute. + +RTOS Integration +---------------- + +**Bare Metal**: +- Application calls ``tud_task()`` in main loop +- No threading primitives needed +- Simplest integration method + +**FreeRTOS**: +- USB task runs at high priority +- Semaphores used for synchronization +- Queue for inter-task communication + +**Other RTOS**: +- Similar patterns with RTOS-specific primitives +- OSAL layer abstracts RTOS differences + +Interrupt Handling +------------------ + +**Interrupt Service Routine**: +- Minimal processing in ISR +- Event capture and queuing only +- Quick return to avoid blocking + +**Deferred Processing**: +- All complex processing in task context +- Thread-safe access to data structures +- Application callbacks in known context + +Memory Usage Patterns +--------------------- + +**Flash Memory**: +- Core stack: 8-15KB depending on features +- Each class: 1-4KB additional +- Portable driver: 2-8KB depending on MCU + +**RAM Usage**: +- Core stack: 1-2KB +- Endpoint buffers: User configurable +- Class buffers: Depends on configuration diff --git a/docs/reference/configuration.rst b/docs/reference/configuration.rst deleted file mode 100644 index fa0a874f5..000000000 --- a/docs/reference/configuration.rst +++ /dev/null @@ -1,307 +0,0 @@ -************* -Configuration -************* - -TinyUSB behavior is controlled through compile-time configuration in ``tusb_config.h``. This reference covers all available configuration options. - -Basic Configuration -=================== - -Required Settings ------------------ - -.. code-block:: c - - // Target MCU family - REQUIRED - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - - // OS abstraction layer - REQUIRED - #define CFG_TUSB_OS OPT_OS_NONE - - // Enable device or host stack - #define CFG_TUD_ENABLED 1 // Device stack - #define CFG_TUH_ENABLED 1 // Host stack - -Debug and Logging ------------------ - -.. code-block:: c - - // Debug level (0=off, 1=error, 2=warning, 3=info) - #define CFG_TUSB_DEBUG 2 - - // Memory alignment for buffers (usually 4) - #define CFG_TUSB_MEM_ALIGN __attribute__ ((aligned(4))) - -Device Stack Configuration -========================== - -Endpoint Configuration ----------------------- - -.. code-block:: c - - // Control endpoint buffer size - #define CFG_TUD_ENDPOINT0_SIZE 64 - - // Number of endpoints (excluding EP0) - #define CFG_TUD_ENDPOINT_MAX 16 - -Device Classes --------------- - -**CDC (Communication Device Class)**: - -.. code-block:: c - - #define CFG_TUD_CDC 1 // Number of CDC interfaces - #define CFG_TUD_CDC_EP_BUFSIZE 512 // CDC endpoint buffer size - #define CFG_TUD_CDC_RX_BUFSIZE 256 // CDC RX FIFO size - #define CFG_TUD_CDC_TX_BUFSIZE 256 // CDC TX FIFO size - -**HID (Human Interface Device)**: - -.. code-block:: c - - #define CFG_TUD_HID 1 // Number of HID interfaces - #define CFG_TUD_HID_EP_BUFSIZE 16 // HID endpoint buffer size - -**MSC (Mass Storage Class)**: - -.. code-block:: c - - #define CFG_TUD_MSC 1 // Number of MSC interfaces - #define CFG_TUD_MSC_EP_BUFSIZE 512 // MSC endpoint buffer size - -**Audio Class**: - -.. code-block:: c - - #define CFG_TUD_AUDIO 1 // Number of audio interfaces - #define CFG_TUD_AUDIO_FUNC_1_DESC_LEN 220 - #define CFG_TUD_AUDIO_FUNC_1_N_AS_INT 1 - #define CFG_TUD_AUDIO_FUNC_1_CTRL_BUF_SZ 64 - #define CFG_TUD_AUDIO_ENABLE_EP_IN 1 - #define CFG_TUD_AUDIO_FUNC_1_N_BYTES_PER_SAMPLE_TX 2 - #define CFG_TUD_AUDIO_FUNC_1_N_CHANNELS_TX 2 - -**MIDI**: - -.. code-block:: c - - #define CFG_TUD_MIDI 1 // Number of MIDI interfaces - #define CFG_TUD_MIDI_RX_BUFSIZE 128 // MIDI RX buffer size - #define CFG_TUD_MIDI_TX_BUFSIZE 128 // MIDI TX buffer size - -**DFU (Device Firmware Update)**: - -.. code-block:: c - - #define CFG_TUD_DFU 1 // Enable DFU mode - #define CFG_TUD_DFU_XFER_BUFSIZE 512 // DFU transfer buffer size - -**Vendor Class**: - -.. code-block:: c - - #define CFG_TUD_VENDOR 1 // Number of vendor interfaces - #define CFG_TUD_VENDOR_EPSIZE 64 // Vendor endpoint size - #define CFG_TUD_VENDOR_RX_BUFSIZE 64 // RX buffer size (0 = no buffering) - #define CFG_TUD_VENDOR_TX_BUFSIZE 64 // TX buffer size (0 = no buffering) - -.. note:: - Unlike other classes, vendor class supports setting buffer sizes to 0 to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. - -Host Stack Configuration -======================== - -Port and Hub Configuration --------------------------- - -.. code-block:: c - - // Number of host root hub ports - #define CFG_TUH_HUB 1 - - // Number of connected devices (including hub) - #define CFG_TUH_DEVICE_MAX 5 - - // Control transfer buffer size - #define CFG_TUH_ENUMERATION_BUFSIZE 512 - -Host Classes ------------- - -**CDC Host**: - -.. code-block:: c - - #define CFG_TUH_CDC 2 // Number of CDC host instances - #define CFG_TUH_CDC_FTDI 1 // FTDI serial support - #define CFG_TUH_CDC_CP210X 1 // CP210x serial support - #define CFG_TUH_CDC_CH34X 1 // CH34x serial support - -**HID Host**: - -.. code-block:: c - - #define CFG_TUH_HID 4 // Number of HID instances - #define CFG_TUH_HID_EPIN_BUFSIZE 64 // HID endpoint buffer size - #define CFG_TUH_HID_EPOUT_BUFSIZE 64 - -**MSC Host**: - -.. code-block:: c - - #define CFG_TUH_MSC 1 // Number of MSC instances - #define CFG_TUH_MSC_MAXLUN 4 // Max LUNs per device - -Advanced Configuration -====================== - -Memory Management ------------------ - -.. code-block:: c - - // Enable stack protection - #define CFG_TUSB_DEBUG_PRINTF printf - - // Custom memory allocation (if needed) - #define CFG_TUSB_MEM_SECTION __attribute__((section(".usb_ram"))) - -RTOS Configuration ------------------- - -TinyUSB supports multiple operating systems through its OSAL (Operating System Abstraction Layer). Choose the appropriate configuration based on your target environment. - -**FreeRTOS Integration**: - -When using FreeRTOS, configure the task queue sizes to handle USB events efficiently: - -.. code-block:: c - - #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUD_TASK_QUEUE_SZ 16 // Device task queue size - #define CFG_TUH_TASK_QUEUE_SZ 16 // Host task queue size - -**RT-Thread Integration**: - -RT-Thread requires only the OS selection, as it uses the RTOS's built-in primitives: - -.. code-block:: c - - #define CFG_TUSB_OS OPT_OS_RTTHREAD - -Low Power Configuration ------------------------ - -.. code-block:: c - - // Enable remote wakeup - #define CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP 1 - - // Suspend/resume callbacks - // Implement tud_suspend_cb() and tud_resume_cb() - -MCU-Specific Options -==================== - -The ``CFG_TUSB_MCU`` option selects the target microcontroller family: - -.. code-block:: c - - // STM32 families - #define CFG_TUSB_MCU OPT_MCU_STM32F0 - #define CFG_TUSB_MCU OPT_MCU_STM32F1 - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_MCU OPT_MCU_STM32F7 - #define CFG_TUSB_MCU OPT_MCU_STM32H7 - - // NXP families - #define CFG_TUSB_MCU OPT_MCU_LPC18XX - #define CFG_TUSB_MCU OPT_MCU_LPC40XX - #define CFG_TUSB_MCU OPT_MCU_LPC43XX - #define CFG_TUSB_MCU OPT_MCU_KINETIS_KL - #define CFG_TUSB_MCU OPT_MCU_IMXRT - - // Other vendors - #define CFG_TUSB_MCU OPT_MCU_RP2040 - #define CFG_TUSB_MCU OPT_MCU_ESP32S2 - #define CFG_TUSB_MCU OPT_MCU_ESP32S3 - #define CFG_TUSB_MCU OPT_MCU_SAMD21 - #define CFG_TUSB_MCU OPT_MCU_SAMD51 - #define CFG_TUSB_MCU OPT_MCU_NRF5X - -Configuration Examples -====================== - -Minimal Device (CDC only) --------------------------- - -.. code-block:: c - - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_OS OPT_OS_NONE - #define CFG_TUSB_DEBUG 0 - - #define CFG_TUD_ENABLED 1 - #define CFG_TUD_ENDPOINT0_SIZE 64 - - #define CFG_TUD_CDC 1 - #define CFG_TUD_CDC_EP_BUFSIZE 512 - #define CFG_TUD_CDC_RX_BUFSIZE 512 - #define CFG_TUD_CDC_TX_BUFSIZE 512 - - // Disable other classes - #define CFG_TUD_HID 0 - #define CFG_TUD_MSC 0 - #define CFG_TUD_MIDI 0 - #define CFG_TUD_AUDIO 0 - #define CFG_TUD_VENDOR 0 - -Full-Featured Host ------------------- - -.. code-block:: c - - #define CFG_TUSB_MCU OPT_MCU_STM32F4 - #define CFG_TUSB_OS OPT_OS_FREERTOS - #define CFG_TUSB_DEBUG 2 - - #define CFG_TUH_ENABLED 1 - #define CFG_TUH_HUB 1 - #define CFG_TUH_DEVICE_MAX 8 - #define CFG_TUH_ENUMERATION_BUFSIZE 512 - - #define CFG_TUH_CDC 2 - #define CFG_TUH_HID 4 - #define CFG_TUH_MSC 2 - #define CFG_TUH_VENDOR 2 - -Validation -========== - -Use these checks to validate your configuration: - -.. code-block:: c - - // In your main.c, add compile-time checks - #if !defined(CFG_TUSB_MCU) || (CFG_TUSB_MCU == OPT_MCU_NONE) - #error "CFG_TUSB_MCU must be defined" - #endif - - #if CFG_TUD_ENABLED && !defined(CFG_TUD_ENDPOINT0_SIZE) - #error "CFG_TUD_ENDPOINT0_SIZE must be defined for device stack" - #endif - -Common Configuration Issues -=========================== - -1. **Endpoint buffer size too small**: Causes transfer failures -2. **Missing CFG_TUSB_MCU**: Build will fail -3. **Incorrect OS setting**: RTOS functions won't work properly -4. **Insufficient endpoint count**: Device enumeration will fail -5. **Buffer size mismatches**: Data corruption or transfer failures - -For configuration examples specific to your board, check ``examples/device/*/tusb_config.h``. \ No newline at end of file diff --git a/docs/reference/index.rst b/docs/reference/index.rst index cb35dd1b9..d3c96eeee 100644 --- a/docs/reference/index.rst +++ b/docs/reference/index.rst @@ -7,9 +7,8 @@ Complete reference documentation for TinyUSB APIs, configuration, and supported .. toctree:: :maxdepth: 2 - api/index - configuration - usb_classes + architecture + usb_concepts boards dependencies concurrency diff --git a/docs/reference/usb_classes.rst b/docs/reference/usb_classes.rst deleted file mode 100644 index 387587b48..000000000 --- a/docs/reference/usb_classes.rst +++ /dev/null @@ -1,287 +0,0 @@ -*********** -USB Classes -*********** - -TinyUSB supports multiple USB device and host classes. This reference describes the features, capabilities, and requirements for each class. - -Device Classes -============== - -CDC (Communication Device Class) --------------------------------- - -Implements USB CDC specification for serial communication. - -**Supported Features:** -- CDC-ACM (Abstract Control Model) for virtual serial ports -- Data terminal ready (DTR) and request to send (RTS) control lines -- Line coding configuration (baud rate, parity, stop bits) -- Break signal support - -**Configuration:** -- ``CFG_TUD_CDC``: Number of CDC interfaces (1-4) -- ``CFG_TUD_CDC_EP_BUFSIZE``: Endpoint buffer size (typically 512) -- ``CFG_TUD_CDC_RX_BUFSIZE``: Receive FIFO size -- ``CFG_TUD_CDC_TX_BUFSIZE``: Transmit FIFO size - -**Key Functions:** -- ``tud_cdc_available()``: Check bytes available to read -- ``tud_cdc_read()``: Read data from host -- ``tud_cdc_write()``: Write data to host -- ``tud_cdc_write_flush()``: Flush transmit buffer - -**Callbacks:** -- ``tud_cdc_line_coding_cb()``: Line coding changed -- ``tud_cdc_line_state_cb()``: DTR/RTS state changed - -HID (Human Interface Device) ----------------------------- - -Implements USB HID specification for input devices. - -**Supported Features:** -- Boot protocol (keyboard/mouse) -- Report protocol with custom descriptors -- Input, output, and feature reports -- Multiple HID interfaces - -**Configuration:** -- ``CFG_TUD_HID``: Number of HID interfaces -- ``CFG_TUD_HID_EP_BUFSIZE``: Endpoint buffer size - -**Key Functions:** -- ``tud_hid_ready()``: Check if ready to send report -- ``tud_hid_report()``: Send HID report -- ``tud_hid_keyboard_report()``: Send keyboard report -- ``tud_hid_mouse_report()``: Send mouse report - -**Callbacks:** -- ``tud_hid_descriptor_report_cb()``: Provide report descriptor -- ``tud_hid_get_report_cb()``: Handle get report request -- ``tud_hid_set_report_cb()``: Handle set report request - -MSC (Mass Storage Class) ------------------------- - -Implements USB mass storage for file systems. - -**Supported Features:** -- SCSI transparent command set -- Multiple logical units (LUNs) -- Read/write operations -- Inquiry and capacity commands - -**Configuration:** -- ``CFG_TUD_MSC``: Number of MSC interfaces -- ``CFG_TUD_MSC_EP_BUFSIZE``: Endpoint buffer size - -**Key Functions:** -- Storage operations handled via callbacks - -**Required Callbacks:** -- ``tud_msc_inquiry_cb()``: Device inquiry information -- ``tud_msc_test_unit_ready_cb()``: Test if LUN is ready -- ``tud_msc_capacity_cb()``: Get LUN capacity -- ``tud_msc_start_stop_cb()``: Start/stop LUN -- ``tud_msc_read10_cb()``: Read data from LUN -- ``tud_msc_write10_cb()``: Write data to LUN - -Audio Class ------------ - -Implements USB Audio Class 2.0 specification. - -**Supported Features:** -- Audio streaming (input/output) -- Multiple sampling rates -- Volume and mute controls -- Feedback endpoints for asynchronous mode - -**Configuration:** -- ``CFG_TUD_AUDIO``: Number of audio functions -- Multiple configuration options for channels, sample rates, bit depth - -**Key Functions:** -- ``tud_audio_read()``: Read audio data -- ``tud_audio_write()``: Write audio data -- ``tud_audio_clear_ep_out_ff()``: Clear output FIFO - -MIDI ----- - -Implements USB MIDI specification. - -**Supported Features:** -- MIDI 1.0 message format -- Multiple virtual MIDI cables -- Standard MIDI messages - -**Configuration:** -- ``CFG_TUD_MIDI``: Number of MIDI interfaces -- ``CFG_TUD_MIDI_RX_BUFSIZE``: Receive buffer size -- ``CFG_TUD_MIDI_TX_BUFSIZE``: Transmit buffer size - -**Key Functions:** -- ``tud_midi_available()``: Check available MIDI messages -- ``tud_midi_read()``: Read MIDI packet -- ``tud_midi_write()``: Send MIDI packet - -DFU (Device Firmware Update) ----------------------------- - -Implements USB DFU specification for firmware updates. - -**Supported Modes:** -- DFU Mode: Device enters DFU for firmware update -- DFU Runtime: Request transition to DFU mode - -**Configuration:** -- ``CFG_TUD_DFU``: Enable DFU mode -- ``CFG_TUD_DFU_RUNTIME``: Enable DFU runtime - -**Key Functions:** -- Firmware update operations handled via callbacks - -**Required Callbacks:** -- ``tud_dfu_download_cb()``: Receive firmware data -- ``tud_dfu_manifest_cb()``: Complete firmware update - -Vendor Class ------------- - -Custom vendor-specific USB class implementation. - -**Features:** -- Configurable endpoints -- Custom protocol implementation -- WebUSB support -- Microsoft OS descriptors - -**Configuration:** -- ``CFG_TUD_VENDOR``: Number of vendor interfaces -- ``CFG_TUD_VENDOR_EPSIZE``: Endpoint size - -**Key Functions:** -- ``tud_vendor_available()``: Check available data -- ``tud_vendor_read()``: Read vendor data -- ``tud_vendor_write()``: Write vendor data - -Host Classes -============ - -CDC Host --------- - -Connect to CDC devices (virtual serial ports). - -**Supported Devices:** -- CDC-ACM devices -- FTDI USB-to-serial converters -- CP210x USB-to-serial converters -- CH34x USB-to-serial converters - -**Configuration:** -- ``CFG_TUH_CDC``: Number of CDC host instances -- ``CFG_TUH_CDC_FTDI``: Enable FTDI support -- ``CFG_TUH_CDC_CP210X``: Enable CP210x support - -**Key Functions:** -- ``tuh_cdc_available()``: Check available data -- ``tuh_cdc_read()``: Read from CDC device -- ``tuh_cdc_write()``: Write to CDC device -- ``tuh_cdc_set_baudrate()``: Configure serial settings - -HID Host --------- - -Connect to HID devices (keyboards, mice, etc.). - -**Supported Devices:** -- Boot keyboards and mice -- Generic HID devices with report descriptors -- Composite HID devices - -**Configuration:** -- ``CFG_TUH_HID``: Number of HID host instances -- ``CFG_TUH_HID_EPIN_BUFSIZE``: Input endpoint buffer size - -**Key Functions:** -- ``tuh_hid_receive_report()``: Start receiving reports -- ``tuh_hid_send_report()``: Send report to device -- ``tuh_hid_parse_report_descriptor()``: Parse HID descriptors - -MSC Host --------- - -Connect to mass storage devices (USB drives). - -**Supported Features:** -- SCSI transparent command set -- FAT file system support (with FatFS integration) -- Multiple LUNs per device - -**Configuration:** -- ``CFG_TUH_MSC``: Number of MSC host instances -- ``CFG_TUH_MSC_MAXLUN``: Maximum LUNs per device - -**Key Functions:** -- ``tuh_msc_ready()``: Check if device is ready -- ``tuh_msc_read10()``: Read sectors from device -- ``tuh_msc_write10()``: Write sectors to device - -Hub ---- - -Support for USB hubs to connect multiple devices. - -**Features:** -- Multi-level hub support -- Port power management -- Device connect/disconnect detection - -**Configuration:** -- ``CFG_TUH_HUB``: Number of hub instances -- ``CFG_TUH_DEVICE_MAX``: Total connected devices - -Class Implementation Guidelines -=============================== - -Descriptor Requirements ------------------------ - -Each USB class requires specific descriptors: - -1. **Interface Descriptor**: Defines the class type -2. **Endpoint Descriptors**: Define communication endpoints -3. **Class-Specific Descriptors**: Additional class requirements -4. **String Descriptors**: Human-readable device information - -Callback Implementation ------------------------ - -Most classes require callback functions: - -- **Mandatory callbacks**: Must be implemented for class to function -- **Optional callbacks**: Provide additional functionality -- **Event callbacks**: Called when specific events occur - -Performance Considerations --------------------------- - -When implementing USB classes, match **buffer sizes** to expected data rates to avoid bottlenecks. Choose appropriate **transfer types** based on your application's requirements. Keep **callback processing** lightweight for optimal performance. Avoid **memory allocations in critical paths** where possible to maintain consistent performance. - -Testing and Validation ----------------------- - -- **USB-IF Compliance**: Ensure descriptors meet USB standards -- **Host Compatibility**: Test with multiple operating systems -- **Performance Testing**: Verify transfer rates and latency -- **Error Handling**: Test disconnect/reconnect scenarios - -Class-Specific Resources -======================== - -- **USB-IF Specifications**: Official USB class specifications -- **Example Code**: Reference implementations in ``examples/`` directory -- **Test Applications**: Host-side test applications for validation -- **Debugging Tools**: USB protocol analyzers and debugging utilities \ No newline at end of file diff --git a/docs/reference/usb_concepts.rst b/docs/reference/usb_concepts.rst new file mode 100644 index 000000000..86ae97007 --- /dev/null +++ b/docs/reference/usb_concepts.rst @@ -0,0 +1,428 @@ +************ +USB Concepts +************ + +This document provides a brief introduction to USB protocol fundamentals that are essential for understanding TinyUSB development. + +TinyUSB API Naming Conventions +=============================== + +TinyUSB uses consistent function prefixes to organize its API: + +* **tusb_**: Core stack functions (initialization, interrupt handling) +* **tud_**: Device stack functions (e.g., ``tud_task()``, ``tud_cdc_write()``) +* **tuh_**: Host stack functions (e.g., ``tuh_task()``, ``tuh_cdc_receive()``) +* **tu_**: Internal utility functions (generally not used by applications) + +This naming makes it easy to identify which part of the stack a function belongs to and ensures there are no naming conflicts when using both device and host stacks together. + +USB Protocol Basics +==================== + +Universal Serial Bus (USB) is a standardized communication protocol designed for connecting devices to hosts (typically computers). Understanding these core concepts is essential for effective TinyUSB development. + +Host and Device Roles +---------------------- + +**USB Host**: The controlling side of a USB connection (typically a computer). The host: +- Initiates all communication +- Provides power to devices +- Manages the USB bus +- Enumerates and configures devices + +**TinyUSB Host Stack**: Enable with ``CFG_TUH_ENABLED=1`` in ``tusb_config.h``. Call ``tuh_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. + +**USB Device**: The peripheral side (keyboard, mouse, storage device, etc.). Devices: +- Respond to host requests +- Cannot initiate communication +- Receive power from the host +- Must be enumerated by the host before use + +**TinyUSB Device Stack**: Enable with ``CFG_TUD_ENABLED=1`` in ``tusb_config.h``. Call ``tud_task()`` regularly in your main loop. See the :doc:`../getting_started` Quick Start Examples for implementation details. + +**OTG (On-The-Go)**: Some devices can switch between host and device roles dynamically. **TinyUSB Support**: Both stacks can be enabled simultaneously on OTG-capable hardware. See ``examples/dual/`` for dual-role implementations. + +USB Transfers +============= + +Every USB transfer consists of the host issuing a request, and the device replying to that request. The host is the bus master and initiates all communication. +Devices cannot initiate sending data; for unsolicited incoming data, polling is used by the host. + +USB defines four transfer types, each intended for different use cases: + +Control Transfers +----------------- + +Used for device configuration and control commands. + +**Characteristics**: +- Bidirectional (uses both IN and OUT) +- Guaranteed delivery with error detection +- Limited data size (8-64 bytes per packet) +- All devices must support control transfers on endpoint 0 + +**Usage**: Device enumeration, configuration changes, class-specific commands + +**TinyUSB Context**: Handled automatically by the core stack for standard requests; class drivers handle class-specific requests. Endpoint 0 is managed by ``src/device/usbd.c`` and ``src/host/usbh.c``. Configure buffer size with ``CFG_TUD_ENDPOINT0_SIZE`` (typically 64 bytes). + +Bulk Transfers +-------------- + +Used for large amounts of data that don't require guaranteed timing. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Large packet sizes (up to 512 bytes for High Speed) +- Uses available bandwidth when no other transfers are active + +**Usage**: File transfers, large data communication, CDC serial data + +**TinyUSB Context**: Used by MSC (mass storage) and CDC classes for data transfer. Configure endpoint buffer sizes with ``CFG_TUD_MSC_EP_BUFSIZE`` and ``CFG_TUD_CDC_EP_BUFSIZE``. See ``src/class/msc/`` and ``src/class/cdc/`` for implementation details. + +Interrupt Transfers +------------------- + +Used for small, time-sensitive data with guaranteed maximum latency. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- Guaranteed delivery with error detection +- Small packet sizes (up to 64 bytes for Full Speed) +- Regular polling interval (1ms to 255ms) + +**Usage**: Keyboard/mouse input, sensor data, status updates + +**TinyUSB Context**: Used by HID class for input reports. Configure with ``CFG_TUD_HID`` and ``CFG_TUD_HID_EP_BUFSIZE``. Send reports using ``tud_hid_report()`` or ``tud_hid_keyboard_report()``. See ``src/class/hid/`` and HID examples in ``examples/device/hid_*/``. + +Isochronous Transfers +--------------------- + +Used for time-critical streaming data. + +**Characteristics**: +- Unidirectional (separate IN and OUT endpoints) +- No error correction (speed over reliability) +- Guaranteed bandwidth +- Real-time delivery + +**Usage**: Audio, video streaming + +**TinyUSB Context**: Used by Audio class for streaming audio data. Configure with ``CFG_TUD_AUDIO`` and related audio configuration macros. See ``src/class/audio/`` and audio examples in ``examples/device/audio_*/`` for UAC2 implementation. + +Endpoints and Addressing +========================= + +Endpoint Basics +--------------- + +**Endpoint**: A communication channel between host and device. + +- Each endpoint has a number (0-15) and direction +- Endpoint 0 is reserved for control transfers +- Other endpoints are assigned by device class requirements + +**TinyUSB Endpoint Management**: Configure maximum endpoints with ``CFG_TUD_ENDPOINT_MAX``. Endpoints are automatically allocated by enabled classes. See your board's ``usb_descriptors.c`` for endpoint assignments. + +**Direction**: +- **OUT**: Host to device (host sends data out) +- **IN**: Device to host (host reads data in) +- Note that in TinyUSB code, for ``tx``/``rx``, the device perspective is used typically: E.g., ``tud_cdc_tx_complete_cb()`` designates the callback executed once the device has completed sending data to the host (in device mode). + +**Addressing**: Endpoints are addressed as EPx IN/OUT (e.g., EP1 IN, EP2 OUT) + +Endpoint Configuration +---------------------- + +Each endpoint is configured with a specific **transfer type** (control, bulk, interrupt, or isochronous), a **direction** (IN, OUT, or bidirectional for control only), a **maximum packet size** that depends on USB speed and transfer type, and an **interval** for interrupt and isochronous endpoints. + +**TinyUSB Configuration**: Endpoint characteristics are defined in descriptors (``usb_descriptors.c``) and automatically configured by the stack. Buffer sizes are set via ``CFG_TUD_*_EP_BUFSIZE`` macros. + +Error Handling and Flow Control +------------------------------- + +**Transfer Results**: USB transfers can complete with different results. An **ACK** indicates a successful transfer, while a **NAK** signals that the device is not ready (commonly used for flow control). A **STALL** response indicates an error condition or unsupported request, and **Timeout** occurs when a transfer fails to complete within the expected time frame. + +**Flow Control in USB**: Unlike network protocols, USB doesn't use traditional congestion control. Instead, devices use NAK responses when not ready to receive data, applications implement buffering and proper timing strategies, and some classes (like CDC) support hardware flow control mechanisms such as RTS/CTS. + +**TinyUSB Handling**: Transfer results are represented as ``xfer_result_t`` enum values. The stack automatically handles NAK responses and timing. STALL conditions indicate application-level errors that should be addressed in class drivers. + +USB Device States +================= + +A USB device progresses through several states: + +1. **Attached**: Device is physically connected +2. **Powered**: Device receives power from host +3. **Default**: Device responds to address 0 +4. **Address**: Device has been assigned a unique address +5. **Configured**: Device is ready for normal operation +6. **Suspended**: Device is in low-power state + +**TinyUSB State Management**: State transitions are handled automatically by ``src/device/usbd.c``. You can implement ``tud_mount_cb()`` and ``tud_umount_cb()`` to respond to configuration changes, and ``tud_suspend_cb()``/``tud_resume_cb()`` for power management. + +Device Enumeration Process +========================== + +When a device is connected, the host follows this process: + +1. **Detection**: Host detects device connection +2. **Reset**: Host resets the device +3. **Descriptor Requests**: Host requests device descriptors +4. **Address Assignment**: Host assigns unique address to device +5. **Configuration**: Host selects and configures device +6. **Class Loading**: Host loads appropriate drivers +7. **Normal Operation**: Device is ready for use + +**TinyUSB Role**: The device stack handles steps 1-6 automatically; your application handles step 7. + +USB Descriptors +=============== + +Descriptors are data structures that describe device capabilities: + +Device Descriptor +----------------- +Describes the device (VID, PID, USB version, etc.) + +Configuration Descriptor +------------------------ +Describes device configuration (power requirements, interfaces, etc.) + +Interface Descriptor +-------------------- +Describes a functional interface (class, endpoints, etc.) + +Endpoint Descriptor +------------------- +Describes endpoint characteristics (type, direction, size, etc.) + +String Descriptors +------------------ +Human-readable strings (manufacturer, product name, etc.) + +**TinyUSB Implementation**: You provide descriptors in ``usb_descriptors.c`` via callback functions: +- ``tud_descriptor_device_cb()`` - Device descriptor +- ``tud_descriptor_configuration_cb()`` - Configuration descriptor +- ``tud_descriptor_string_cb()`` - String descriptors + +The stack automatically handles descriptor requests during enumeration. See examples in ``examples/device/*/usb_descriptors.c`` for reference implementations. + +USB Classes +=========== + +USB classes define standardized protocols for device types: + +**Class Code**: Identifies the device type in descriptors +**Class Driver**: Software that implements the class protocol +**Class Requests**: Standardized commands for the class + +**Common TinyUSB-Supported Classes**: +- **CDC (02h)**: Communication devices (virtual serial ports) - Enable with ``CFG_TUD_CDC`` +- **HID (03h)**: Human interface devices (keyboards, mice) - Enable with ``CFG_TUD_HID`` +- **MSC (08h)**: Mass storage devices (USB drives) - Enable with ``CFG_TUD_MSC`` +- **Audio (01h)**: Audio devices (speakers, microphones) - Enable with ``CFG_TUD_AUDIO`` +- **MIDI**: MIDI devices - Enable with ``CFG_TUD_MIDI`` +- **DFU**: Device Firmware Update - Enable with ``CFG_TUD_DFU`` +- **Vendor**: Custom vendor classes - Enable with ``CFG_TUD_VENDOR`` + +.. note:: + **Vendor Class Buffer Configuration**: Unlike other USB classes, the vendor class supports setting buffer sizes to 0 in ``tusb_config.h`` (``CFG_TUD_VENDOR_RX_BUFSIZE = 0``) to disable internal buffering. When disabled, data goes directly to ``tud_vendor_rx_cb()`` and the ``tud_vendor_read()``/``tud_vendor_write()`` functions are not available - applications must handle data directly in callbacks. + +See ``examples/device/*/tusb_config.h`` for configuration examples. + +USB Speeds +========== + +USB supports multiple speed modes: + +**Low Speed (1.5 Mbps)**: +- Simple devices (mice, keyboards) +- Limited endpoint types and sizes + +**Full Speed (12 Mbps)**: +- Most common for embedded devices +- All transfer types supported +- Maximum packet sizes: Control (64), Bulk (64), Interrupt (64) + +**High Speed (480 Mbps)**: +- High-performance devices +- Larger packet sizes: Control (64), Bulk (512), Interrupt (1024) +- Requires more complex hardware + +**Super Speed (5 Gbps)**: +- USB 3.0 and later +- Not supported by TinyUSB + +**TinyUSB Speed Support**: Most TinyUSB ports support Full Speed and High Speed. Speed is typically auto-detected by hardware. Configure speed requirements in board configuration (``hw/bsp/FAMILY/boards/BOARD/board.mk``) and ensure your MCU supports the desired speed. + +USB Controller Abstraction +=========================== + +USB controllers are hardware peripherals that handle the low-level USB protocol implementation. Understanding how they work helps explain TinyUSB's architecture and portability. + +Controller Fundamentals +----------------------- + +**What Controllers Do**: +- Handle USB signaling and protocol timing +- Manage endpoint buffers and data transfers +- Generate interrupts for USB events +- Implement USB electrical specifications + +**Key Components**: USB controllers consist of several key components working together. The **Physical Layer** provides USB signal drivers and receivers for electrical interfacing. The **Protocol Engine** handles USB packets and ACK/NAK responses according to the USB specification. **Endpoint Buffers** provide hardware FIFOs or RAM for data storage during transfers. Finally, the **Interrupt Controller** generates events for software processing when USB activities occur. + +Controller Architecture Types +----------------------------- + +Different MCU vendors implement USB controllers with varying architectures. +To list a few common patterns: + +**FIFO-Based Controllers** (e.g., STM32 OTG, NXP LPC): +- Shared or dedicated FIFOs for endpoint data +- Software manages FIFO allocation and data flow +- Common in higher-end MCUs with flexible configurations + +**Buffer-Based Controllers** (e.g., STM32 FSDEV, Microchip SAMD, RP2040): +- Fixed packet memory areas for each endpoint +- Hardware automatically handles packet placement +- Simpler programming model, common in smaller MCUs + +**Descriptor-Based Controllers** (e.g., NXP EHCI-style): +- Use descriptor chains to describe transfers +- Hardware processes transfer descriptors independently +- More complex but can handle larger transfers autonomously + +TinyUSB Controller Abstraction +------------------------------ + +TinyUSB abstracts controller differences through the TinyUSB **Device Controller Driver (DCD)** layer. +These internal details don't matter to users of TinyUSB typically; however, when debugging, knowledge about internal details helps sometimes. + +**Portable Interface** (``src/device/usbd.h``): +- Standardized function signatures for all controllers +- Common endpoint and transfer management APIs +- Unified interrupt and event handling + +**Controller-Specific Drivers** (``src/portable/VENDOR/FAMILY/``): +- Implement the DCD interface for specific hardware +- Handle vendor-specific register layouts and behaviors +- Manage controller-specific quirks and workarounds + +**Common DCD Functions**: +- ``dcd_init()`` - Initialize controller hardware +- ``dcd_edpt_open()`` - Configure endpoint with type and size +- ``dcd_edpt_xfer()`` - Start data transfer on endpoint +- ``dcd_int_handler()`` - Process USB interrupts +- ``dcd_connect()/dcd_disconnect()`` - Control USB bus connection + +Host Controller Driver (HCD) +----------------------------- + +TinyUSB also abstracts USB host controllers through the **Host Controller Driver (HCD)** layer for host mode applications. + +**Portable Interface** (``src/host/usbh.h``): +- Standardized interface for all host controllers +- Common device enumeration and pipe management +- Unified transfer scheduling and completion handling + +**Common HCD Functions**: +- ``hcd_init()`` - Initialize host controller hardware +- ``hcd_port_connect_status()`` - Check device connection status +- ``hcd_port_reset()`` - Reset connected device +- ``hcd_edpt_open()`` - Open communication pipe to device endpoint +- ``hcd_edpt_xfer()`` - Transfer data to/from connected device + +**Host vs Device Architecture**: While DCD is reactive (responds to host requests), HCD is active (initiates all communication). Host controllers manage device enumeration, driver loading, and transfer scheduling to multiple connected devices. + +TinyUSB Event System & Thread Safety +==================================== + +Deferred Interrupt Processing +----------------------------- + +**Core Architectural Principle**: TinyUSB uses a deferred interrupt processing model where all USB hardware events are captured in interrupt service routines (ISRs) but processed later in non-interrupt context. + +**Event Flow**: + +1. **Hardware Event**: USB controller generates interrupt (e.g., data received, transfer complete) +2. **ISR Handling**: TinyUSB ISR captures the event and pushes it to a central event queue +3. **Deferred Processing**: Application calls ``tud_task()`` or ``tuh_task()`` to process queued events +4. **Class Driver Callbacks**: Events trigger appropriate class driver functions and user callbacks + +**Buffer Integration**: The deferred processing model works seamlessly with TinyUSB's buffer/FIFO design. Since callbacks run in task context (not ISR), it's safe and straightforward to enqueue TX data directly in RX callbacks - for example, processing incoming CDC data and immediately sending a response. + +Controller Event Flow +--------------------- + +**Typical USB Event Processing**: + +1. **Hardware Event**: USB controller detects bus activity (setup packet, data transfer, etc.) +2. **Interrupt Generation**: Controller generates interrupt to CPU +3. **ISR Processing**: ``dcd_int_handler()`` reads controller status +4. **Event Queuing**: Events are queued for later processing (thread safety) +5. **Task Processing**: ``tud_task()`` processes queued events +6. **Class Notification**: Appropriate class drivers handle the event +7. **Application Callback**: User code responds to the event + +USB Class Driver Architecture +============================== + +TinyUSB implements USB classes through a standardized driver pattern that provides consistent integration with the core stack while allowing class-specific functionality. + +Class Driver Pattern +--------------------- + +**Standardized Entry Points**: Each class driver implements these core functions: + +- ``*_init()`` - Initialize class driver state and buffers +- ``*_reset()`` - Reset to initial state on USB bus reset +- ``*_open()`` - Parse and configure interfaces during enumeration +- ``*_control_xfer_cb()`` - Handle class-specific control requests +- ``*_xfer_cb()`` - Handle transfer completion callbacks + +**Multi-Instance Support**: Classes support multiple instances using ``_n`` suffixed APIs: + +.. code-block:: c + + // Single instance (default instance 0) + tud_cdc_write(data, len); + + // Multiple instances + tud_cdc_n_write(0, data, len); // Instance 0 + tud_cdc_n_write(1, data, len); // Instance 1 + +**Integration with Core Stack**: Class drivers are automatically discovered and integrated through function pointers in driver tables. The core stack calls class drivers during enumeration, control requests, and data transfers without requiring explicit registration. + +Class Driver Types +------------------- + +TinyUSB classes have different architectural patterns based on their buffering capabilities and callback designs. + +Most classes like CDC, MIDI, and HID always use internal buffers for data management. These classes provide notification-only callbacks such as ``tud_cdc_rx_cb(uint8_t itf)`` that signal when data is available, requiring applications to use class-specific APIs like ``tud_cdc_read()`` and ``tud_cdc_write()`` to access the data. HID is slightly different in that it provides direct buffer access in some callbacks (``tud_hid_set_report_cb()`` receives buffer and size parameters), but it still maintains internal endpoint buffering that cannot be disabled. + +The **Vendor Class** is unique in that it supports both buffered and direct modes. When buffered, vendor class behaves like other classes with ``tud_vendor_read()`` and ``tud_vendor_write()`` APIs. However, when buffering is disabled by setting buffer size to 0, the vendor class provides direct buffer access through ``tud_vendor_rx_cb(itf, buffer, bufsize)`` callbacks, eliminating internal FIFO overhead and providing direct endpoint control. + +**Block-Oriented Classes** like MSC operate differently by handling large data blocks through callback interfaces. The application implements storage access functions such as ``tud_msc_read10_cb()`` and ``tud_msc_write10_cb()``, while the TinyUSB stack manages the USB protocol aspects and the application manages the underlying storage. + +Power Management +================ + +USB provides power to devices: + +**Bus-Powered**: Device draws power from USB bus (up to 500mA) +**Self-Powered**: Device has its own power source +**Suspend/Resume**: Devices must enter low-power mode when bus is idle + +**TinyUSB Power Management**: +- Implement ``tud_suspend_cb()`` and ``tud_resume_cb()`` for power management +- Configure power requirements in device descriptor (``bMaxPower`` field) +- Use ``tud_remote_wakeup()`` to wake the host from suspend (if supported) +- Enable remote wakeup with ``CFG_TUD_USBD_ENABLE_REMOTE_WAKEUP`` + +Next Steps +========== + +- Start with :doc:`../getting_started` for basic setup +- Review ``examples/device/*/tusb_config.h`` for configuration examples +- Explore examples in ``examples/device/`` and ``examples/host/`` directories diff --git a/docs/tutorials/getting_started.rst b/docs/tutorials/getting_started.rst deleted file mode 100644 index 35a9aa9bf..000000000 --- a/docs/tutorials/getting_started.rst +++ /dev/null @@ -1,356 +0,0 @@ -*************** -Getting Started -*************** - -This tutorial will guide you through setting up TinyUSB for your first project. We'll cover the basic integration steps and build your first example application. - -Add TinyUSB to your project ---------------------------- - -To incorporate TinyUSB into your project: - -* Copy this repository or add it as a git submodule to a subfolder in your project. For example, place it at ``your_project/tinyusb`` -* Add all the ``.c`` files in the ``tinyusb/src`` folder to your project -* Add ``your_project/tinyusb/src`` to your include path. Also ensure that your include path contains the configuration file ``tusb_config.h``. -* Ensure all required macros are properly defined in ``tusb_config.h``. The configuration file from the demo applications provides a good starting point, but you'll need to add additional macros such as ``CFG_TUSB_MCU`` and ``CFG_TUSB_OS``. These are typically passed by make/cmake to maintain unique configurations for different boards. -* If you're using the device stack, ensure you have created or modified USB descriptors to meet your specific requirements. Ultimately you need to implement all **tud descriptor** callbacks for the stack to work. -* Add a ``tusb_init(rhport, role)`` call to your reset initialization code. -* Call ``tusb_int_handler(rhport, in_isr)`` from your USB IRQ handler -* Implement all enabled classes' callbacks. -* If you're not using an RTOS, you must call the ``tud_task()``/``tuh_task()`` functions continuously or periodically. These task functions handle all callbacks and core functionality. - -.. note:: - TinyUSB uses consistent naming prefixes: ``tud_`` for device stack functions and ``tuh_`` for host stack functions. See the :doc:`../reference/glossary` for more details. - -.. code-block:: c - - int main(void) { - tusb_rhport_init_t dev_init = { - .role = TUSB_ROLE_DEVICE, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(0, &dev_init); // initialize device stack on roothub port 0 - - tusb_rhport_init_t host_init = { - .role = TUSB_ROLE_HOST, - .speed = TUSB_SPEED_AUTO - }; - tusb_init(1, &host_init); // initialize host stack on roothub port 1 - - while(1) { // the mainloop - your_application_code(); - tud_task(); // device task - tuh_task(); // host task - } - } - - void USB0_IRQHandler(void) { - tusb_int_handler(0, true); - } - - void USB1_IRQHandler(void) { - tusb_int_handler(1, true); - } - -Examples --------- - -For your convenience, TinyUSB contains a handful of examples for both host and device with/without RTOS to quickly test the functionality as well as demonstrate how API should be used. Most examples will work on most of :doc:`the supported boards `. Firstly we need to ``git clone`` if not already - -.. code-block:: bash - - $ git clone https://github.com/hathach/tinyusb tinyusb - $ cd tinyusb - -Some ports require additional port-specific SDKs (e.g., for RP2040) or binaries (e.g., for Sony Spresense) to build examples. These components are outside the scope of TinyUSB, so you should download and install them first according to the manufacturer's documentation. - -Dependencies -^^^^^^^^^^^^ - -TinyUSB separates example applications from board-specific hardware configurations. Example applications live in ``examples/device``, ``examples/host``, and ``examples/dual`` directories, while Board Support Package (BSP) configurations are stored in ``hw/bsp/FAMILY/boards/BOARD_NAME``. The BSP provides hardware abstraction including pin mappings, clock settings, linker scripts, and hardware initialization routines. For example, raspberry_pi_pico is located in ``hw/bsp/rp2040/boards/raspberry_pi_pico`` where ``FAMILY=rp2040`` and ``BOARD=raspberry_pi_pico``. When you build an example with ``BOARD=raspberry_pi_pico``, the build system automatically finds and uses the corresponding BSP. - -Before building, you must first download dependencies including MCU low-level peripheral drivers and external libraries such as FreeRTOS (required by some examples). You can do this in either of two ways: - -1. Run the ``tools/get_deps.py {FAMILY}`` script to download all dependencies for a specific MCU family. To download dependencies for all families, use ``FAMILY=all``. - -.. code-block:: bash - - $ python tools/get_deps.py rp2040 - -2. Or run the ``get-deps`` target in one of the example folders as follows. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=feather_nrf52840_express get-deps - -You only need to do this once per family. Check out :doc:`complete list of dependencies and their designated path here ` - -Build Examples -^^^^^^^^^^^^^^ - -Examples support both Make and CMake build systems for most MCUs. However, some MCU families (such as Espressif and RP2040) only support CMake. First change directory to an example folder. - -.. code-block:: bash - - $ cd examples/device/cdc_msc - -Then compile with make or cmake - -.. code-block:: bash - - $ # make - $ make BOARD=feather_nrf52840_express all - - $ # cmake - $ mkdir build && cd build - $ cmake -DBOARD=raspberry_pi_pico .. - $ make - -To list all available targets with cmake - -.. code-block:: bash - - $ cmake --build . --target help - -Note: Some examples, especially those that use Vendor class (e.g., webUSB), may require udev permissions on Linux (and/or macOS) to access USB devices. It depends on your OS distribution, but typically copying ``99-tinyusb.rules`` and reloading udev is sufficient - -.. code-block:: bash - - $ cp examples/device/99-tinyusb.rules /etc/udev/rules.d/ - $ sudo udevadm control --reload-rules && sudo udevadm trigger - -RootHub Port Selection -~~~~~~~~~~~~~~~~~~~~~~ - -If a board has several ports, one port is chosen by default in the individual board.mk file. Use option ``RHPORT_DEVICE=x`` or ``RHPORT_HOST=x`` To choose another port. For example to select the HS port of a STM32F746Disco board, use: - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE=1 all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE=1 .. - -Port Speed -~~~~~~~~~~ - -An MCU can support multiple operational speeds. By default, the example build system uses the fastest speed supported by the board. Use the option ``RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED`` or ``RHPORT_HOST_SPEED=OPT_MODE_FULL_SPEED/OPT_MODE_HIGH_SPEED``. For example, to force the F723 to operate at full speed instead of the default high speed: - -.. code-block:: bash - - $ make BOARD=stm32f746disco RHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED all - - $ cmake -DBOARD=stm32f746disco -DRHPORT_DEVICE_SPEED=OPT_MODE_FULL_SPEED .. - -Size Analysis -~~~~~~~~~~~~~ - -First install `linkermap tool `_ then ``linkermap`` target can be used to analyze code size. You may want to compile with ``NO_LTO=1`` since ``-flto`` merges code across ``.o`` files and make it difficult to analyze. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express NO_LTO=1 all linkermap - -Flashing the Device -^^^^^^^^^^^^^^^^^^^ - -The ``flash`` target uses the default on-board debugger (jlink/cmsisdap/stlink/dfu) to flash the binary. Please install the supporting software in advance. Some boards use bootloader/DFU via serial, which requires passing the serial port to the make command - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash - $ make SERIAL=/dev/ttyACM0 BOARD=feather_nrf52840_express flash - -Since jlink/openocd can be used with most of the boards, there is also ``flash-jlink/openocd`` (make) and ``EXAMPLE-jlink/openocd`` target for your convenience. Note for stm32 board with stlink, you can use ``flash-stlink`` target as well. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express flash-jlink - $ make BOARD=feather_nrf52840_express flash-openocd - - $ cmake --build . --target cdc_msc-jlink - $ cmake --build . --target cdc_msc-openocd - -Some boards use UF2 bootloader for drag-and-drop into a mass storage device. UF2 files can be generated with the ``uf2`` target - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express all uf2 - - $ cmake --build . --target cdc_msc-uf2 - -Debugging -^^^^^^^^^ - -To compile for debugging add ``DEBUG=1``\ , for example - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express DEBUG=1 all - - $ cmake -DBOARD=feather_nrf52840_express -DCMAKE_BUILD_TYPE=Debug .. - -Enable Logging -~~~~~~~~~~~~~~ - -If you encounter issues running examples or need to submit a bug report, you can enable TinyUSB's built-in debug logging with the optional ``LOG=`` parameter. ``LOG=1`` prints only error messages, while ``LOG=2`` prints more detailed information about ongoing events. ``LOG=3`` or higher is not used yet. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 .. - -Logging Performance Impact -~~~~~~~~~~~~~~~~~~~~~~~~~~ - -By default, log messages are printed via the on-board UART, which is slow and consumes significant CPU time compared to USB speeds. If your board supports an on-board or external debugger, it would be more efficient to use it for logging. There are 2 protocols: - - -* `LOGGER=rtt`: use `Segger RTT protocol `_ - - * Cons: requires jlink as the debugger. - * Pros: work with most if not all MCUs - * Software viewer is JLink RTT Viewer/Client/Logger which is bundled with JLink driver package. - -* ``LOGGER=swo``\ : Use dedicated SWO pin of ARM Cortex SWD debug header. - - * Cons: Only works with ARM Cortex MCUs except M0 - * Pros: should be compatible with more debugger that support SWO. - * Software viewer should be provided along with your debugger driver. - -.. code-block:: bash - - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=rtt all - $ make BOARD=feather_nrf52840_express LOG=2 LOGGER=swo all - - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=rtt .. - $ cmake -DBOARD=feather_nrf52840_express -DLOG=2 -DLOGGER=swo .. - -IAR Support -^^^^^^^^^^^ - -IAR Embedded Workbench is a commercial IDE and toolchain for embedded development. TinyUSB provides integration support for IAR through project connection files and native CMake support. - -Use project connection -~~~~~~~~~~~~~~~~~~~~~~ - -IAR Project Connection files are provided to import TinyUSB stack into your project. - -* A buildable project for your MCU needs to be created in advance. - - * Take example of STM32F0: - - - You need ``stm32f0xx.h``, ``startup_stm32f0xx.s``, and ``system_stm32f0xx.c``. - - - ``STM32F0xx_HAL_Driver`` is only needed to run examples, TinyUSB stack itself doesn't rely on MCU's SDKs. - -* Open ``Tools -> Configure Custom Argument Variables`` (Switch to ``Global`` tab if you want to do it for all your projects) - Click ``New Group ...``, name it to ``TUSB``, Click ``Add Variable ...``, name it to ``TUSB_DIR``, change it's value to the path of your TinyUSB stack, - for example ``C:\\tinyusb`` - -**Import stack only** - -Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\tools\\iar_template.ipcf``. - -**Run examples** - -1. Run ``iar_gen.py`` to generate .ipcf files of examples: - - .. code-block:: - - > cd C:\tinyusb\tools - > python iar_gen.py - -2. Open ``Project -> Add project Connection ...``, click ``OK``, choose ``tinyusb\\examples\\(.ipcf of example)``. - For example ``C:\\tinyusb\\examples\\device\\cdc_msc\\iar_cdc_msc.ipcf`` - -Native CMake support -~~~~~~~~~~~~~~~~~~~~ - -With 9.50.1 release, IAR added experimental native CMake support (strangely not mentioned in public release note). Now it's possible to import CMakeLists.txt then build and debug as a normal project. - -Following these steps: - -1. Add IAR compiler binary path to system ``PATH`` environment variable, such as ``C:\Program Files\IAR Systems\Embedded Workbench 9.2\arm\bin``. -2. Create new project in IAR, in Tool chain dropdown menu, choose CMake for Arm then Import ``CMakeLists.txt`` from chosen example directory. -3. Set up board option in ``Option - CMake/CMSIS-TOOLBOX - CMake``, for example ``-DBOARD=stm32f439nucleo -DTOOLCHAIN=iar``, **Uncheck 'Override tools in env'**. -4. (For debug only) Choose correct CPU model in ``Option - General Options - Target``, to profit register and memory view. - -Common Issues and Solutions ---------------------------- - -**Build Errors** - -* **"arm-none-eabi-gcc: command not found"**: Install ARM GCC toolchain: ``sudo apt-get install gcc-arm-none-eabi`` -* **"Board 'X' not found"**: Check the available boards in ``hw/bsp/FAMILY/boards/`` or run ``python tools/build.py -l`` -* **Missing dependencies**: Run ``python tools/get_deps.py FAMILY`` where FAMILY matches your board - -**Runtime Issues** - -* **Device not recognized**: Check USB descriptors implementation and ``tusb_config.h`` settings -* **Enumeration failure**: Enable logging with ``LOG=2`` and check for USB protocol errors -* **Hard faults/crashes**: Verify interrupt handler setup and stack size allocation - -Quick Start Examples --------------------- - -Now that you have TinyUSB set up, you can try these examples to see it in action. - -Simple Device Example -^^^^^^^^^^^^^^^^^^^^^ - -The ``cdc_msc`` example creates a USB device with both a virtual serial port (CDC) and mass storage (MSC). This is the most commonly used example and demonstrates core device functionality. - -**What it does:** -* Appears as a serial port that echoes back any text you send -* Appears as a small USB drive with a README.TXT file -* Blinks an LED to show activity - -**Build and run:** - -.. code-block:: bash - - $ cd examples/device/cdc_msc - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tud_task()`` loop -* ``src/usb_descriptors.c`` - USB device descriptors -* ``src/msc_disk.c`` - Mass storage implementation - -**Expected behavior:** Connect to your computer and you'll see both a new serial port and a small USB drive appear. - -Simple Host Example -^^^^^^^^^^^^^^^^^^^ - -The ``cdc_msc_hid`` example creates a USB host that can connect to USB devices with CDC, MSC, or HID interfaces. - -**What it does:** -* Detects and enumerates connected USB devices -* Communicates with CDC devices (like USB-to-serial adapters) -* Reads from MSC devices (like USB drives) -* Receives input from HID devices (like keyboards and mice) - -**Build and run:** - -.. code-block:: bash - - $ cd examples/host/cdc_msc_hid - $ make BOARD=stm32f407disco all - $ make BOARD=stm32f407disco flash - -**Key files:** -* ``src/main.c`` - Main application with ``tuh_task()`` loop -* ``src/cdc_app.c`` - CDC host functionality -* ``src/msc_app.c`` - Mass storage host functionality -* ``src/hid_app.c`` - HID host functionality - -**Expected behavior:** Connect USB devices to see enumeration messages and device-specific interactions in the serial output. - -Next Steps -^^^^^^^^^^ - -* Check :doc:`../reference/boards` for board-specific information -* Explore more :doc:`../examples` for advanced use cases diff --git a/docs/tutorials/index.rst b/docs/tutorials/index.rst deleted file mode 100644 index dc362d717..000000000 --- a/docs/tutorials/index.rst +++ /dev/null @@ -1,10 +0,0 @@ -********* -Tutorials -********* - -Step-by-step learning guides for TinyUSB development. - -.. toctree:: - :maxdepth: 2 - - getting_started \ No newline at end of file -- cgit v1.3.1