Mistake on this page?
Report an issue in GitHub or email us

USB device

The HAL USBPhy API provides physical access to the USB bus in the role of a USB device. Implementing this API enables the use of any supported class driver, such as CDC, HID and MSD.

Warning: We are changing the USB API in an upcoming release of Mbed OS. This page documents code that exists on a feature branch of Mbed OS. You can find details on how it may affect you in the Implementing the USB section.

Assumptions

Defined behavior

  • You can use any endpoint configurations that fit in the parameters of the table returned by USBPhy::endpoint_table.
  • You can use all endpoints in any valid endpoint configuration concurrently.
  • The device supports use of at least one control, bulk, interrupt and isochronous in each direction at the same time - at least 8 endpoints.
  • USBPhy supports all standard endpoint sizes (wMaxPacketSize).
  • USBPhy can handle an interrupt latency of at least 100ms if the host PC is not performing a reset or setting the device's address.
  • USBPhy only sends USBPhyEvents when it is in the initialized state.
  • When unpowered, USBPhy only sends the USBPhyEvents::power event.
  • On USB reset, all endpoints are removed except for endpoint 0.
  • A call to USBPhy::ep0_write results in the call of USBPhyEvents::in when the PC reads the data unless a power loss, reset or a call to USBPhy::disconnect occurs first.
  • A call to USBPhy::endpoint_write results in the call of USBPhyEvents::in when the PC reads the data unless a power loss, reset or a call to USBPhy::endpoint_abort occurs first.
  • A call to USBPhy::endpoint_read results in the call of USBPhyEvents::out when the PC sends data unless a power loss, reset or a call to USBPhy::endpoint_abort occurs first.
  • Endpoint 0 naks all transactions aside from setup packets until higher-level code calls one of USBPhy::ep0_read, USBPhy::ep0_write or USBPhy::ep0_stall.
  • Endpoint 0 stall automatically clears on reception of a setup packet.

Undefined behavior

  • Calling USBPhy::endpoint_add or USBPhy::endpoint_remove outside of the control requests SetInterface or SetConfiguration.
  • Calling USBPhy::endpoint_remove on an endpoint that has an ongoing read or write operation. To avoid undefined behavior, you must abort ongoing operations with USBPhy::endpoint_abort.
  • Devices behavior is undefined if latency is greater than 2ms when address is being set - see USB spec 9.2.6.3.
  • Devices behavior is undefined if latency is greater than 10ms when a reset occurs - see USB spec 7.1.7.5.
  • Calling any of the USBPhy::endpoint_* functions on endpoint 0.

Notes

  • Make sure USBPhy sends USBPhyEvents in the correct order when multiple packets are present. USBPhy must send IN endpoint events before OUT endpoint events if both are pending.
  • A host PC may resend setup packets to a USB device if there is noise on the USB line. The USBPhy should be able to handle this scenario and respond to the setup packet with an ACK.
  • Bidirectional protocols making use of alternating IN and OUT phases should not rely on the last ACK an IN transfer to indicate that the OUT phase should start. Instead, the OUT phase should be started at the same time the last IN transfer is started. This is because the ACK to the last in transfer may be dropped if there is noise on the USB line. If dropped, it will only be resent on the next IN phase. You can find more information on this in section 8.5.3.3 of the USB specification.

Implementing USB

To add support for the HAL USBPhy API, you need to implement this API and submit pull requests against the feature-hal-spec-usb-device branch. Please see the API and specification for the HAL USBPhy API for more information:

Public Member Functions
virtual void init (USBPhyEvents *events)=0
 Initialize this USBPhy instance. More...
virtual void deinit ()=0
 Power down this USBPhy instance. More...
virtual bool powered ()=0
 Check if USB power is present. More...
virtual void connect ()=0
 Make the USB phy visible to the USB host. More...
virtual void disconnect ()=0
 Detach the USB phy. More...
virtual void configure ()=0
 Set this device to the configured state. More...
virtual void unconfigure ()=0
 Leave the configured state. More...
virtual void sof_enable ()=0
 Enable the start of frame interrupt. More...
virtual void sof_disable ()=0
 Disable the start of frame interrupt. More...
virtual void set_address (uint8_t address)=0
 Set the USBPhy's address. More...
virtual void remote_wakeup ()=0
 Wake upstream devices. More...
virtual const usb_ep_table_tendpoint_table ()=0
 Get the endpoint table. More...
virtual uint32_t ep0_set_max_packet (uint32_t max_packet)=0
 Set wMaxPacketSize of endpoint 0. More...
virtual void ep0_setup_read_result (uint8_t *buffer, uint32_t size)=0
 Read the contents of the SETUP packet. More...
virtual void ep0_read (uint8_t *data, uint32_t size)=0
 Start receiving a packet of up to wMaxPacketSize on endpoint 0. More...
virtual uint32_t ep0_read_result ()=0
 Read the contents of a received packet. More...
virtual void ep0_write (uint8_t *buffer, uint32_t size)=0
 Write a packet on endpoint 0. More...
virtual void ep0_stall ()=0
 Protocol stall on endpoint 0. More...
virtual bool endpoint_add (usb_ep_t endpoint, uint32_t max_packet, usb_ep_type_t type)=0
 Configure and enable an endpoint. More...
virtual void endpoint_remove (usb_ep_t endpoint)=0
 Disable an endpoint. More...
virtual void endpoint_stall (usb_ep_t endpoint)=0
 Perform a functional stall on the given endpoint. More...
virtual void endpoint_unstall (usb_ep_t endpoint)=0
 Unstall the endpoint. More...
virtual bool endpoint_read (usb_ep_t endpoint, uint8_t *data, uint32_t size)=0
 Start a read on the given endpoint. More...
virtual uint32_t endpoint_read_result (usb_ep_t endpoint)=0
 Finish a read on the given endpoint. More...
virtual bool endpoint_write (usb_ep_t endpoint, uint8_t *data, uint32_t size)=0
 Start a write on the given endpoint. More...
virtual void endpoint_abort (usb_ep_t endpoint)=0
 Abort the current transfer if it has not yet been sent. More...
virtual void process ()=0
 Callback used for performing USB processing. More...

To enable the HAL USBPhy API in Mbed OS, add the USBDEVICE label in the device_has option of the target's section in the targets.json file.

Testing

The Mbed OS HAL provides a set of conformance tests for the HAL USBPhy API. You can use these tests to validate the correctness of your implementation. To run the HAL USBPhy API tests, use the following command:

mbed test -t <toolchain> -m <target> -n mbed-os-tests-usb_device-*
Important Information for this Arm website

This site uses cookies to store information on your computer. By continuing to use our site, you consent to our cookies. If you are not happy with the use of these cookies, please review our Cookie Policy to learn how they can be disabled. By disabling cookies, some features of the site will not work.