Skip to content
This repository was archived by the owner on Mar 26, 2026. It is now read-only.
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
4 changes: 2 additions & 2 deletions examples/boot-uf2-dfu/Makefile
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@ TARGET = boot-uf2-dfu
LIBRARIES = fx2 fx2usb fx2dfu fx2usbmassstor fx2uf2 fx2isrs
MODEL = medium

CODE_SIZE ?= 0x3c00
XRAM_SIZE ?= 0x0400
CODE_SIZE ?= 0x3d00
XRAM_SIZE ?= 0x0300

LIBFX2 = ../../firmware/library
include $(LIBFX2)/fx2rules.mk
2 changes: 2 additions & 0 deletions firmware/library/include/fx2usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -160,6 +160,8 @@ struct usb_descriptor_set {
usb_configuration_set_c *configs;
uint8_t string_count;
usb_ascii_string_c *strings;
uint8_t capability_count;
usb_desc_generic_c *capabilities;
};

typedef __code const struct usb_descriptor_set
Expand Down
32 changes: 32 additions & 0 deletions firmware/library/include/usb.h
Original file line number Diff line number Diff line change
Expand Up @@ -49,11 +49,18 @@ enum usb_descriptor {
USB_DESC_DEVICE = 1,
USB_DESC_CONFIGURATION = 2,
USB_DESC_STRING = 3,
USB_DESC_URL = USB_DESC_STRING,
USB_DESC_INTERFACE = 4,
USB_DESC_ENDPOINT = 5,
USB_DESC_DEVICE_QUALIFIER = 6,
USB_DESC_OTHER_SPEED_CONFIGURATION = 7,
USB_DESC_INTERFACE_POWER = 8,
USB_DESC_BINARY_OBJECT_STORE = 15,
USB_DESC_DEVICE_CAPABILITY = 16,
};

enum usb_device_capability {
USB_DEV_CAP_PLATFORM = 5,
};

enum usb_feature {
Expand Down Expand Up @@ -232,4 +239,29 @@ struct usb_desc_string {
typedef __code const struct usb_desc_string
usb_desc_string_c;

enum usb_url_scheme {
USB_URL_SCHEME_HTTP = 0,
USB_URL_SCHEME_HTTPS = 1,
};

struct usb_desc_url {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bScheme;
uint8_t bURL[];
};

typedef __code const struct usb_desc_url
usb_desc_url_c;

struct usb_desc_binary_object_store {
uint8_t bLength;
uint8_t bDescriptorType;
uint16_t wTotalLength;
uint8_t bNumDeviceCaps;
};

typedef __code const struct usb_desc_binary_object_store
usb_binary_object_store_c;

#endif
24 changes: 24 additions & 0 deletions firmware/library/include/usbweb.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,24 @@
#ifndef USBWEB_H
#define USBWEB_H

#include <usb.h>

// {3408b638-09a9-47a0-8bfd-a0768815b665}
#define USB_PLATFORM_CAPABILITY_UUID_WEBUSB \
{0x38, 0xB6, 0x08, 0x34, 0xA9, 0x09, 0xA0, 0x47, 0x8B, 0xFD, 0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65}

struct usb_desc_platform_capability_webusb {
uint8_t bLength;
uint8_t bDescriptorType;
uint8_t bDevCapabilityType;
uint8_t bReserved;
uint8_t PlatformCapablityUUID[16];
uint16_t bcdVersion;
uint8_t bVendorCode;
uint8_t iLandingPage;
};

typedef __code const struct usb_desc_platform_capability_webusb
usb_desc_platform_capability_webusb_c;

#endif
63 changes: 41 additions & 22 deletions firmware/library/usb.c
Original file line number Diff line number Diff line change
Expand Up @@ -68,67 +68,70 @@ __asm
mov _DPS, #0
__endasm;

uint8_t bmRequestType = req->bmRequestType;
uint8_t bRequest = req->bRequest;

// Get Descriptor
if(req->bmRequestType == (USB_RECIP_DEVICE|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_DESCRIPTOR) {
if(bmRequestType == (USB_RECIP_DEVICE|USB_DIR_IN) &&
bRequest == USB_REQ_GET_DESCRIPTOR) {
enum usb_descriptor type = (enum usb_descriptor)(req->wValue >> 8);
uint8_t index = req->wValue & 0xff;
handle_usb_get_descriptor(type, index);
// Set Configuration
} else if(req->bmRequestType == (USB_RECIP_DEVICE|USB_DIR_OUT) &&
req->bRequest == USB_REQ_SET_CONFIGURATION) {
} else if(bmRequestType == (USB_RECIP_DEVICE|USB_DIR_OUT) &&
bRequest == USB_REQ_SET_CONFIGURATION) {
if(handle_usb_set_configuration((uint8_t)req->wValue)) {
ACK_EP0();
} else {
STALL_EP0();
}
// Get Configuration
} else if(req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_CONFIGURATION) {
} else if(bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_IN) &&
bRequest == USB_REQ_GET_CONFIGURATION) {
handle_usb_get_configuration();
// Set Interface
} else if(req->bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_OUT) &&
req->bRequest == USB_REQ_SET_INTERFACE) {
} else if(bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_OUT) &&
bRequest == USB_REQ_SET_INTERFACE) {
if(handle_usb_set_interface((uint8_t)req->wIndex, (uint8_t)req->wValue)) {
ACK_EP0();
} else {
STALL_EP0();
}
// Get Interface
} else if(req->bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_INTERFACE) {
} else if(bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_IN) &&
bRequest == USB_REQ_GET_INTERFACE) {
handle_usb_get_interface((uint8_t)req->wIndex);
// Set Feature - Device
} else if(req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_OUT) &&
req->bRequest == USB_REQ_SET_FEATURE) {
} else if(bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_OUT) &&
bRequest == USB_REQ_SET_FEATURE) {
if(req->wValue == USB_FEAT_DEVICE_REMOTE_WAKEUP) {
usb_remote_wakeup = true;
ACK_EP0();
} else if(req->wValue == USB_FEAT_TEST_MODE) {
ACK_EP0();
}
// Get Status - Device
} else if(req->bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_STATUS) {
} else if(bmRequestType == (USB_RECIP_DEVICE|USB_TYPE_STANDARD|USB_DIR_IN) &&
bRequest == USB_REQ_GET_STATUS) {
EP0BUF[0] = (usb_self_powered << 0) |
(usb_remote_wakeup << 1);
EP0BUF[1] = 0;
SETUP_EP0_IN_BUF(2);
// Get Status - Interface
} else if(req->bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_STATUS) {
} else if(bmRequestType == (USB_RECIP_IFACE|USB_TYPE_STANDARD|USB_DIR_IN) &&
bRequest == USB_REQ_GET_STATUS) {
EP0BUF[0] = 0;
EP0BUF[1] = 0;
SETUP_EP0_IN_BUF(2);
// Set Feature - Endpoint
// Clear Feature - Endpoint
} else if(req->bmRequestType == (USB_RECIP_ENDPT|USB_TYPE_STANDARD|USB_DIR_OUT) &&
(req->bRequest == USB_REQ_SET_FEATURE ||
req->bRequest == USB_REQ_CLEAR_FEATURE)) {
} else if(bmRequestType == (USB_RECIP_ENDPT|USB_TYPE_STANDARD|USB_DIR_OUT) &&
(bRequest == USB_REQ_SET_FEATURE ||
bRequest == USB_REQ_CLEAR_FEATURE)) {
if(req->wValue == USB_FEAT_ENDPOINT_HALT) {
__xdata volatile uint8_t *EPnCS = EPnCS_for_n(req->wIndex);
if(EPnCS != 0) {
if(req->bRequest == USB_REQ_SET_FEATURE) {
if(bRequest == USB_REQ_SET_FEATURE) {
*EPnCS |= _STALL;
ACK_EP0();
} else {
Expand All @@ -141,8 +144,8 @@ __endasm;
}
}
// Get Status - Endpoint
} else if(req->bmRequestType == (USB_RECIP_ENDPT|USB_TYPE_STANDARD|USB_DIR_IN) &&
req->bRequest == USB_REQ_GET_STATUS) {
} else if(bmRequestType == (USB_RECIP_ENDPT|USB_TYPE_STANDARD|USB_DIR_IN) &&
bRequest == USB_REQ_GET_STATUS) {
__xdata volatile uint8_t *EPnCS = EPnCS_for_n(req->wIndex);
if(EPnCS != 0) {
EP0BUF[0] = ((*EPnCS & _STALL) != 0);
Expand Down Expand Up @@ -210,6 +213,22 @@ void usb_serve_descriptor(usb_descriptor_set_c *set,
*buf++ = 0;
scratch[0] += 2;
}
} else if(type == USB_DESC_BINARY_OBJECT_STORE && index == 0) {
__xdata struct usb_desc_binary_object_store *bos_desc =
(__xdata struct usb_desc_binary_object_store *)buf;
bos_desc->bLength = sizeof(struct usb_desc_binary_object_store);
bos_desc->bDescriptorType = USB_DESC_BINARY_OBJECT_STORE;
// bos_desc->wTotalLength filled in later
bos_desc->bNumDeviceCaps = set->capability_count;
buf += bos_desc->bLength;
__code const struct usb_desc_generic *dev_cap_desc = set->capabilities;
for(uint8_t i = 0; i < set->capability_count; i++) {
APPEND(dev_cap_desc);
dev_cap_desc++;
}
bos_desc->wTotalLength = (uint16_t)(buf - scratch);
SETUP_EP0_IN_DATA(scratch, bos_desc->wTotalLength);
return;
} else {
STALL_EP0();
return;
Expand Down