From a62a1636892f2454d06b05186aa09ac8ed6ae029 Mon Sep 17 00:00:00 2001 From: Alex Taradov Date: Sat, 5 Mar 2022 15:50:14 -0800 Subject: [PATCH] Added CMSIS-DAP v2 support to RP2040 port + some USB code refactoring --- platform/rp2040/main.c | 43 +++-- platform/rp2040/make/.gitignore | 2 +- platform/rp2040/make/Makefile | 180 ++++++++++---------- platform/rp2040/startup_rp2040.c | 2 - platform/rp2040/tools/.gitignore | 6 +- platform/rp2040/{ => usb}/usb.h | 3 - platform/rp2040/{ => usb}/usb_cdc.c | 50 +----- platform/rp2040/{ => usb}/usb_cdc.h | 17 +- platform/rp2040/{ => usb}/usb_hid.c | 30 +--- platform/rp2040/{ => usb}/usb_hid.h | 6 +- platform/rp2040/{usb.c => usb/usb_rp2040.c} | 9 +- platform/rp2040/{ => usb}/usb_std.c | 69 +++++--- platform/rp2040/{ => usb}/usb_std.h | 70 ++++++-- platform/rp2040/usb/usb_winusb.c | 37 ++++ platform/rp2040/usb/usb_winusb.h | 153 +++++++++++++++++ platform/rp2040/usb_descriptors.c | 155 ++++++++++++++--- platform/rp2040/usb_descriptors.h | 63 +++++-- platform/rp2040/utils.h | 14 -- 18 files changed, 619 insertions(+), 290 deletions(-) rename platform/rp2040/{ => usb}/usb.h (91%) rename platform/rp2040/{ => usb}/usb_cdc.c (77%) rename platform/rp2040/{ => usb}/usb_cdc.h (97%) rename platform/rp2040/{ => usb}/usb_hid.c (58%) rename platform/rp2040/{ => usb}/usb_hid.h (93%) rename platform/rp2040/{usb.c => usb/usb_rp2040.c} (98%) rename platform/rp2040/{ => usb}/usb_std.c (79%) rename platform/rp2040/{ => usb}/usb_std.h (71%) create mode 100644 platform/rp2040/usb/usb_winusb.c create mode 100644 platform/rp2040/usb/usb_winusb.h delete mode 100644 platform/rp2040/utils.h diff --git a/platform/rp2040/main.c b/platform/rp2040/main.c index 7d4aba6..b779e23 100644 --- a/platform/rp2040/main.c +++ b/platform/rp2040/main.c @@ -25,8 +25,10 @@ #define F_TICK 1000000 /*- Variables ---------------------------------------------------------------*/ -static uint8_t app_request_buffer[DAP_CONFIG_PACKET_SIZE]; -static uint8_t app_response_buffer[DAP_CONFIG_PACKET_SIZE]; +static uint8_t app_req_buf_hid[DAP_CONFIG_PACKET_SIZE]; +static uint8_t app_resp_buf_hid[DAP_CONFIG_PACKET_SIZE]; +static uint8_t app_req_buf_bulk[DAP_CONFIG_PACKET_SIZE]; +static uint8_t app_resp_buf_bulk[DAP_CONFIG_PACKET_SIZE]; static uint8_t app_recv_buffer[USB_BUFFER_SIZE]; static uint8_t app_send_buffer[USB_BUFFER_SIZE]; static int app_recv_buffer_size = 0; @@ -124,7 +126,7 @@ static void serial_number_init(void) //----------------------------------------------------------------------------- static void sys_time_init(void) { - SysTick->VAL = 0; + SysTick->VAL = 0; SysTick->LOAD = 1000; // 1 ms SysTick->CTRL = SysTick_CTRL_ENABLE_Msk; app_system_time = 0; @@ -222,6 +224,7 @@ static void uart_timer_task(void) //----------------------------------------------------------------------------- void usb_cdc_line_coding_updated(usb_cdc_line_coding_t *line_coding) { + (void)line_coding; uart_init(line_coding); } @@ -277,35 +280,43 @@ void usb_cdc_recv_callback(int size) //----------------------------------------------------------------------------- void usb_hid_send_callback(void) { - usb_hid_recv(app_request_buffer, DAP_CONFIG_PACKET_SIZE); + usb_hid_recv(app_req_buf_hid, DAP_CONFIG_PACKET_SIZE); } //----------------------------------------------------------------------------- void usb_hid_recv_callback(int size) { app_dap_event = true; - dap_process_request(app_request_buffer, sizeof(app_request_buffer), - app_response_buffer, sizeof(app_response_buffer)); - usb_hid_send(app_response_buffer, sizeof(app_response_buffer)); + dap_process_request(app_req_buf_hid, sizeof(app_req_buf_hid), + app_resp_buf_hid, sizeof(app_resp_buf_hid)); + usb_hid_send(app_resp_buf_hid, sizeof(app_resp_buf_hid)); (void)size; } //----------------------------------------------------------------------------- -bool usb_class_handle_request(usb_request_t *request) +static void usb_bulk_send_callback(void) { - if (usb_cdc_handle_request(request)) - return true; - else if (usb_hid_handle_request(request)) - return true; - else - return false; + usb_recv(USB_BULK_EP_RECV, app_req_buf_bulk, sizeof(app_req_buf_bulk)); +} + +//----------------------------------------------------------------------------- +static void usb_bulk_recv_callback(int size) +{ + app_dap_event = true; + size = dap_process_request(app_req_buf_bulk, size, + app_resp_buf_bulk, sizeof(app_resp_buf_bulk)); + usb_send(USB_BULK_EP_SEND, app_resp_buf_bulk, size); } //----------------------------------------------------------------------------- void usb_configuration_callback(int config) { + usb_set_send_callback(USB_BULK_EP_SEND, usb_bulk_send_callback); + usb_set_recv_callback(USB_BULK_EP_RECV, usb_bulk_recv_callback); + usb_cdc_recv(app_recv_buffer, sizeof(app_recv_buffer)); - usb_hid_recv(app_request_buffer, sizeof(app_request_buffer)); + usb_hid_recv(app_req_buf_hid, sizeof(app_req_buf_hid)); + usb_recv(USB_BULK_EP_RECV, app_req_buf_bulk, sizeof(app_req_buf_bulk)); app_send_buffer_free = true; app_send_buffer_ptr = 0; @@ -367,5 +378,3 @@ int main(void) return 0; } - - diff --git a/platform/rp2040/make/.gitignore b/platform/rp2040/make/.gitignore index 3722ac6..567609b 100644 --- a/platform/rp2040/make/.gitignore +++ b/platform/rp2040/make/.gitignore @@ -1 +1 @@ -build/ +build/ diff --git a/platform/rp2040/make/Makefile b/platform/rp2040/make/Makefile index 1ec77d1..5244806 100644 --- a/platform/rp2040/make/Makefile +++ b/platform/rp2040/make/Makefile @@ -1,87 +1,93 @@ -############################################################################## -BUILD = build -BIN = free_dap_rp2040 - -############################################################################## -.PHONY: all directory clean size - -CC = arm-none-eabi-gcc -OBJCOPY = arm-none-eabi-objcopy -SIZE = arm-none-eabi-size - -ifeq ($(OS), Windows_NT) - MKDIR = gmkdir -else - MKDIR = mkdir -endif - -CFLAGS += -W -Wall --std=gnu11 -Os -CFLAGS += -ffreestanding -CFLAGS += -fno-diagnostics-show-caret -CFLAGS += -fdata-sections -ffunction-sections -CFLAGS += -funsigned-char -funsigned-bitfields -CFLAGS += -mcpu=cortex-m0plus -mthumb -CFLAGS += -MD -MP -MT $(BUILD)/$(*F).o -MF $(BUILD)/$(@F).d - -LDFLAGS += -mcpu=cortex-m0plus -mthumb -LDFLAGS += -nostartfiles -LDFLAGS += -Wl,--gc-sections -LDFLAGS += -Wl,--script=../linker/rp2040.ld - -INCLUDES += \ - -I../include \ - -I../../.. \ - -I.. - -SRCS += \ - ../main.c \ - ../uart.c \ - ../usb.c \ - ../usb_std.c \ - ../usb_cdc.c \ - ../usb_hid.c \ - ../usb_descriptors.c \ - ../startup_rp2040.c \ - ../../../dap.c \ - -DEFINES += \ - -CFLAGS += $(INCLUDES) $(DEFINES) - -OBJS = $(addprefix $(BUILD)/, $(notdir %/$(subst .c,.o, $(SRCS)))) - -all: directory $(BUILD)/$(BIN).elf $(BUILD)/$(BIN).hex $(BUILD)/$(BIN).bin $(BUILD)/$(BIN).uf2 size - -$(BUILD)/$(BIN).elf: $(OBJS) - @echo LD $@ - @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ - -$(BUILD)/$(BIN).hex: $(BUILD)/$(BIN).elf - @echo OBJCOPY $@ - @$(OBJCOPY) -O ihex $^ $@ - -$(BUILD)/$(BIN).bin: $(BUILD)/$(BIN).elf - @echo OBJCOPY $@ - @$(OBJCOPY) -O binary $^ $@ - -$(BUILD)/$(BIN).uf2: $(BUILD)/$(BIN).bin - @echo BIN2UF2 $@ - @bin2uf2 -i $^ -o $@ - -%.o: - @echo CC $@ - @$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $@)), $(SRCS)) -c -o $@ - -directory: - @$(MKDIR) -p $(BUILD) - -size: $(BUILD)/$(BIN).elf - @echo size: - @$(SIZE) -t $^ - -clean: - @echo clean - @-rm -rf $(BUILD) - --include $(wildcard $(BUILD)/*.d) - +############################################################################## +BUILD = build +BIN = free_dap_rp2040 + +############################################################################## +.PHONY: all directory clean size release + +CC = arm-none-eabi-gcc +OBJCOPY = arm-none-eabi-objcopy +SIZE = arm-none-eabi-size + +ifeq ($(OS), Windows_NT) + MKDIR = gmkdir +else + MKDIR = mkdir +endif + +CFLAGS += -W -Wall --std=gnu11 -Os +CFLAGS += -ffreestanding +CFLAGS += -fno-diagnostics-show-caret +CFLAGS += -fdata-sections -ffunction-sections +CFLAGS += -funsigned-char -funsigned-bitfields +CFLAGS += -mcpu=cortex-m0plus -mthumb +CFLAGS += -MD -MP -MT $(BUILD)/$(*F).o -MF $(BUILD)/$(@F).d + +LDFLAGS += -mcpu=cortex-m0plus -mthumb +LDFLAGS += -nostartfiles +LDFLAGS += -Wl,--gc-sections +LDFLAGS += -Wl,--script=../linker/rp2040.ld + +INCLUDES += \ + -I../include \ + -I../usb \ + -I../../.. \ + -I.. + +SRCS += \ + ../main.c \ + ../uart.c \ + ../usb/usb_rp2040.c \ + ../usb/usb_std.c \ + ../usb/usb_cdc.c \ + ../usb/usb_hid.c \ + ../usb/usb_winusb.c \ + ../usb_descriptors.c \ + ../startup_rp2040.c \ + ../../../dap.c \ + +DEFINES += \ + +CFLAGS += $(INCLUDES) $(DEFINES) + +OBJS = $(addprefix $(BUILD)/, $(notdir %/$(subst .c,.o, $(SRCS)))) + +all: directory $(BUILD)/$(BIN).elf $(BUILD)/$(BIN).hex $(BUILD)/$(BIN).bin $(BUILD)/$(BIN).uf2 release size + +$(BUILD)/$(BIN).elf: $(OBJS) + @echo LD $@ + @$(CC) $(LDFLAGS) $(OBJS) $(LIBS) -o $@ + +$(BUILD)/$(BIN).hex: $(BUILD)/$(BIN).elf + @echo OBJCOPY $@ + @$(OBJCOPY) -O ihex $^ $@ + +$(BUILD)/$(BIN).bin: $(BUILD)/$(BIN).elf + @echo OBJCOPY $@ + @$(OBJCOPY) -O binary $^ $@ + +$(BUILD)/$(BIN).uf2: $(BUILD)/$(BIN).bin + @echo BIN2UF2 $@ + @bin2uf2 -i $^ -o $@ + +%.o: + @echo CC $@ + @$(CC) $(CFLAGS) $(filter %/$(subst .o,.c,$(notdir $@)), $(SRCS)) -c -o $@ + +release: $(BUILD)/$(BIN).uf2 + @echo release + @cp $(BUILD)/$(BIN).uf2 ../../../bin/ + +directory: + @$(MKDIR) -p $(BUILD) + +size: $(BUILD)/$(BIN).elf + @echo size: + @$(SIZE) -t $^ + +clean: + @echo clean + @-rm -rf $(BUILD) + +-include $(wildcard $(BUILD)/*.d) + diff --git a/platform/rp2040/startup_rp2040.c b/platform/rp2040/startup_rp2040.c index 50be8ec..ee9ca35 100644 --- a/platform/rp2040/startup_rp2040.c +++ b/platform/rp2040/startup_rp2040.c @@ -193,5 +193,3 @@ __attribute__((naked, used, noreturn, section(".boot.entry"))) void boot_entry(v __builtin_unreachable(); } - - diff --git a/platform/rp2040/tools/.gitignore b/platform/rp2040/tools/.gitignore index 850f9b1..9c94a45 100644 --- a/platform/rp2040/tools/.gitignore +++ b/platform/rp2040/tools/.gitignore @@ -1,3 +1,3 @@ -bin2uf2 -bin2uf2.exe - +bin2uf2 +bin2uf2.exe + diff --git a/platform/rp2040/usb.h b/platform/rp2040/usb/usb.h similarity index 91% rename from platform/rp2040/usb.h rename to platform/rp2040/usb/usb.h index f5ae07e..fde361a 100644 --- a/platform/rp2040/usb.h +++ b/platform/rp2040/usb/usb.h @@ -9,9 +9,6 @@ #include #include "usb_descriptors.h" -/*- Definitions -------------------------------------------------------------*/ -#define USB_EP_NUM 16 - /*- Prototypes --------------------------------------------------------------*/ void usb_hw_init(void); void usb_attach(void); diff --git a/platform/rp2040/usb_cdc.c b/platform/rp2040/usb/usb_cdc.c similarity index 77% rename from platform/rp2040/usb_cdc.c rename to platform/rp2040/usb/usb_cdc.c index 2d204bb..8ed6ae0 100644 --- a/platform/rp2040/usb_cdc.c +++ b/platform/rp2040/usb/usb_cdc.c @@ -2,10 +2,6 @@ // Copyright (c) 2017-2022, Alex Taradov . All rights reserved. /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include -#include "utils.h" #include "usb.h" #include "usb_std.h" #include "usb_cdc.h" @@ -17,9 +13,7 @@ /*- Prototypes --------------------------------------------------------------*/ static void usb_cdc_send_state_notify(void); -static void usb_cdc_ep_comm_callback(int size); -static void usb_cdc_ep_send_callback(int size); -static void usb_cdc_ep_recv_callback(int size); +static void usb_cdc_ep_comm_callback(void); /*- Variables ---------------------------------------------------------------*/ static usb_cdc_line_coding_t usb_cdc_line_coding = @@ -39,9 +33,9 @@ static bool usb_cdc_comm_busy; //----------------------------------------------------------------------------- void usb_cdc_init(void) { - usb_set_callback(USB_CDC_EP_COMM, usb_cdc_ep_comm_callback); - usb_set_callback(USB_CDC_EP_SEND, usb_cdc_ep_send_callback); - usb_set_callback(USB_CDC_EP_RECV, usb_cdc_ep_recv_callback); + usb_set_send_callback(USB_CDC_EP_COMM, usb_cdc_ep_comm_callback); + usb_set_send_callback(USB_CDC_EP_SEND, usb_cdc_send_callback); + usb_set_recv_callback(USB_CDC_EP_RECV, usb_cdc_recv_callback); usb_cdc_notify_message.request.bmRequestType = USB_IN_TRANSFER | USB_INTERFACE_RECIPIENT | USB_CLASS_REQUEST; @@ -107,25 +101,11 @@ static void usb_cdc_send_state_notify(void) } //----------------------------------------------------------------------------- -static void usb_cdc_ep_comm_callback(int size) +static void usb_cdc_ep_comm_callback(void) { usb_cdc_comm_busy = false; usb_cdc_notify_message.value &= ~ONE_SHOT_STATES; usb_cdc_send_state_notify(); - (void)size; -} - -//----------------------------------------------------------------------------- -static void usb_cdc_ep_send_callback(int size) -{ - usb_cdc_send_callback(); - (void)size; -} - -//----------------------------------------------------------------------------- -static void usb_cdc_ep_recv_callback(int size) -{ - usb_cdc_recv_callback(size); } //----------------------------------------------------------------------------- @@ -146,18 +126,18 @@ bool usb_cdc_handle_request(usb_request_t *request) { int length = request->wLength; - switch ((request->bRequest << 8) | request->bmRequestType) + switch (USB_CMD_VALUE(request)) { case USB_CMD(OUT, INTERFACE, CLASS, CDC_SET_LINE_CODING): { - length = LIMIT(length, sizeof(usb_cdc_line_coding_t)); + length = USB_LIMIT(length, sizeof(usb_cdc_line_coding_t)); usb_control_recv(usb_cdc_set_line_coding_handler); } break; case USB_CMD(IN, INTERFACE, CLASS, CDC_GET_LINE_CODING): { - length = LIMIT(length, sizeof(usb_cdc_line_coding_t)); + length = USB_LIMIT(length, sizeof(usb_cdc_line_coding_t)); usb_control_send((uint8_t *)&usb_cdc_line_coding, length); } break; @@ -182,17 +162,3 @@ bool usb_cdc_handle_request(usb_request_t *request) return true; } - -//----------------------------------------------------------------------------- -WEAK void usb_cdc_control_line_state_update(int line_state) -{ - (void)line_state; -} - -//----------------------------------------------------------------------------- -WEAK void usb_cdc_send_break(int duration) -{ - (void)duration; -} - - diff --git a/platform/rp2040/usb_cdc.h b/platform/rp2040/usb/usb_cdc.h similarity index 97% rename from platform/rp2040/usb_cdc.h rename to platform/rp2040/usb/usb_cdc.h index cef4391..2b68126 100644 --- a/platform/rp2040/usb_cdc.h +++ b/platform/rp2040/usb/usb_cdc.h @@ -5,12 +5,11 @@ #define _USB_CDC_H_ /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include "utils.h" #include "usb_std.h" /*- Definitions -------------------------------------------------------------*/ +#define USB_CDC_BCD_VERSION 0x0110 + enum { USB_CDC_SEND_ENCAPSULATED_COMMAND = 0x00, @@ -144,7 +143,7 @@ enum #define USB_CDC_BREAK_DURATION_INFINITE 0xffff /*- Types -------------------------------------------------------------------*/ -typedef struct PACK +typedef struct USB_PACK { uint8_t bFunctionalLength; uint8_t bDescriptorType; @@ -152,7 +151,7 @@ typedef struct PACK uint16_t bcdCDC; } usb_cdc_header_functional_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bFunctionalLength; uint8_t bDescriptorType; @@ -160,7 +159,7 @@ typedef struct PACK uint8_t bmCapabilities; } usb_cdc_abstract_control_managment_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bFunctionalLength; uint8_t bDescriptorType; @@ -169,7 +168,7 @@ typedef struct PACK uint8_t bDataInterface; } usb_cdc_call_managment_functional_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bFunctionalLength; uint8_t bDescriptorType; @@ -178,7 +177,7 @@ typedef struct PACK uint8_t bSlaveInterface0; } usb_cdc_union_functional_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint32_t dwDTERate; uint8_t bCharFormat; @@ -186,7 +185,7 @@ typedef struct PACK uint8_t bDataBits; } usb_cdc_line_coding_t; -typedef struct PACK +typedef struct USB_PACK { usb_request_t request; uint16_t value; diff --git a/platform/rp2040/usb_hid.c b/platform/rp2040/usb/usb_hid.c similarity index 58% rename from platform/rp2040/usb_hid.c rename to platform/rp2040/usb/usb_hid.c index 3de2993..5f06949 100644 --- a/platform/rp2040/usb_hid.c +++ b/platform/rp2040/usb/usb_hid.c @@ -2,26 +2,18 @@ // Copyright (c) 2019-2022, Alex Taradov . All rights reserved. /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include -#include "utils.h" #include "usb.h" #include "usb_std.h" #include "usb_hid.h" #include "usb_descriptors.h" -/*- Prototypes --------------------------------------------------------------*/ -static void usb_hid_ep_send_callback(int size); -static void usb_hid_ep_recv_callback(int size); - /*- Implementations ---------------------------------------------------------*/ //----------------------------------------------------------------------------- void usb_hid_init(void) { - usb_set_callback(USB_HID_EP_SEND, usb_hid_ep_send_callback); - usb_set_callback(USB_HID_EP_RECV, usb_hid_ep_recv_callback); + usb_set_send_callback(USB_HID_EP_SEND, usb_hid_send_callback); + usb_set_recv_callback(USB_HID_EP_RECV, usb_hid_recv_callback); } //----------------------------------------------------------------------------- @@ -36,29 +28,16 @@ void usb_hid_recv(uint8_t *data, int size) usb_recv(USB_HID_EP_RECV, data, size); } -//----------------------------------------------------------------------------- -static void usb_hid_ep_send_callback(int size) -{ - usb_hid_send_callback(); - (void)size; -} - -//----------------------------------------------------------------------------- -static void usb_hid_ep_recv_callback(int size) -{ - usb_hid_recv_callback(size); -} - //----------------------------------------------------------------------------- bool usb_hid_handle_request(usb_request_t *request) { int length = request->wLength; - switch ((request->bRequest << 8) | request->bmRequestType) + switch (USB_CMD_VALUE(request)) { case USB_CMD(IN, INTERFACE, STANDARD, GET_DESCRIPTOR): { - length = LIMIT(length, sizeof(usb_hid_report_descriptor)); + length = USB_LIMIT(length, sizeof(usb_hid_report_descriptor)); usb_control_send((uint8_t *)usb_hid_report_descriptor, length); } break; @@ -69,4 +48,3 @@ bool usb_hid_handle_request(usb_request_t *request) return true; } - diff --git a/platform/rp2040/usb_hid.h b/platform/rp2040/usb/usb_hid.h similarity index 93% rename from platform/rp2040/usb_hid.h rename to platform/rp2040/usb/usb_hid.h index c1955fc..17e838d 100644 --- a/platform/rp2040/usb_hid.h +++ b/platform/rp2040/usb/usb_hid.h @@ -5,9 +5,6 @@ #define _USB_HID_H_ /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include "utils.h" #include "usb_std.h" /*- Definitions -------------------------------------------------------------*/ @@ -24,7 +21,7 @@ enum }; /*- Types -------------------------------------------------------------------*/ -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -45,4 +42,3 @@ void usb_hid_send_callback(void); void usb_hid_recv_callback(int size); #endif // _USB_HID_H_ - diff --git a/platform/rp2040/usb.c b/platform/rp2040/usb/usb_rp2040.c similarity index 98% rename from platform/rp2040/usb.c rename to platform/rp2040/usb/usb_rp2040.c index 630f060..5afa79f 100644 --- a/platform/rp2040/usb.c +++ b/platform/rp2040/usb/usb_rp2040.c @@ -2,16 +2,13 @@ // Copyright (c) 2022, Alex Taradov . All rights reserved. /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include #include "rp2040.h" -#include "utils.h" #include "usb.h" #include "usb_std.h" #include "usb_descriptors.h" /*- Definitions -------------------------------------------------------------*/ +#define USB_EP_NUM 16 #define USB_DPRAM_SIZE 4096 #define USB_DPRAM ((usb_dpram_t *)USBCTRL_DPRAM_BASE) #define USB_DPRAM_FIXED_SIZE 0x100 @@ -268,7 +265,7 @@ void usb_control_send(uint8_t *data, int size) { while (size) { - int transfer_size = LIMIT(size, usb_device_descriptor.bMaxPacketSize0); + int transfer_size = USB_LIMIT(size, usb_device_descriptor.bMaxPacketSize0); for (int i = 0; i < transfer_size; i++) usb_ep[0].in_buf[i] = data[i]; @@ -364,5 +361,3 @@ void usb_task(void) USBCTRL_REGS->BUFF_STATUS = status; } } - - diff --git a/platform/rp2040/usb_std.c b/platform/rp2040/usb/usb_std.c similarity index 79% rename from platform/rp2040/usb_std.c rename to platform/rp2040/usb/usb_std.c index cc41d92..c951e39 100644 --- a/platform/rp2040/usb_std.c +++ b/platform/rp2040/usb/usb_std.c @@ -2,16 +2,19 @@ // Copyright (c) 2016-2022, Alex Taradov . All rights reserved. /*- Includes ----------------------------------------------------------------*/ -#include -#include -#include -#include "utils.h" #include "usb.h" #include "usb_std.h" #include "usb_descriptors.h" +/*- Definitions -------------------------------------------------------------*/ +#define USB_EP_NUM 16 + /*- Types -------------------------------------------------------------------*/ -typedef void (*usb_ep_callback_t)(int size); +typedef struct +{ + void (*send)(void); + void (*recv)(int size); +} usb_ep_callback_t; /*- Variables ---------------------------------------------------------------*/ static usb_ep_callback_t usb_ep_callbacks[USB_EP_NUM]; @@ -22,30 +25,32 @@ static usb_ep_callback_t usb_ep_callbacks[USB_EP_NUM]; void usb_init(void) { for (int i = 0; i < USB_EP_NUM; i++) - usb_ep_callbacks[i] = NULL; + { + usb_ep_callbacks[i].send = NULL; + usb_ep_callbacks[i].recv = NULL; + } usb_hw_init(); } //----------------------------------------------------------------------------- -void usb_set_callback(int ep, void (*callback)(int size)) +void usb_set_send_callback(int ep, void (*callback)(void)) { - usb_ep_callbacks[ep] = callback; + usb_ep_callbacks[ep].send = callback; } //----------------------------------------------------------------------------- -WEAK bool usb_class_handle_request(usb_request_t *request) +void usb_set_recv_callback(int ep, void (*callback)(int size)) { - (void)request; - return false; + usb_ep_callbacks[ep].recv = callback; } //----------------------------------------------------------------------------- bool usb_handle_standard_request(usb_request_t *request) { - static int usb_config = 0; + static uint8_t usb_config = 0; - switch ((request->bRequest << 8) | request->bmRequestType) + switch (USB_CMD_VALUE(request)) { case USB_CMD(IN, DEVICE, STANDARD, GET_DESCRIPTOR): { @@ -55,22 +60,20 @@ bool usb_handle_standard_request(usb_request_t *request) if (USB_DEVICE_DESCRIPTOR == type) { - length = LIMIT(length, usb_device_descriptor.bLength); + length = USB_LIMIT(length, usb_device_descriptor.bLength); usb_control_send((uint8_t *)&usb_device_descriptor, length); } else if (USB_CONFIGURATION_DESCRIPTOR == type) { - length = LIMIT(length, usb_configuration_hierarchy.configuration.wTotalLength); - + length = USB_LIMIT(length, sizeof(usb_configuration_hierarchy_t)); usb_control_send((uint8_t *)&usb_configuration_hierarchy, length); } else if (USB_STRING_DESCRIPTOR == type) { if (0 == index) { - length = LIMIT(length, usb_string_descriptor_zero.bLength); - + length = USB_LIMIT(length, usb_string_descriptor_zero.bLength); usb_control_send((uint8_t *)&usb_string_descriptor_zero, length); } else if (index < USB_STR_COUNT) @@ -89,7 +92,7 @@ bool usb_handle_standard_request(usb_request_t *request) buf[3 + i*2] = 0; } - length = LIMIT(length, size); + length = USB_LIMIT(length, size); usb_control_send(buf, length); } @@ -98,6 +101,13 @@ bool usb_handle_standard_request(usb_request_t *request) return false; } } +#ifdef USB_ENABLE_BOS + else if (USB_BINARY_OBJECT_STORE_DESCRIPTOR == type) + { + length = USB_LIMIT(length, sizeof(usb_bos_hierarchy_t)); + usb_control_send((uint8_t *)&usb_bos_hierarchy, length); + } +#endif else { return false; @@ -136,8 +146,7 @@ bool usb_handle_standard_request(usb_request_t *request) case USB_CMD(IN, DEVICE, STANDARD, GET_CONFIGURATION): { - uint8_t config = usb_config; - usb_control_send(&config, sizeof(config)); + usb_control_send(&usb_config, sizeof(uint8_t)); } break; case USB_CMD(IN, DEVICE, STANDARD, GET_STATUS): @@ -218,8 +227,13 @@ bool usb_handle_standard_request(usb_request_t *request) default: { - if (!usb_class_handle_request(request)) - return false; + for (int i = 0; i < USB_ARRAY_SIZE(usb_class_handlers); i++) + { + if (usb_class_handlers[i](request)) + return true; + } + + return false; } break; } @@ -229,14 +243,13 @@ bool usb_handle_standard_request(usb_request_t *request) //----------------------------------------------------------------------------- void usb_send_callback(int ep) { - if (usb_ep_callbacks[ep]) - usb_ep_callbacks[ep](0); + if (usb_ep_callbacks[ep].send) + usb_ep_callbacks[ep].send(); } //----------------------------------------------------------------------------- void usb_recv_callback(int ep, int size) { - if (usb_ep_callbacks[ep]) - usb_ep_callbacks[ep](size); + if (usb_ep_callbacks[ep].recv) + usb_ep_callbacks[ep].recv(size); } - diff --git a/platform/rp2040/usb_std.h b/platform/rp2040/usb/usb_std.h similarity index 71% rename from platform/rp2040/usb_std.h rename to platform/rp2040/usb/usb_std.h index 55a138c..bd6fd71 100644 --- a/platform/rp2040/usb_std.h +++ b/platform/rp2040/usb/usb_std.h @@ -5,9 +5,11 @@ #define _USB_STD_H_ /*- Includes ----------------------------------------------------------------*/ +#include +#include #include #include -#include "utils.h" +#include /*- Definitions -------------------------------------------------------------*/ enum @@ -91,7 +93,31 @@ enum enum { - USB_DEVICE_CLASS_MISCELLANEOUS = 0xef, + USB_ATTRIBUTE_REMOTE_WAKEUP = 0x20, + USB_ATTRIBUTE_SELF_POWERED = 0x40, + USB_ATTRIBUTE_BUS_POWERED = 0x80, +}; + +enum +{ + USB_DEVICE_CAPABILITY_WIRELESS_USB = 1, + USB_DEVICE_CAPABILITY_USB_2_0_EXTENSION = 2, + USB_DEVICE_CAPABILITY_SUPERSPEED_USB = 3, + USB_DEVICE_CAPABILITY_CONTAINER_ID = 4, + USB_DEVICE_CAPABILITY_PLATFORM = 5, + USB_DEVICE_CAPABILITY_POWER_DELIVERY = 6, + USB_DEVICE_CAPABILITY_BATTERY_INFO = 7, + USB_DEVICE_CAPABILITY_PD_CONSUMER_PORT = 8, + USB_DEVICE_CAPABILITY_PD_PROVIDER_PORT = 9, + USB_DEVICE_CAPABILITY_SUPERSPEED_PLUS = 10, + USB_DEVICE_CAPABILITY_PRECISION_TIME_MEASUREMENT = 11, + USB_DEVICE_CAPABILITY_WIRELESS_USB_EXT = 12, +}; + +enum +{ + USB_DEVICE_CLASS_MISCELLANEOUS = 0xef, + USB_DEVICE_CLASS_VENDOR_SPECIFIC = 0xff, }; enum @@ -105,13 +131,21 @@ enum }; #define USB_CTRL_EP_SIZE 64 +#define USB_LANGID_ENGLISH 0x0409 // English (United States) +#define USB_MAX_POWER(ma) ((ma) / 2) + +#define USB_PACK __attribute__((packed)) +#define USB_LIMIT(a, b) (((int)(a) > (int)(b)) ? (int)(b) : (int)(a)) +#define USB_ARRAY_SIZE(x) ((int)(sizeof(x) / sizeof(0[x]))) + +#define USB_CMD_VALUE(req) (((req)->bRequest << 8) | (req)->bmRequestType) #define USB_CMD(dir, rcpt, type, cmd) \ ((USB_##cmd << 8) | (USB_##dir##_TRANSFER << 7) | \ (USB_##type##_REQUEST << 5) | (USB_##rcpt##_RECIPIENT << 0)) /*- Types -------------------------------------------------------------------*/ -typedef struct PACK +typedef struct USB_PACK { uint8_t bmRequestType; uint8_t bRequest; @@ -120,13 +154,13 @@ typedef struct PACK uint16_t wLength; } usb_request_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; } usb_descriptor_header_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -144,7 +178,7 @@ typedef struct PACK uint8_t bNumConfigurations; } usb_device_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -156,7 +190,7 @@ typedef struct PACK uint8_t bMaxPower; } usb_configuration_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -169,7 +203,7 @@ typedef struct PACK uint8_t iInterface; } usb_interface_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -179,21 +213,21 @@ typedef struct PACK uint8_t bInterval; } usb_endpoint_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; uint16_t wLANGID; } usb_string_descriptor_zero_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; uint16_t bString; } usb_string_descriptor_t; -typedef struct PACK +typedef struct USB_PACK { uint8_t bLength; uint8_t bDescriptorType; @@ -205,12 +239,22 @@ typedef struct PACK uint8_t iFunction; } usb_interface_association_descriptor_t; +typedef struct USB_PACK +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint16_t wTotalLength; + uint8_t bNumDeviceCaps; +} usb_binary_object_store_descriptor_t; + +typedef bool (*usb_class_handler_t)(usb_request_t *request); + /*- Prototypes --------------------------------------------------------------*/ void usb_init(void); -void usb_set_callback(int ep, void (*callback)(int size)); +void usb_set_send_callback(int ep, void (*callback)(void)); +void usb_set_recv_callback(int ep, void (*callback)(int size)); bool usb_handle_standard_request(usb_request_t *request); void usb_send_callback(int ep); void usb_recv_callback(int ep, int size); #endif // _USB_STD_H_ - diff --git a/platform/rp2040/usb/usb_winusb.c b/platform/rp2040/usb/usb_winusb.c new file mode 100644 index 0000000..6bffd09 --- /dev/null +++ b/platform/rp2040/usb/usb_winusb.c @@ -0,0 +1,37 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Alex Taradov . All rights reserved. + +/*- Includes ----------------------------------------------------------------*/ +#include "usb.h" +#include "usb_std.h" +#include "usb_winusb.h" +#include "usb_descriptors.h" + +/*- Implementations ---------------------------------------------------------*/ + +//----------------------------------------------------------------------------- +bool usb_winusb_handle_request(usb_request_t *request) +{ + int length = request->wLength; + + switch (USB_CMD_VALUE(request)) + { + case USB_CMD(IN, DEVICE, VENDOR, WINUSB_VENDOR_CODE): + { + if (USB_WINUSB_DESCRIPTOR_INDEX == request->wIndex) + { + length = USB_LIMIT(length, sizeof(usb_msos_descriptor_set_t)); + usb_control_send((uint8_t *)&usb_msos_descriptor_set, length); + } + else + { + return false; + } + } break; + + default: + return false; + } + + return true; +} diff --git a/platform/rp2040/usb/usb_winusb.h b/platform/rp2040/usb/usb_winusb.h new file mode 100644 index 0000000..f09b9c5 --- /dev/null +++ b/platform/rp2040/usb/usb_winusb.h @@ -0,0 +1,153 @@ +// SPDX-License-Identifier: BSD-3-Clause +// Copyright (c) 2022, Alex Taradov . All rights reserved. + +#ifndef _USB_WINUSB_H_ +#define _USB_WINUSB_H_ + +// WinUSB device information is stored in the Windows registry at: +// HKEY_LOCAL_MACHINE\System\CurrentControlSet\Enum\USB\\\Device Parameters + +/*- Includes ----------------------------------------------------------------*/ +#include "usb_std.h" + +/*- Definitions -------------------------------------------------------------*/ +#define USB_WINUSB_VENDOR_CODE 0x20 + +#define USB_WINUSB_WINDOWS_VERSION 0x06030000 // Windows 8.1 + +#define USB_WINUSB_PLATFORM_CAPABILITY_ID \ + { 0xdf, 0x60, 0xdd, 0xd8, 0x89, 0x45, 0xc7, 0x4c, \ + 0x9c, 0xd2, 0x65, 0x9d, 0x9e, 0x64, 0x8a, 0x9f } + +enum // WinUSB Microsoft OS 2.0 descriptor request codes +{ + USB_WINUSB_DESCRIPTOR_INDEX = 0x07, + USB_WINUSB_SET_ALT_ENUMERATION = 0x08, +}; + +enum // wDescriptorType +{ + USB_WINUSB_SET_HEADER_DESCRIPTOR = 0x00, + USB_WINUSB_SUBSET_HEADER_CONFIGURATION = 0x01, + USB_WINUSB_SUBSET_HEADER_FUNCTION = 0x02, + USB_WINUSB_FEATURE_COMPATBLE_ID = 0x03, + USB_WINUSB_FEATURE_REG_PROPERTY = 0x04, + USB_WINUSB_FEATURE_MIN_RESUME_TIME = 0x05, + USB_WINUSB_FEATURE_MODEL_ID = 0x06, + USB_WINUSB_FEATURE_CCGP_DEVICE = 0x07, + USB_WINUSB_FEATURE_VENDOR_REVISION = 0x08, +}; + +enum // wPropertyDataType +{ + USB_WINUSB_PROPERTY_DATA_TYPE_SZ = 1, + USB_WINUSB_PROPERTY_DATA_TYPE_EXPAND_SZ = 2, + USB_WINUSB_PROPERTY_DATA_TYPE_BINARY = 3, + USB_WINUSB_PROPERTY_DATA_TYPE_DWORD_LITTLE_ENDIAN = 4, + USB_WINUSB_PROPERTY_DATA_TYPE_DWORD_BIG_ENDIAN = 5, + USB_WINUSB_PROPERTY_DATA_TYPE_LINK = 6, + USB_WINUSB_PROPERTY_DATA_TYPE_MULTI_SZ = 7, +}; + +/*- Types -------------------------------------------------------------------*/ +typedef struct USB_PACK +{ + uint8_t bLength; + uint8_t bDescriptorType; + uint8_t bDevCapabilityType; + uint8_t bReserved; + uint8_t PlatformCapabilityUUID[16]; + uint32_t dwWindowsVersion; + uint16_t wMSOSDescriptorSetTotalLength; + uint8_t bMS_VendorCode; + uint8_t bAltEnumCode; +} usb_winusb_capability_descriptor_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint32_t dwWindowsVersion; + uint16_t wDescriptorSetTotalLength; +} usb_winusb_set_header_descriptor_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t bConfigurationValue; + uint8_t bReserved; + uint16_t wTotalLength; +} usb_winusb_subset_header_configuration_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t bFirstInterface; + uint8_t bReserved; + uint16_t wSubsetLength; +} usb_winusb_subset_header_function_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t CompatibleID[8]; + uint8_t SubCompatibleID[8]; +} usb_winusb_feature_compatble_id_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint16_t wPropertyDataType; + //uint16_t wPropertyNameLength; + //uint8_t PropertyName[...]; + //uint16_t wPropertyDataLength + //uint8_t PropertyData[...]; +} usb_winusb_feature_reg_property_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint16_t wPropertyDataType; + uint16_t wPropertyNameLength; + uint8_t PropertyName[42]; + uint16_t wPropertyDataLength; + uint8_t PropertyData[80]; +} usb_winusb_feature_reg_property_guids_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t bResumeRecoveryTime; + uint8_t bResumeSignalingTime; +} usb_winusb_feature_min_resume_time_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint8_t ModelID[16]; +} usb_winusb_feature_model_id_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; +} usb_winusb_feature_ccgp_device_t; + +typedef struct USB_PACK +{ + uint16_t wLength; + uint16_t wDescriptorType; + uint16_t VendorRevision; +} usb_winusb_feature_vendor_revision_t; + +/*- Prototypes --------------------------------------------------------------*/ +bool usb_winusb_handle_request(usb_request_t *request); + +#endif // _USB_WINUSB_H_ diff --git a/platform/rp2040/usb_descriptors.c b/platform/rp2040/usb_descriptors.c index dcec73c..ecfb8cd 100644 --- a/platform/rp2040/usb_descriptors.c +++ b/platform/rp2040/usb_descriptors.c @@ -3,7 +3,6 @@ /*- Includes ----------------------------------------------------------------*/ #include -#include "usb.h" #include "usb_descriptors.h" /*- Variables ---------------------------------------------------------------*/ @@ -11,14 +10,14 @@ const alignas(4) usb_device_descriptor_t usb_device_descriptor = { .bLength = sizeof(usb_device_descriptor_t), .bDescriptorType = USB_DEVICE_DESCRIPTOR, - .bcdUSB = 0x0200, + .bcdUSB = USB_BCD_VERSION, .bDeviceClass = USB_DEVICE_CLASS_MISCELLANEOUS, .bDeviceSubClass = USB_DEVICE_SUBCLASS_COMMON, .bDeviceProtocol = USB_DEVICE_PROTOCOL_INTERFACE_ASSOCIATION, .bMaxPacketSize0 = USB_CTRL_EP_SIZE, .idVendor = 0x6666, - .idProduct = 0x6600, - .bcdDevice = 0x0101, + .idProduct = 0x9930, + .bcdDevice = 0x0100, .iManufacturer = USB_STR_MANUFACTURER, .iProduct = USB_STR_PRODUCT, .iSerialNumber = USB_STR_SERIAL_NUMBER, @@ -32,24 +31,25 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = .bLength = sizeof(usb_configuration_descriptor_t), .bDescriptorType = USB_CONFIGURATION_DESCRIPTOR, .wTotalLength = sizeof(usb_configuration_hierarchy_t), - .bNumInterfaces = 3, + .bNumInterfaces = USB_INTF_COUNT, .bConfigurationValue = 1, .iConfiguration = 0, - .bmAttributes = 0x80, - .bMaxPower = 250, // 500 mA + .bmAttributes = USB_ATTRIBUTE_BUS_POWERED, + .bMaxPower = USB_MAX_POWER(500), }, + // CMSIS-DAP v1 .hid_interface = { .bLength = sizeof(usb_interface_descriptor_t), .bDescriptorType = USB_INTERFACE_DESCRIPTOR, - .bInterfaceNumber = 0, + .bInterfaceNumber = USB_INTF_HID, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_HID_DEVICE_CLASS, .bInterfaceSubClass = 0, .bInterfaceProtocol = 0, - .iInterface = USB_STR_CMSIS_DAP, + .iInterface = USB_STR_CMSIS_DAP_V1, }, .hid = @@ -83,11 +83,46 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = .bInterval = 1, }, + // CMSIS-DAP v2 + .bulk_interface = + { + .bLength = sizeof(usb_interface_descriptor_t), + .bDescriptorType = USB_INTERFACE_DESCRIPTOR, + .bInterfaceNumber = USB_INTF_BULK, + .bAlternateSetting = 0, + .bNumEndpoints = 2, + .bInterfaceClass = USB_DEVICE_CLASS_VENDOR_SPECIFIC, + .bInterfaceSubClass = 0, + .bInterfaceProtocol = 0, + .iInterface = USB_STR_CMSIS_DAP_V2, + }, + + .bulk_ep_out = + { + .bLength = sizeof(usb_endpoint_descriptor_t), + .bDescriptorType = USB_ENDPOINT_DESCRIPTOR, + .bEndpointAddress = USB_OUT_ENDPOINT | USB_BULK_EP_RECV, + .bmAttributes = USB_BULK_ENDPOINT, + .wMaxPacketSize = 64, + .bInterval = 0, + }, + + .bulk_ep_in = + { + .bLength = sizeof(usb_endpoint_descriptor_t), + .bDescriptorType = USB_ENDPOINT_DESCRIPTOR, + .bEndpointAddress = USB_IN_ENDPOINT | USB_BULK_EP_SEND, + .bmAttributes = USB_BULK_ENDPOINT, + .wMaxPacketSize = 64, + .bInterval = 0, + }, + + // VCP .iad = { .bLength = sizeof(usb_interface_association_descriptor_t), .bDescriptorType = USB_INTERFACE_ASSOCIATION_DESCRIPTOR, - .bFirstInterface = 1, + .bFirstInterface = USB_INTF_CDC_COMM, .bInterfaceCount = 2, .bFunctionClass = USB_CDC_COMM_CLASS, .bFunctionSubClass = USB_CDC_ACM_SUBCLASS, @@ -99,7 +134,7 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = { .bLength = sizeof(usb_interface_descriptor_t), .bDescriptorType = USB_INTERFACE_DESCRIPTOR, - .bInterfaceNumber = 1, + .bInterfaceNumber = USB_INTF_CDC_COMM, .bAlternateSetting = 0, .bNumEndpoints = 1, .bInterfaceClass = USB_CDC_COMM_CLASS, @@ -113,7 +148,7 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = .bFunctionalLength = sizeof(usb_cdc_header_functional_descriptor_t), .bDescriptorType = USB_CS_INTERFACE_DESCRIPTOR, .bDescriptorSubtype = USB_CDC_HEADER_SUBTYPE, - .bcdCDC = 0x0110, + .bcdCDC = USB_CDC_BCD_VERSION, }, .cdc_acm = @@ -130,7 +165,7 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = .bDescriptorType = USB_CS_INTERFACE_DESCRIPTOR, .bDescriptorSubtype = USB_CDC_CALL_MGMT_SUBTYPE, .bmCapabilities = USB_CDC_CALL_MGMT_OVER_DCI, - .bDataInterface = 2, + .bDataInterface = USB_INTF_CDC_DATA, }, .cdc_union = @@ -138,8 +173,8 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = .bFunctionalLength = sizeof(usb_cdc_union_functional_descriptor_t), .bDescriptorType = USB_CS_INTERFACE_DESCRIPTOR, .bDescriptorSubtype = USB_CDC_UNION_SUBTYPE, - .bMasterInterface = 1, - .bSlaveInterface0 = 2, + .bMasterInterface = USB_INTF_CDC_COMM, + .bSlaveInterface0 = USB_INTF_CDC_DATA, }, .ep_comm = @@ -156,7 +191,7 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = { .bLength = sizeof(usb_interface_descriptor_t), .bDescriptorType = USB_INTERFACE_DESCRIPTOR, - .bInterfaceNumber = 2, + .bInterfaceNumber = USB_INTF_CDC_DATA, .bAlternateSetting = 0, .bNumEndpoints = 2, .bInterfaceClass = USB_CDC_DATA_CLASS, @@ -186,6 +221,76 @@ const alignas(4) usb_configuration_hierarchy_t usb_configuration_hierarchy = }, }; +const alignas(4) usb_bos_hierarchy_t usb_bos_hierarchy = +{ + .bos = + { + .bLength = sizeof(usb_binary_object_store_descriptor_t), + .bDescriptorType = USB_BINARY_OBJECT_STORE_DESCRIPTOR, + .wTotalLength = sizeof(usb_bos_hierarchy_t), + .bNumDeviceCaps = 1, + }, + + .winusb = + { + .bLength = sizeof(usb_winusb_capability_descriptor_t), + .bDescriptorType = USB_DEVICE_CAPABILITY_DESCRIPTOR, + .bDevCapabilityType = USB_DEVICE_CAPABILITY_PLATFORM, + .bReserved = 0, + .PlatformCapabilityUUID = USB_WINUSB_PLATFORM_CAPABILITY_ID, + .dwWindowsVersion = USB_WINUSB_WINDOWS_VERSION, + .wMSOSDescriptorSetTotalLength = sizeof(usb_msos_descriptor_set_t), + .bMS_VendorCode = USB_WINUSB_VENDOR_CODE, + .bAltEnumCode = 0, + }, +}; + +const alignas(4) usb_msos_descriptor_set_t usb_msos_descriptor_set = +{ + .header = + { + .wLength = sizeof(usb_winusb_set_header_descriptor_t), + .wDescriptorType = USB_WINUSB_SET_HEADER_DESCRIPTOR, + .dwWindowsVersion = USB_WINUSB_WINDOWS_VERSION, + .wDescriptorSetTotalLength = sizeof(usb_msos_descriptor_set_t), + }, + + .subset = + { + .header = { + .wLength = sizeof(usb_winusb_subset_header_function_t), + .wDescriptorType = USB_WINUSB_SUBSET_HEADER_FUNCTION, + .bFirstInterface = USB_INTF_BULK, + .bReserved = 0, + .wSubsetLength = sizeof(usb_msos_descriptor_subset_t), + }, + + .comp_id = + { + .wLength = sizeof(usb_winusb_feature_compatble_id_t), + .wDescriptorType = USB_WINUSB_FEATURE_COMPATBLE_ID, + .CompatibleID = "WINUSB\0\0", + .SubCompatibleID = { 0 }, + }, + + .property = + { + .wLength = sizeof(usb_winusb_feature_reg_property_guids_t), + .wDescriptorType = USB_WINUSB_FEATURE_REG_PROPERTY, + .wPropertyDataType = USB_WINUSB_PROPERTY_DATA_TYPE_MULTI_SZ, + .wPropertyNameLength = sizeof(usb_msos_descriptor_set.subset.property.PropertyName), + .PropertyName = { + 'D',0,'e',0,'v',0,'i',0,'c',0,'e',0,'I',0,'n',0,'t',0,'e',0,'r',0,'f',0,'a',0,'c',0,'e',0, + 'G',0,'U',0,'I',0,'D',0,'s',0, 0, 0 }, + .wPropertyDataLength = sizeof(usb_msos_descriptor_set.subset.property.PropertyData), + .PropertyData = { + '{',0,'C',0,'D',0,'B',0,'3',0,'B',0,'5',0,'A',0,'D',0,'-',0,'2',0,'9',0,'3',0,'B',0,'-',0, + '4',0,'6',0,'6',0,'3',0,'-',0,'A',0,'A',0,'3',0,'6',0,'-',0,'1',0,'A',0,'A',0,'E',0,'4',0, + '6',0,'4',0,'6',0,'3',0,'7',0,'7',0,'6',0,'}',0, 0, 0, 0, 0 }, + }, + }, +}; + const alignas(4) uint8_t usb_hid_report_descriptor[28] = { 0x05, 0x01, // Usage Page (Generic Desktop Ctrls) @@ -206,20 +311,26 @@ const alignas(4) uint8_t usb_hid_report_descriptor[28] = const alignas(4) usb_string_descriptor_zero_t usb_string_descriptor_zero = { - .bLength = sizeof(usb_string_descriptor_zero_t), - .bDescriptorType = USB_STRING_DESCRIPTOR, - .wLANGID = 0x0409, // English (United States) + .bLength = sizeof(usb_string_descriptor_zero_t), + .bDescriptorType = USB_STRING_DESCRIPTOR, + .wLANGID = USB_LANGID_ENGLISH, }; -char usb_serial_number[16]; - const char *usb_strings[] = { [USB_STR_MANUFACTURER] = "Alex Taradov", [USB_STR_PRODUCT] = "Combined VCP and CMSIS-DAP Adapter", [USB_STR_COM_PORT] = "Virtual COM-Port", - [USB_STR_CMSIS_DAP] = "CMSIS-DAP Adapter", + [USB_STR_CMSIS_DAP_V1] = "CMSIS-DAP v1 Adapter", + [USB_STR_CMSIS_DAP_V2] = "CMSIS-DAP v2 Adapter", [USB_STR_SERIAL_NUMBER] = usb_serial_number, }; +const usb_class_handler_t usb_class_handlers[3] = +{ + usb_hid_handle_request, + usb_cdc_handle_request, + usb_winusb_handle_request, +}; +char usb_serial_number[16]; diff --git a/platform/rp2040/usb_descriptors.h b/platform/rp2040/usb_descriptors.h index dad337a..fbb29a0 100644 --- a/platform/rp2040/usb_descriptors.h +++ b/platform/rp2040/usb_descriptors.h @@ -5,40 +5,61 @@ #define _USB_DESCRIPTORS_H_ /*- Includes ----------------------------------------------------------------*/ -#include "usb.h" #include "usb_std.h" #include "usb_cdc.h" #include "usb_hid.h" +#include "usb_winusb.h" /*- Definitions -------------------------------------------------------------*/ +#define USB_ENABLE_BOS +#define USB_BCD_VERSION 0x0210 + enum { USB_STR_ZERO, USB_STR_MANUFACTURER, USB_STR_PRODUCT, - USB_STR_COM_PORT, - USB_STR_CMSIS_DAP, USB_STR_SERIAL_NUMBER, + USB_STR_CMSIS_DAP_V1, + USB_STR_CMSIS_DAP_V2, + USB_STR_COM_PORT, USB_STR_COUNT, }; enum { - USB_HID_EP_SEND = 1, - USB_HID_EP_RECV = 2, - USB_CDC_EP_COMM = 3, - USB_CDC_EP_SEND = 4, - USB_CDC_EP_RECV = 5, + USB_HID_EP_SEND = 1, + USB_HID_EP_RECV = 2, + USB_BULK_EP_RECV = 3, + USB_BULK_EP_SEND = 4, + USB_CDC_EP_COMM = 5, + USB_CDC_EP_SEND = 6, + USB_CDC_EP_RECV = 7, +}; + +enum +{ + USB_INTF_HID, + USB_INTF_BULK, + USB_INTF_CDC_COMM, + USB_INTF_CDC_DATA, + USB_INTF_COUNT, }; /*- Types -------------------------------------------------------------------*/ -typedef struct PACK +typedef struct USB_PACK { usb_configuration_descriptor_t configuration; + usb_interface_descriptor_t hid_interface; usb_hid_descriptor_t hid; usb_endpoint_descriptor_t hid_ep_in; usb_endpoint_descriptor_t hid_ep_out; + + usb_interface_descriptor_t bulk_interface; + usb_endpoint_descriptor_t bulk_ep_out; + usb_endpoint_descriptor_t bulk_ep_in; + usb_interface_association_descriptor_t iad; usb_interface_descriptor_t interface_comm; usb_cdc_header_functional_descriptor_t cdc_header; @@ -51,14 +72,34 @@ typedef struct PACK usb_endpoint_descriptor_t ep_out; } usb_configuration_hierarchy_t; +typedef struct USB_PACK +{ + usb_binary_object_store_descriptor_t bos; + usb_winusb_capability_descriptor_t winusb; +} usb_bos_hierarchy_t; + +typedef struct USB_PACK +{ + usb_winusb_subset_header_function_t header; + usb_winusb_feature_compatble_id_t comp_id; + usb_winusb_feature_reg_property_guids_t property; +} usb_msos_descriptor_subset_t; + +typedef struct USB_PACK +{ + usb_winusb_set_header_descriptor_t header; + usb_msos_descriptor_subset_t subset; +} usb_msos_descriptor_set_t; + //----------------------------------------------------------------------------- extern const usb_device_descriptor_t usb_device_descriptor; extern const usb_configuration_hierarchy_t usb_configuration_hierarchy; +extern const usb_bos_hierarchy_t usb_bos_hierarchy; +extern const usb_msos_descriptor_set_t usb_msos_descriptor_set; extern const uint8_t usb_hid_report_descriptor[28]; extern const usb_string_descriptor_zero_t usb_string_descriptor_zero; extern const char *usb_strings[]; +extern const usb_class_handler_t usb_class_handlers[3]; extern char usb_serial_number[16]; #endif // _USB_DESCRIPTORS_H_ - - diff --git a/platform/rp2040/utils.h b/platform/rp2040/utils.h deleted file mode 100644 index 6199cdd..0000000 --- a/platform/rp2040/utils.h +++ /dev/null @@ -1,14 +0,0 @@ -// SPDX-License-Identifier: BSD-3-Clause -// Copyright (c) 2016-2022, Alex Taradov . All rights reserved. - -#ifndef _UTILS_H_ -#define _UTILS_H_ - -/*- Definitions -------------------------------------------------------------*/ -#define PACK __attribute__((packed)) -#define WEAK __attribute__((weak)) -#define INLINE static inline __attribute__((always_inline)) -#define LIMIT(a, b) (((int)(a) > (int)(b)) ? (int)(b) : (int)(a)) - -#endif // _UTILS_H_ -