Module rp2040_hal::usb[][src]

Expand description

Universal Serial Bus (USB)

Usage

Initialize the Usb Bus forcing the VBUS detection.

use rp2040_hal::{clocks::init_clocks_and_plls, pac, Sio, usb::UsbBus, watchdog::Watchdog};
use usb_device::class_prelude::UsbBusAllocator;

const XOSC_CRYSTAL_FREQ: u32 = 12_000_000; // Typically found in BSP crates

let mut pac = pac::Peripherals::take().unwrap();
let sio = Sio::new(pac.SIO);
let mut watchdog = Watchdog::new(pac.WATCHDOG);
let mut clocks = init_clocks_and_plls(
    XOSC_CRYSTAL_FREQ,
    pac.XOSC,
    pac.CLOCKS,
    pac.PLL_SYS,
    pac.PLL_USB,
    &mut pac.RESETS,
    &mut watchdog
).ok().unwrap();

let usb_bus = UsbBusAllocator::new(UsbBus::new(
        pac.USBCTRL_REGS,
        pac.USBCTRL_DPRAM,
        clocks.usb_clock,
        true,
        &mut pac.RESETS,
    ));
// Use the usb_bus as usual.

See pico_usb_serial.rs for more complete examples

Enumeration issue with small EP0 max packet size

During enumeration Windows hosts send a StatusOut after the DataIn packet of the first Get Descriptor resquest even if the DataIn isn’t completed (typically when the max_packet_size_ep0 is less than 18bytes). The next request request is a Set Address that expect a StatusIn.

The issue is that by the time the previous DataIn packet is acknoledged and the StatusOut followed by Setup are received, the usb stack may have already prepared the next DataIn payload in the EP0 IN mailbox resulting in the payload being transmitted to the host instead of the StatusIn for the Set Address request as expected by the host.

To avoid that issue, the EP0 In mailbox should be invalidated between the Setup packet and the next StatusIn initiated by the host. The workaround implemented clears the available bit of the EP0 In endpoint’s buffer to stop the device from sending the data instead of the status packet. This workaround has the caveat that the poll function must be called between those two which are only separated by a few microseconds.

If the required timing cannot be met, using an maximum packet size of the endpoint 0 above 18bytes (e.g. .max_packet_size_ep0(64)) should avoid that issue.

Structs

Usb bus