Wiznet makers

ruilixin6

Published August 22, 2026 ©

117 UCC

0 VAR

0 Contests

0 Followers

0 Following

Original Link

Understanding Raspberry Pi Pico USB: Hardware, Architecture & MicroPython Control

RP2040 USB works in host/device modes. Pico MicroPython uses built‑in USB‑CDC for data transfer.

COMPONENTS
PROJECT DESCRIPTION

【Preliminary Note】The original hardware example in this article was written based on the RP2040. The actual hardware used in this hands-on demonstration features the W55RP20 as the main controller chip. The circuit logic and UF2 flashing operation principles are universally applicable, with only the main controller model differing. The original chip model mentioned in the circuit descriptions below is provided for reference purposes only.

1.Overview of Raspberry Pi Pico USB Peripherals 

The RP2040 chip on Raspberry Pi Pico integrates a USB 2.0 controller that can operate in the following modes:

 A full‑speed device (12 Mbps) 

A host communicating with low‑speed (1.5 Mbps) and full‑speed devices, including multiple downstream devices connected via a USB hub

RP2040 has a built‑in USB 1.1 PHY chip. The USB controller connects to the chip’s DP(D+) and DM(D‑) pins through this PHY. The USB‑controller hardware implements the USB physical layer, data‑link layer and partial transaction‑layer functions. Programmers do not need to handle complex low‑level USB protocol details manually. Instead, developers focus on these tasks: 

Configure controller parameters such as device address and endpoints 

Supply data buffers for controller transmit and receive operations

 Respond to controller interrupt events like transfer completion and endpoint status changes

The USB controller features 4 kB DPSRAM for storing USB‑device configuration and data buffers.

The USB controller supports two operating modes:

 Device Mode: 

USB 2.0‑compliant full‑speed device (12 Mbps)

 Supports up to 32 endpoints (0 → 15 for both IN and OUT directions) 

Supports control, isochronous, bulk and interrupt endpoint types with double‑buffering

 3840‑byte usable buffer space inside DPSRAM, equivalent to 60 × 64‑byte buffers 

Host Mode:

 Communicates with full‑speed (12 Mbps) and low‑speed (1.5 Mbps) devices 

Works with multiple devices over a USB hub, including low‑speed devices behind a full‑speed hub 

Hardware can poll up to 15 interrupt endpoints

 Interrupt endpoints notify hosts of hub connect/disconnect events, mouse movement and other signals

Structure of the USB peripheral: 1280X1280.PNG

The USB peripheral consists mainly of the components listed below:

 Integrated USB PHY Chip

 Implements USB physical‑layer protocols including electrical characteristics, signal encoding and differential transmission 

Provides electrical interface between USB DP/DM pins and controller digital logic

 Drives DP and DM pins for transmission and performs differential reception for incoming data 

Feeds single‑ended and differential received data to the line‑state‑detection module

 USB Controller

 Implements USB device‑side protocol stack and endpoint management 

Manages data reception and transmission, plus generation and parsing of control signals 

Buffer Memory 

DPSRAM holds control registers and data buffers 

The USB controller includes 4 kB (4096‑byte) dual‑port SRAM (DPSRAM) 

DPSRAM can be accessed as 32‑bit memory at USB‑controller address 0 (0x50100000

Supports 8‑bit / 16‑bit / 32‑bit access; set‑and‑clear alias operations are unsupported

 Typical buffer length is 64 bytes: 

          Max buffer size for isochronous transfers: 1023 bytes 

         Max buffer size for other transfer types: 64 bytes

 DPSRAM of USB controller must be treated as asynchronous and non‑atomic:

         As dual‑port SRAM, it has one port for the processor and one port for the USB controller. Both may access the same memory address simultaneously. One may write while the other reads. Reading by the controller during CPU writes yields inconsistent data. This race condition must be avoided. 

Line‑State‑Detection Module

    Defines and detects bus states: bus reset, connect, suspend, resume, DATA1, DATA0 and more 

    Contains state machines for state detection and sends event signals to other hardware blocks       USB has no shared clock; received RX data is sampled via internal clock

     Full‑speed USB runs at 12 Mbps. RX data is sampled at 48 MHz, providing four clock cycles to capture and filter bus states. Filtered RX data is forwarded to the serial RX engine. 

Receive Engine 

   The serial receive engine decodes data captured by the line‑state‑detection module. It extracts: 

   PID (Packet Identifier) of incoming packets

    Device address of incoming traffic 

   Endpoint number of incoming traffic

    Payload data bytes

   It runs CRC checks on incoming data to detect receive errors. Errors trigger notifications to other hardware blocks and may raise interrupts.

   Hardware generates errors if USB cable is disconnected mid‑transfer under host or device mode. 

Transmit Engine

 The serial transmit engine is the counterpart of the receive engine.It connects to the active controller (device or host). It builds TOKEN and DATA packets, calculates CRC values and transmits packets onto the USB bus.

2. Software Control Methods

 Within MicroPython, USB devices fall into two categories: 

1."Runtime" USB Devices:  

       1. Defined after MicroPython boots via Python APIs (USBDevice class) 

      2.Require runtime configuration and activation

2. "Built‑in" USB Devices: 

   1. Compiled into MicroPython firmware and always available

   2.Usually includes USB‑CDC (virtual serial port) and optional USB‑MSC (mass‑storage class)          3.  Ready‑to‑use without extra configuration

MicroPython provides the low‑level Python API USBDevice class for implementing USB‑device drivers: 

  Constructor:

    USBDevice is a singleton class; every constructor call returns the identical object reference. 

  Main Methods:

    config() — configures USB‑device descriptors and callback functions

    active() — enables or disables runtime USB devices 

    builtin_driver attribute — reads or modifies built‑in USB‑driver settings

    remote_wakeup() — wakes a suspended USB host

    submit_xfer() — submits non‑control transfers

    stall() — sets or queries endpoint STALL status

   Constants:

 BUILTIN_NONE, BUILTIN_DEFAULT, BUILTIN_CDC, BUILTIN_MSC, BUILTIN_CDC_MSC represent different built‑in USB‑driver configurations.

Unfortunately, as shown in replies from the link below, Raspberry Pi Pico cannot use the USBDevice class to control runtime USB devices like STM32‑based PyBoard: https://github.com/micropython/micropython/issues/6811

2.png

Referring to previous REPL interpreter documentation: default MicroPython firmware for Raspberry Pi Pico carries a built‑in USB‑CDC driver offering a virtual serial channel. This USB‑CDC is a firmware‑integrated "Built‑in" device usable with zero extra configuration. We can leverage this virtual serial port together with system standard input and output to complete USB data transmission.

 

Documents
Comments Write