Added CMSIS-DAP v2 support to RP2040 port + some USB code refactoring
This commit is contained in:
parent
61d9fe21be
commit
a62a163689
@ -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;
|
||||
}
|
||||
|
||||
|
||||
|
||||
2
platform/rp2040/make/.gitignore
vendored
2
platform/rp2040/make/.gitignore
vendored
@ -1 +1 @@
|
||||
build/
|
||||
build/
|
||||
|
||||
@ -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)
|
||||
|
||||
|
||||
@ -193,5 +193,3 @@ __attribute__((naked, used, noreturn, section(".boot.entry"))) void boot_entry(v
|
||||
|
||||
__builtin_unreachable();
|
||||
}
|
||||
|
||||
|
||||
|
||||
6
platform/rp2040/tools/.gitignore
vendored
6
platform/rp2040/tools/.gitignore
vendored
@ -1,3 +1,3 @@
|
||||
bin2uf2
|
||||
bin2uf2.exe
|
||||
|
||||
bin2uf2
|
||||
bin2uf2.exe
|
||||
|
||||
|
||||
@ -9,9 +9,6 @@
|
||||
#include <stdbool.h>
|
||||
#include "usb_descriptors.h"
|
||||
|
||||
/*- Definitions -------------------------------------------------------------*/
|
||||
#define USB_EP_NUM 16
|
||||
|
||||
/*- Prototypes --------------------------------------------------------------*/
|
||||
void usb_hw_init(void);
|
||||
void usb_attach(void);
|
||||
@ -2,10 +2,6 @@
|
||||
// Copyright (c) 2017-2022, Alex Taradov <alex@taradov.com>. All rights reserved.
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdalign.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
|
||||
@ -5,12 +5,11 @@
|
||||
#define _USB_CDC_H_
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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;
|
||||
@ -2,26 +2,18 @@
|
||||
// Copyright (c) 2019-2022, Alex Taradov <alex@taradov.com>. All rights reserved.
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdalign.h>
|
||||
#include <string.h>
|
||||
#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;
|
||||
}
|
||||
|
||||
@ -5,9 +5,6 @@
|
||||
#define _USB_HID_H_
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#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_
|
||||
|
||||
@ -2,16 +2,13 @@
|
||||
// Copyright (c) 2022, Alex Taradov <alex@taradov.com>. All rights reserved.
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <string.h>
|
||||
#include <stdbool.h>
|
||||
#include <stdalign.h>
|
||||
#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;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
@ -2,16 +2,19 @@
|
||||
// Copyright (c) 2016-2022, Alex Taradov <alex@taradov.com>. All rights reserved.
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdbool.h>
|
||||
#include <stdalign.h>
|
||||
#include <string.h>
|
||||
#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);
|
||||
}
|
||||
|
||||
@ -5,9 +5,11 @@
|
||||
#define _USB_STD_H_
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stddef.h>
|
||||
#include <string.h>
|
||||
#include <stdint.h>
|
||||
#include <stdbool.h>
|
||||
#include "utils.h"
|
||||
#include <stdalign.h>
|
||||
|
||||
/*- 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_
|
||||
|
||||
37
platform/rp2040/usb/usb_winusb.c
Normal file
37
platform/rp2040/usb/usb_winusb.c
Normal file
@ -0,0 +1,37 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2022, Alex Taradov <alex@taradov.com>. 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;
|
||||
}
|
||||
153
platform/rp2040/usb/usb_winusb.h
Normal file
153
platform/rp2040/usb/usb_winusb.h
Normal file
@ -0,0 +1,153 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2022, Alex Taradov <alex@taradov.com>. 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>\<Instance>\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_
|
||||
@ -3,7 +3,6 @@
|
||||
|
||||
/*- Includes ----------------------------------------------------------------*/
|
||||
#include <stdalign.h>
|
||||
#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];
|
||||
|
||||
@ -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_
|
||||
|
||||
|
||||
|
||||
@ -1,14 +0,0 @@
|
||||
// SPDX-License-Identifier: BSD-3-Clause
|
||||
// Copyright (c) 2016-2022, Alex Taradov <alex@taradov.com>. 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_
|
||||
|
||||
Loading…
Reference in New Issue
Block a user