rtt更新

This commit is contained in:
2025-01-18 13:25:25 +08:00
parent c6a7554b51
commit d6009a0773
726 changed files with 103376 additions and 6270 deletions

Binary file not shown.

After

Width:  |  Height:  |  Size: 42 KiB

View File

@@ -0,0 +1,330 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "FreeRTOS.h"
#include "task.h"
#include "event_groups.h"
#include "csh.h"
#include "usbd_core.h"
#include "usbd_adb.h"
#include "chry_ringbuffer.h"
static chry_ringbuffer_t shell_rb;
static uint8_t mempool[1024];
#ifndef task_repl_PRIORITY
#define task_repl_PRIORITY (configMAX_PRIORITIES - 4U)
#endif
#ifndef task_exec_PRIORITY
#define task_exec_PRIORITY (configMAX_PRIORITIES - 5U)
#endif
static chry_shell_t csh;
static volatile bool login = false;
static StaticTask_t task_buffer_repl;
static StaticTask_t task_buffer_exec;
static StackType_t task_stack_repl[1024];
static StackType_t task_stack_exec[1024];
static TaskHandle_t task_hdl_repl = NULL;
static TaskHandle_t task_hdl_exec = NULL;
static EventGroupHandle_t event_hdl;
static StaticEventGroup_t event_grp;
void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len)
{
chry_ringbuffer_write(&shell_rb, data, len);
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xEventGroupSetBitsFromISR(event_hdl, 0x10, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
void usbd_adb_notify_write_done(void)
{
BaseType_t xHigherPriorityTaskWoken = pdFALSE;
xEventGroupSetBitsFromISR(event_hdl, 0x20, &xHigherPriorityTaskWoken);
portYIELD_FROM_ISR(xHigherPriorityTaskWoken);
}
static uint16_t csh_sput_cb(chry_readline_t *rl, const void *data, uint16_t size)
{
(void)rl;
if (!usb_device_is_configured(0)) {
return size;
}
if (usbd_adb_can_write() && size) {
usbd_abd_write(ADB_SHELL_LOALID, data, size);
xEventGroupWaitBits(event_hdl, 0x20, pdTRUE, pdFALSE, portMAX_DELAY);
}
return size;
}
static uint16_t csh_sget_cb(chry_readline_t *rl, void *data, uint16_t size)
{
(void)rl;
return chry_ringbuffer_read(&shell_rb, data, size);
}
static void wait_char(void)
{
EventBits_t event;
wait:
/* In order to lock the log from being disrupted , wait for REPL task execution to complete */
event = xEventGroupWaitBits(event_hdl, (0x10 | 0x01 | 0x04), pdTRUE, pdFALSE, portMAX_DELAY);
if ((event & 0x10) == 0) {
if (event & 0x01) {
chry_readline_erase_line(&csh.rl);
xEventGroupSetBits(event_hdl, 0x02);
}
if (event & 0x04) {
chry_readline_edit_refresh(&csh.rl);
xEventGroupSetBits(event_hdl, 0x08);
}
goto wait;
}
}
static void task_repl(void *param)
{
(void)param;
int ret;
volatile uint8_t *pexec = (void *)&csh.exec;
for (;;) {
restart:
if (login) {
goto repl;
} else {
}
ret = csh_login(&csh);
if (ret == 0) {
login = true;
} else if (ret == 1) {
/*!< no enough char */
wait_char();
continue;
} else {
continue;
}
repl:
ret = chry_shell_task_repl(&csh);
if (ret == -1) {
/*!< error */
goto restart;
} else if (ret == 1) {
/*!< no enough char */
wait_char();
} else {
/*!< restart */
}
/*!< check flag */
if (*pexec == CSH_STATUS_EXEC_DONE) {
*pexec = CSH_STATUS_EXEC_IDLE;
chry_readline_auto_refresh(&csh.rl, true);
chry_readline_ignore(&csh.rl, false);
chry_readline_edit_refresh(&csh.rl);
}
if (login == false) {
chry_readline_erase_line(&csh.rl);
csh.rl.noblock = false;
}
}
}
static void task_exec(void *param)
{
(void)param;
/*!< execute shell command */
chry_shell_task_exec(&csh);
/*!< notify REPL task execute done */
xEventGroupSetBits(event_hdl, 0x10);
/*!< wait for REPL task delete */
vTaskSuspend(NULL);
}
int chry_shell_port_create_context(chry_shell_t *csh, int argc, const char **argv)
{
volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec;
(void)csh;
(void)argc;
(void)argv;
if (*p_task_hdl_exec != NULL) {
vTaskDelete(*p_task_hdl_exec);
}
*p_task_hdl_exec = xTaskCreateStatic(task_exec, "task_exec", 1024U, NULL, task_exec_PRIORITY, task_stack_exec, &task_buffer_exec);
return 0;
}
void chry_shell_port_default_handler(chry_shell_t *csh, int sig)
{
volatile uint8_t *pexec = (void *)&csh->exec;
volatile TaskHandle_t *p_task_hdl_exec = (void *)&task_hdl_exec;
switch (sig) {
case CSH_SIGINT:
case CSH_SIGQUIT:
case CSH_SIGKILL:
case CSH_SIGTERM:
break;
default:
return;
}
/*!< force delete task */
if (*p_task_hdl_exec != NULL) {
vTaskDelete(task_hdl_exec);
*p_task_hdl_exec = NULL;
}
switch (sig) {
case CSH_SIGINT:
csh->rl.sput(&csh->rl, "^SIGINT" CONFIG_CSH_NEWLINE, sizeof("^SIGINT" CONFIG_CSH_NEWLINE) - 1);
break;
case CSH_SIGQUIT:
csh->rl.sput(&csh->rl, "^SIGQUIT" CONFIG_CSH_NEWLINE, sizeof("^SIGQUIT" CONFIG_CSH_NEWLINE) - 1);
break;
case CSH_SIGKILL:
csh->rl.sput(&csh->rl, "^SIGKILL" CONFIG_CSH_NEWLINE, sizeof("^SIGKILL" CONFIG_CSH_NEWLINE) - 1);
break;
case CSH_SIGTERM:
csh->rl.sput(&csh->rl, "^SIGTERM" CONFIG_CSH_NEWLINE, sizeof("^SIGTERM" CONFIG_CSH_NEWLINE) - 1);
break;
default:
return;
}
*pexec = CSH_STATUS_EXEC_IDLE;
chry_readline_auto_refresh(&csh->rl, true);
chry_readline_ignore(&csh->rl, false);
chry_readline_edit_refresh(&csh->rl);
}
int shell_init(bool need_login)
{
chry_shell_init_t csh_init;
if (chry_ringbuffer_init(&shell_rb, mempool, sizeof(mempool))) {
return -1;
}
if (need_login) {
login = false;
} else {
login = true;
}
/*!< I/O callback */
csh_init.sput = csh_sput_cb;
csh_init.sget = csh_sget_cb;
#if defined(CONFIG_CSH_SYMTAB) && CONFIG_CSH_SYMTAB
extern const int __fsymtab_start;
extern const int __fsymtab_end;
extern const int __vsymtab_start;
extern const int __vsymtab_end;
/*!< get table from ld symbol */
csh_init.command_table_beg = &__fsymtab_start;
csh_init.command_table_end = &__fsymtab_end;
csh_init.variable_table_beg = &__vsymtab_start;
csh_init.variable_table_end = &__vsymtab_end;
#endif
#if defined(CONFIG_CSH_PROMPTEDIT) && CONFIG_CSH_PROMPTEDIT
static char csh_prompt_buffer[128];
/*!< set prompt buffer */
csh_init.prompt_buffer = csh_prompt_buffer;
csh_init.prompt_buffer_size = sizeof(csh_prompt_buffer);
#endif
#if defined(CONFIG_CSH_HISTORY) && CONFIG_CSH_HISTORY
static char csh_history_buffer[128];
/*!< set history buffer */
csh_init.history_buffer = csh_history_buffer;
csh_init.history_buffer_size = sizeof(csh_history_buffer);
#endif
#if defined(CONFIG_CSH_LNBUFF_STATIC) && CONFIG_CSH_LNBUFF_STATIC
static char csh_line_buffer[128];
/*!< set linebuffer */
csh_init.line_buffer = csh_line_buffer;
csh_init.line_buffer_size = sizeof(csh_line_buffer);
#endif
csh_init.uid = 0;
csh_init.user[0] = "cherry";
/*!< The port hash function is required,
and the strcmp attribute is used weakly by default,
int chry_shell_port_hash_strcmp(const char *hash, const char *str); */
csh_init.hash[0] = "12345678"; /*!< If there is no password, set to NULL */
csh_init.host = "cherryadb";
csh_init.user_data = NULL;
int ret = chry_shell_init(&csh, &csh_init);
if (ret) {
return -1;
}
task_hdl_exec = NULL;
event_hdl = xEventGroupCreateStatic(&event_grp);
task_hdl_repl = xTaskCreateStatic(task_repl, "task_repl", 1024U, NULL, task_repl_PRIORITY, task_stack_repl, &task_buffer_repl);
return 0;
}
void shell_lock(void)
{
xEventGroupSetBits(event_hdl, 0x01);
xEventGroupWaitBits(event_hdl, 0x02, pdTRUE, pdTRUE, portMAX_DELAY);
}
void shell_unlock(void)
{
xEventGroupSetBits(event_hdl, 0x04);
xEventGroupWaitBits(event_hdl, 0x08, pdTRUE, pdTRUE, portMAX_DELAY);
}
static int csh_exit(int argc, char **argv)
{
(void)argc;
(void)argv;
usbd_adb_close(ADB_SHELL_LOALID);
return 0;
}
CSH_SCMD_EXPORT_ALIAS(csh_exit, exit, );
#define __ENV_PATH "/sbin:/bin"
const char ENV_PATH[] = __ENV_PATH;
CSH_RVAR_EXPORT(ENV_PATH, PATH, sizeof(__ENV_PATH));
#define __ENV_ZERO ""
const char ENV_ZERO[] = __ENV_ZERO;
CSH_RVAR_EXPORT(ENV_ZERO, ZERO, sizeof(__ENV_ZERO));

View File

@@ -0,0 +1,228 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_adb.h"
/*!< endpoint address */
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
#define USBD_VID 0xFFFF
#define USBD_PID 0xFFFF
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
/*!< config descriptor size */
#define USB_CONFIG_SIZE (9 + 9 + 7 + 7)
#ifdef CONFIG_USB_HS
#define WINUSB_MAX_MPS 512
#else
#define WINUSB_MAX_MPS 64
#endif
#define WCID_VENDOR_CODE 0x17
#define ADB_INTF_NUM 0
__ALIGN_BEGIN const uint8_t WCID_StringDescriptor_MSOS[18] __ALIGN_END = {
///////////////////////////////////////
/// MS OS string descriptor
///////////////////////////////////////
0x12, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
/* MSFT100 */
'M', 0x00, 'S', 0x00, 'F', 0x00, 'T', 0x00, /* wcChar_7 */
'1', 0x00, '0', 0x00, '0', 0x00, /* wcChar_7 */
WCID_VENDOR_CODE, /* bVendorCode */
0x00, /* bReserved */
};
__ALIGN_BEGIN const uint8_t WINUSB_WCIDDescriptor[40] __ALIGN_END = {
///////////////////////////////////////
/// WCID descriptor
///////////////////////////////////////
0x28, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x04, 0x00, /* wIndex */
0x01, /* bCount */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_7 */
///////////////////////////////////////
/// WCID function descriptor
///////////////////////////////////////
ADB_INTF_NUM, /* bFirstInterfaceNumber */
0x01, /* bReserved */
/* Compatible ID */
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00, /* cCID_8: WINUSB */
/* */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* cSubCID_8 */
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, /* bReserved_6 */
};
__ALIGN_BEGIN const uint8_t WINUSB_IF0_WCIDProperties[142] __ALIGN_END = {
///////////////////////////////////////
/// WCID property descriptor
///////////////////////////////////////
0x8e, 0x00, 0x00, 0x00, /* dwLength */
0x00, 0x01, /* bcdVersion */
0x05, 0x00, /* wIndex */
0x01, 0x00, /* wCount */
///////////////////////////////////////
/// registry propter descriptor
///////////////////////////////////////
0x84, 0x00, 0x00, 0x00, /* dwSize */
0x01, 0x00, 0x00, 0x00, /* dwPropertyDataType */
0x28, 0x00, /* wPropertyNameLength */
/* DeviceInterfaceGUID */
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, /* wcName_20 */
'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, /* wcName_20 */
't', 0x00, 'e', 0x00, 'r', 0x00, 'f', 0x00, /* wcName_20 */
'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, /* wcName_20 */
'U', 0x00, 'I', 0x00, 'D', 0x00, 0x00, 0x00, /* wcName_20 */
0x4e, 0x00, 0x00, 0x00, /* dwPropertyDataLength */
/* {1D4B2365-4749-48EA-B38A-7C6FDDDD7E26} */
'{', 0x00, '1', 0x00, 'D', 0x00, '4', 0x00, /* wcData_39 */
'B', 0x00, '2', 0x00, '3', 0x00, '6', 0x00, /* wcData_39 */
'5', 0x00, '-', 0x00, '4', 0x00, '7', 0x00, /* wcData_39 */
'4', 0x00, '9', 0x00, '-', 0x00, '4', 0x00, /* wcData_39 */
'8', 0x00, 'E', 0x00, 'A', 0x00, '-', 0x00, /* wcData_39 */
'B', 0x00, '3', 0x00, '8', 0x00, 'A', 0x00, /* wcData_39 */
'-', 0x00, '7', 0x00, 'C', 0x00, '6', 0x00, /* wcData_39 */
'F', 0x00, 'D', 0x00, 'D', 0x00, 'D', 0x00, /* wcData_39 */
'D', 0x00, '7', 0x00, 'E', 0x00, '2', 0x00, /* wcData_39 */
'6', 0x00, '}', 0x00, 0x00, 0x00, /* wcData_39 */
};
const uint8_t *WINUSB_IFx_WCIDProperties[] = {
WINUSB_IF0_WCIDProperties,
};
struct usb_msosv1_descriptor msosv1_desc = {
.string = WCID_StringDescriptor_MSOS,
.vendor_code = WCID_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
.comp_id_property = WINUSB_IFx_WCIDProperties,
};
/*!< global descriptor */
static const uint8_t adb_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0100, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
ADB_DESCRIPTOR_INIT(ADB_INTF_NUM, WINUSB_IN_EP, WINUSB_OUT_EP, WINUSB_MAX_MPS),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'A', 0x00, /* wcChar6 */
'D', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x1C, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'A', 0x00, /* wcChar6 */
'D', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
'2', 0x00, /* wcChar9 */
'0', 0x00, /* wcChar10 */
'2', 0x00, /* wcChar11 */
'4', 0x00, /* wcChar12 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x02,
0x02,
0x01,
0x40,
0x00,
0x00,
#endif
0x00
};
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
static struct usbd_interface intf0;
extern int shell_init(bool need_login);
void cherryadb_init(uint8_t busid, uint32_t reg_base)
{
/* default password is : 12345678 */
/* shell_init() must be called in-task */
if (0 != shell_init(false)) {
/* shell failed to be initialized */
printf("Failed to initialize shell\r\n");
for (;;) {
;
}
}
usbd_desc_register(busid, adb_descriptor);
usbd_add_interface(busid, usbd_adb_init_intf(busid, &intf0, WINUSB_IN_EP, WINUSB_OUT_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);
}

View File

@@ -144,7 +144,7 @@ const uint8_t audio_v1_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -212,7 +212,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
void audio_v1_init(uint8_t busid, uint32_t reg_base)
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v1_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 1));

View File

@@ -139,7 +139,7 @@ const uint8_t audio_v1_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -238,7 +238,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
void audio_v1_init(uint8_t busid, uint32_t reg_base)
void audio_v1_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v1_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0100, audio_entity_table, 2));

View File

@@ -149,7 +149,7 @@ const uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -229,7 +229,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
void audio_v2_init(uint8_t busid, uint32_t reg_base)
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));

View File

@@ -196,7 +196,7 @@ uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -346,7 +346,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_IN_EP },
};
void audio_v2_init(uint8_t busid, uint32_t reg_base)
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 4));

View File

@@ -149,7 +149,7 @@ const uint8_t audio_v2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -247,7 +247,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
void audio_v2_init(uint8_t busid, uint32_t reg_base)
void audio_v2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, audio_v2_descriptor);
usbd_add_interface(busid, usbd_audio_init_intf(busid, &intf0, 0x0200, audio_entity_table, 2));

View File

@@ -0,0 +1,463 @@
/*
* Copyright (c) 2024, sakumisu
* Copyright (c) 2024, Egahp
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "bootuf2.h"
#include "usbd_core.h"
char file_INFO[] = {
"CherryUSB UF2 BOOT\r\n"
"Model: " CONFIG_PRODUCT "\r\n"
"Board-ID: " CONFIG_BOARD "\r\n"
};
const char file_IDEX[] = {
"<!doctype html>\n"
"<html>"
"<body>"
"<script>\n"
"location.replace(\"" CONFIG_BOOTUF2_INDEX_URL "\");\n"
"</script>"
"</body>"
"</html>\n"
};
const char file_JOIN[] = {
"<!doctype html>\n"
"<html>"
"<body>"
"<script>\n"
"location.replace(\"" CONFIG_BOOTUF2_JOIN_URL "\");\n"
"</script>"
"</body>"
"</html>\n"
};
const char file_ID__[12] = BOOTUF2_FAMILYID_ARRAY;
static struct bootuf2_FILE files[] = {
[0] = { .Name = file_ID__, .Content = NULL, .FileSize = 0 },
[1] = { .Name = "INFO_UF2TXT", .Content = file_INFO, .FileSize = sizeof(file_INFO) - 1 },
[2] = { .Name = "INDEX HTM", .Content = file_IDEX, .FileSize = sizeof(file_IDEX) - 1 },
[3] = { .Name = "JOIN HTM", .Content = file_JOIN, .FileSize = sizeof(file_JOIN) - 1 },
};
struct bootuf2_data {
const struct bootuf2_DBR *const DBR;
struct bootuf2_STATE *const STATE;
uint8_t *const fbuff;
uint8_t *const erase;
size_t page_count;
uint8_t *const cache;
const size_t cache_size;
uint32_t cached_address;
size_t cached_bytes;
};
/*!< define DBRs */
static const struct bootuf2_DBR bootuf2_DBR = {
.JMPInstruction = { 0xEB, 0x3C, 0x90 },
.OEM = "UF2 UF2 ",
.BPB = {
.BytesPerSector = CONFIG_BOOTUF2_SECTOR_SIZE,
.SectorsPerCluster = CONFIG_BOOTUF2_SECTOR_PER_CLUSTER,
.ReservedSectors = CONFIG_BOOTUF2_SECTOR_RESERVED,
.NumberOfFAT = CONFIG_BOOTUF2_NUM_OF_FAT,
.RootEntries = CONFIG_BOOTUF2_ROOT_ENTRIES,
.Sectors = (BOOTUF2_SECTORS(0) > 0xFFFF) ? 0 : BOOTUF2_SECTORS(0),
.MediaDescriptor = 0xF8,
.SectorsPerFAT = BOOTUF2_SECTORS_PER_FAT(0),
.SectorsPerTrack = 1,
.Heads = 1,
.HiddenSectors = 0,
.SectorsOver32MB = (BOOTUF2_SECTORS(0) > 0xFFFF) ? BOOTUF2_SECTORS(0) : 0,
.BIOSDrive = 0x80,
.Reserved = 0,
.ExtendBootSignature = 0x29,
.VolumeSerialNumber = 0x00420042,
.VolumeLabel = "CHERRYUF2",
.FileSystem = "FAT16 ",
},
};
/*!< define mask */
static uint8_t __attribute__((aligned(4))) bootuf2_mask[BOOTUF2_BLOCKSMAX / 8 + 1] = { 0 };
/*!< define state */
static struct bootuf2_STATE bootuf2_STATE = {
.NumberOfBlock = 0,
.NumberOfWritten = 0,
.Mask = bootuf2_mask,
.Enable = 1,
};
/*!< define flash cache */
static uint8_t __attribute__((aligned(4))) bootuf2_disk_cache[CONFIG_BOOTUF2_CACHE_SIZE];
/*!< define flash buff */
static uint8_t __attribute__((aligned(4))) bootuf2_disk_fbuff[256];
/*!< define erase flag buff */
static uint8_t __attribute__((aligned(4))) bootuf2_disk_erase[BOOTUF2_DIVCEIL(CONFIG_BOOTUF2_PAGE_COUNTMAX, 8)];
/*!< define disk */
static struct bootuf2_data bootuf2_disk = {
.DBR = &bootuf2_DBR,
.STATE = &bootuf2_STATE,
.fbuff = bootuf2_disk_fbuff,
.erase = bootuf2_disk_erase,
.cache = bootuf2_disk_cache,
.cache_size = sizeof(bootuf2_disk_cache),
};
static void fname_copy(char *dst, char const *src, uint16_t len)
{
for (size_t i = 0; i < len; ++i) {
if (*src)
*dst++ = *src++;
else
*dst++ = ' ';
}
}
static void fcalculate_cluster(struct bootuf2_data *ctx)
{
/*!< init files cluster */
uint16_t cluster_beg = 2;
for (int i = 0; i < ARRAY_SIZE(files); i++) {
files[i].ClusterBeg = cluster_beg;
files[i].ClusterEnd = -1 + cluster_beg +
BOOTUF2_DIVCEIL(files[i].FileSize,
ctx->DBR->BPB.BytesPerSector *
ctx->DBR->BPB.SectorsPerCluster);
cluster_beg = files[i].ClusterEnd + 1;
}
}
static int ffind_by_cluster(uint32_t cluster)
{
if (cluster >= 0xFFF0) {
return -1;
}
for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) {
if ((files[i].ClusterBeg <= cluster) &&
(cluster <= files[i].ClusterEnd)) {
return i;
}
}
return -1;
}
static bool bootuf2block_check_writable(struct bootuf2_STATE *STATE,
struct bootuf2_BLOCK *uf2, uint32_t block_max)
{
if (uf2->NumberOfBlock) {
if (uf2->BlockIndex < block_max) {
uint8_t mask = 1 << (uf2->BlockIndex % 8);
uint32_t pos = uf2->BlockIndex / 8;
if ((STATE->Mask[pos] & mask) == 0) {
return true;
}
}
}
return false;
}
static void bootuf2block_state_update(struct bootuf2_STATE *STATE,
struct bootuf2_BLOCK *uf2, uint32_t block_max)
{
if (uf2->NumberOfBlock) {
if (STATE->NumberOfBlock != uf2->NumberOfBlock) {
if ((uf2->NumberOfBlock >= BOOTUF2_BLOCKSMAX) ||
STATE->NumberOfBlock) {
/*!< uf2 block only can be update once */
/*!< this will cause never auto reboot */
STATE->NumberOfBlock = 0xffffffff;
} else {
STATE->NumberOfBlock = uf2->NumberOfBlock;
}
}
if (uf2->BlockIndex < block_max) {
uint8_t mask = 1 << (uf2->BlockIndex % 8);
uint32_t pos = uf2->BlockIndex / 8;
if ((STATE->Mask[pos] & mask) == 0) {
STATE->Mask[pos] |= mask;
STATE->NumberOfWritten++;
}
}
}
USB_LOG_DBG("UF2 block total %d written %d index %d\r\n",
uf2->NumberOfBlock, STATE->NumberOfWritten, uf2->BlockIndex);
}
static bool bootuf2block_state_check(struct bootuf2_STATE *STATE)
{
return (STATE->NumberOfWritten >= STATE->NumberOfBlock) &&
STATE->NumberOfBlock;
}
static int bootuf2_flash_flush(struct bootuf2_data *ctx)
{
int err;
if (ctx->cached_bytes == 0) {
return 0;
}
err = bootuf2_flash_write(ctx->cached_address, ctx->cache, ctx->cached_bytes);
if (err) {
USB_LOG_ERR("UF2 slot flash write error %d at offset %08lx len %d\r\n",
err, ctx->cached_address, ctx->cached_bytes);
return -1;
}
ctx->cached_bytes = 0;
return 0;
}
int bootuf2_flash_write_internal(struct bootuf2_data *ctx, struct bootuf2_BLOCK *uf2)
{
/*!< 1.cache not empty and address not continue */
/*!< 2.cache full */
if ((ctx->cached_bytes && ((ctx->cached_address + ctx->cached_bytes) != uf2->TargetAddress)) ||
(ctx->cached_bytes == ctx->cache_size)) {
int err = bootuf2_flash_flush(ctx);
if (err)
return err;
}
/*!< write len always is 256, cache_size always is a multiple of 256 */
memcpy(ctx->cache + ctx->cached_bytes, uf2->Data, uf2->PayloadSize);
ctx->cached_address = uf2->TargetAddress - ctx->cached_bytes;
ctx->cached_bytes += uf2->PayloadSize;
return 0;
}
void bootuf2_init(void)
{
struct bootuf2_data *ctx;
ctx = &bootuf2_disk;
fcalculate_cluster(ctx);
ctx->cached_bytes = 0;
ctx->cached_address = 0;
}
int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count)
{
struct bootuf2_data *ctx;
ctx = &bootuf2_disk;
while (sector_count) {
memset(buff, 0, ctx->DBR->BPB.BytesPerSector);
uint32_t sector_relative = start_sector;
/*!< DBR sector */
if (start_sector == BOOTUF2_SECTOR_DBR_END) {
memcpy(buff, ctx->DBR, sizeof(struct bootuf2_DBR));
buff[510] = 0x55;
buff[511] = 0xaa;
}
/*!< FAT sector */
else if (start_sector < BOOTUF2_SECTOR_FAT_END(ctx->DBR)) {
uint16_t *buff16 = (uint16_t *)buff;
sector_relative -= BOOTUF2_SECTOR_RSVD_END(ctx->DBR);
/*!< Perform the same operation on all FAT tables */
while (sector_relative >= ctx->DBR->BPB.SectorsPerFAT) {
sector_relative -= ctx->DBR->BPB.SectorsPerFAT;
}
uint16_t cluster_unused = files[ARRAY_SIZE(files) - 1].ClusterEnd + 1;
uint16_t cluster_absolute_first = sector_relative *
BOOTUF2_FAT16_PER_SECTOR(ctx->DBR);
/*!< cluster used link to chain, or unsed */
for (uint16_t i = 0, cluster_absolute = cluster_absolute_first;
i < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR);
i++, cluster_absolute++) {
if (cluster_absolute >= cluster_unused)
buff16[i] = 0;
else
buff16[i] = cluster_absolute + 1;
}
/*!< cluster 0 and 1 */
if (sector_relative == 0) {
buff[0] = ctx->DBR->BPB.MediaDescriptor;
buff[1] = 0xff;
buff16[1] = 0xffff;
}
/*!< cluster end of file */
for (uint32_t i = 0; i < ARRAY_SIZE(files); i++) {
uint16_t cluster_file_last = files[i].ClusterEnd;
if (cluster_file_last >= cluster_absolute_first) {
uint16_t idx = cluster_file_last - cluster_absolute_first;
if (idx < BOOTUF2_FAT16_PER_SECTOR(ctx->DBR)) {
buff16[idx] = 0xffff;
}
}
}
}
/*!< root entries */
else if (start_sector < BOOTUF2_SECTOR_ROOT_END(ctx->DBR)) {
sector_relative -= BOOTUF2_SECTOR_FAT_END(ctx->DBR);
struct bootuf2_ENTRY *ent = (void *)buff;
int remain_entries = BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR);
uint32_t file_index_first;
/*!< volume label entry */
if (sector_relative == 0) {
fname_copy(ent->Name, (char const *)ctx->DBR->BPB.VolumeLabel, 11);
ent->Attribute = 0x28;
ent++;
remain_entries--;
file_index_first = 0;
} else {
/*!< -1 to account for volume label in first sector */
file_index_first = sector_relative * BOOTUF2_ENTRY_PER_SECTOR(ctx->DBR) - 1;
}
for (uint32_t idx = file_index_first;
(remain_entries > 0) && (idx < ARRAY_SIZE(files));
idx++, ent++) {
const uint32_t cluster_beg = files[idx].ClusterBeg;
const struct bootuf2_FILE *f = &files[idx];
if ((0 == f->FileSize) &&
(0 != idx)) {
continue;
}
fname_copy(ent->Name, f->Name, 11);
ent->Attribute = 0x05;
ent->CreateTimeTeenth = BOOTUF2_SECONDS_INT % 2 * 100;
ent->CreateTime = BOOTUF2_DOS_TIME;
ent->CreateDate = BOOTUF2_DOS_DATE;
ent->LastAccessDate = BOOTUF2_DOS_DATE;
ent->FirstClustH16 = cluster_beg >> 16;
ent->UpdateTime = BOOTUF2_DOS_TIME;
ent->UpdateDate = BOOTUF2_DOS_DATE;
ent->FirstClustL16 = cluster_beg & 0xffff;
ent->FileSize = f->FileSize;
}
}
/*!< data */
else if (start_sector < BOOTUF2_SECTOR_DATA_END(ctx->DBR)) {
sector_relative -= BOOTUF2_SECTOR_ROOT_END(ctx->DBR);
int fid = ffind_by_cluster(2 + sector_relative / ctx->DBR->BPB.SectorsPerCluster);
if (fid >= 0) {
const struct bootuf2_FILE *f = &files[fid];
uint32_t sector_relative_file =
sector_relative -
(files[fid].ClusterBeg - 2) * ctx->DBR->BPB.SectorsPerCluster;
size_t fcontent_offset = sector_relative_file * ctx->DBR->BPB.BytesPerSector;
size_t fcontent_length = f->FileSize;
if (fcontent_length > fcontent_offset) {
const void *src = (void *)((uint8_t *)(f->Content) + fcontent_offset);
size_t copy_size = fcontent_length - fcontent_offset;
if (copy_size > ctx->DBR->BPB.BytesPerSector) {
copy_size = ctx->DBR->BPB.BytesPerSector;
}
memcpy(buff, src, copy_size);
}
}
}
/*!< unknown sector, ignore */
start_sector++;
sector_count--;
buff += ctx->DBR->BPB.BytesPerSector;
}
return 0;
}
int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count)
{
struct bootuf2_data *ctx;
ctx = &bootuf2_disk;
while (sector_count) {
struct bootuf2_BLOCK *uf2 = (void *)buff;
if (!((uf2->MagicStart0 == BOOTUF2_MAGIC_START0) &&
(uf2->MagicStart1 == BOOTUF2_MAGIC_START1) &&
(uf2->MagicEnd == BOOTUF2_MAGIC_END) &&
(uf2->Flags & BOOTUF2_FLAG_FAMILID_PRESENT) &&
!(uf2->Flags & BOOTUF2_FLAG_NOT_MAIN_FLASH))) {
goto next;
}
if (uf2->FamilyID == CONFIG_BOOTUF2_FAMILYID) {
if (bootuf2block_check_writable(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX)) {
bootuf2_flash_write_internal(ctx, uf2);
bootuf2block_state_update(ctx->STATE, uf2, CONFIG_BOOTUF2_FLASHMAX);
} else {
USB_LOG_DBG("UF2 block %d already written\r\n",
uf2->BlockIndex);
}
} else {
USB_LOG_DBG("UF2 block illegal id %08x\r\n", uf2->FamilyID);
}
next:
start_sector++;
sector_count--;
buff += ctx->DBR->BPB.BytesPerSector;
}
return 0;
}
uint16_t bootuf2_get_sector_size(void)
{
return bootuf2_disk.DBR->BPB.BytesPerSector;
}
uint32_t bootuf2_get_sector_count(void)
{
return bootuf2_disk.DBR->BPB.SectorsOver32MB + bootuf2_disk.DBR->BPB.Sectors;
}
bool bootuf2_is_write_done(void)
{
if (bootuf2block_state_check(bootuf2_disk.STATE)) {
bootuf2_flash_flush(&bootuf2_disk);
USB_LOG_DBG("UF2 update ok\r\n");
return true;
} else {
return false;
}
}

View File

@@ -0,0 +1,218 @@
/*
* Copyright (c) 2024, sakumisu
* Copyright (c) 2024, Egahp
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef BOOTUF2_H
#define BOOTUF2_H
#include <stdint.h>
#include <stddef.h>
#include <string.h>
#include <stdbool.h>
#include <stdio.h>
#include <bootuf2_config.h>
#ifndef __PACKED
#define __PACKED __attribute__((packed))
#endif
#ifndef ARRAY_SIZE
#define ARRAY_SIZE(array) \
((int)((sizeof(array) / sizeof((array)[0]))))
#endif
struct bootuf2_BLOCK
{
// 32 byte header
uint32_t MagicStart0;
uint32_t MagicStart1;
uint32_t Flags;
uint32_t TargetAddress;
uint32_t PayloadSize;
uint32_t BlockIndex;
uint32_t NumberOfBlock;
uint32_t FamilyID; // or file_size
uint8_t Data[476];
uint32_t MagicEnd;
} __PACKED;
//BUILD_ASSERT(sizeof(struct bootuf2_BLOCK) == 512, "bootuf2_BLOCK not sector sized");
struct bootuf2_STATE
{
uint32_t NumberOfBlock;
uint32_t NumberOfWritten;
uint8_t *const Mask;
uint8_t Enable;
};
struct bootuf2_DBR
{
/*!< offset 0 */
uint8_t JMPInstruction[3];
/*!< offset 3 */
uint8_t OEM[8];
/*!< offset 11 */
struct
{
uint16_t BytesPerSector;
uint8_t SectorsPerCluster;
uint16_t ReservedSectors;
uint8_t NumberOfFAT;
uint16_t RootEntries;
uint16_t Sectors;
uint8_t MediaDescriptor;
uint16_t SectorsPerFAT;
uint16_t SectorsPerTrack;
uint16_t Heads;
uint32_t HiddenSectors;
uint32_t SectorsOver32MB;
uint8_t BIOSDrive;
uint8_t Reserved;
uint8_t ExtendBootSignature;
uint32_t VolumeSerialNumber;
uint8_t VolumeLabel[11];
uint8_t FileSystem[8];
} __PACKED BPB;
/*!< offset 62 */
/*!< BootLoader */
/*!< offset 511 */
/*!< 0x55 0xAA */
} __PACKED;
//BUILD_ASSERT(sizeof(struct bootuf2_DBR) == 62, "bootuf2_DBR size must be 62 byte");
struct bootuf2_ENTRY
{
char Name[11];
uint8_t Attribute;
uint8_t NTReserved;
uint8_t CreateTimeTeenth;
uint16_t CreateTime;
uint16_t CreateDate;
uint16_t LastAccessDate;
uint16_t FirstClustH16;
uint16_t UpdateTime;
uint16_t UpdateDate;
uint16_t FirstClustL16;
uint32_t FileSize;
} __PACKED;
//BUILD_ASSERT(sizeof(struct bootuf2_ENTRY) == 32, "bootuf2_ENTRY size must be 32 byte");
struct bootuf2_FILE
{
const char *const Name;
const void *const Content;
uint32_t FileSize;
uint16_t ClusterBeg;
uint16_t ClusterEnd;
};
#define BOOTUF2_DIVCEIL(_v, _d) (((_v) / (_d)) + ((_v) % (_d) ? 1 : 0))
#define BOOTUF2_MAGIC_START0 0x0A324655u
#define BOOTUF2_MAGIC_START1 0x9E5D5157u
#define BOOTUF2_MAGIC_SERIAL 0x251B18BDu
#define BOOTUF2_MAGIC_END 0x0AB16F30u
#define BOOTUF2_FLAG_NOT_MAIN_FLASH 0x00000001u
#define BOOTUF2_FLAG_FILE_CONTAINER 0x00001000u
#define BOOTUF2_FLAG_FAMILID_PRESENT 0x00002000u
#define BOOTUF2_FLAG_MD5_PRESENT 0x00004000u
#define BOOTUF2_CMD_READ 0
#define BOOTUF2_CMD_SYNC 1
#define BOOTUF2_BLOCKSMAX (((CONFIG_BOOTUF2_FLASHMAX) / 256) + (((CONFIG_BOOTUF2_FLASHMAX) % 256) ? 1 : 0))
#define BOOTUF2_FAMILYID_POSNUM(n) (((CONFIG_BOOTUF2_FAMILYID) / (0x10000000 >> ((n) * 4))) % 0x10)
#define BOOTUF2_FAMILYID_ARRAY \
{ \
((BOOTUF2_FAMILYID_POSNUM(0) >= 10) ? BOOTUF2_FAMILYID_POSNUM(0) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(0) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(1) >= 10) ? BOOTUF2_FAMILYID_POSNUM(1) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(1) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(2) >= 10) ? BOOTUF2_FAMILYID_POSNUM(2) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(2) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(3) >= 10) ? BOOTUF2_FAMILYID_POSNUM(3) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(3) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(4) >= 10) ? BOOTUF2_FAMILYID_POSNUM(4) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(4) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(5) >= 10) ? BOOTUF2_FAMILYID_POSNUM(5) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(5) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(6) >= 10) ? BOOTUF2_FAMILYID_POSNUM(6) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(6) + '0'), \
((BOOTUF2_FAMILYID_POSNUM(7) >= 10) ? BOOTUF2_FAMILYID_POSNUM(7) - 10 + 'A' : BOOTUF2_FAMILYID_POSNUM(7) + '0'), \
('I'), \
('D'), \
(' '), \
('\0'), \
};
#define BOOTUF2_FAT16_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / 2)
#define BOOTUF2_ENTRY_PER_SECTOR(pDBR) (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY))
#define BOOTUF2_CLUSTERSMAX (0xFFF0 - 2)
#define BOOTUF2_SECTOR_DBR_END (0)
#define BOOTUF2_SECTOR_RSVD_END(pDBR) BOOTUF2_SECTOR_DBR_END + (pDBR->BPB.ReservedSectors)
#define BOOTUF2_SECTOR_FAT_END(pDBR) BOOTUF2_SECTOR_RSVD_END(pDBR) + (pDBR->BPB.SectorsPerFAT * pDBR->BPB.NumberOfFAT)
#define BOOTUF2_SECTOR_ROOT_END(pDBR) BOOTUF2_SECTOR_FAT_END(pDBR) + (pDBR->BPB.RootEntries / (pDBR->BPB.BytesPerSector / sizeof(struct bootuf2_ENTRY)))
#define BOOTUF2_SECTOR_DATA_END(pDBR) (pDBR->BPB.Sectors + pDBR->BPB.SectorsOver32MB)
#define BOOTUF2_SECTORS_PER_FAT(n) \
BOOTUF2_DIVCEIL(BOOTUF2_CLUSTERSMAX, (CONFIG_BOOTUF2_SECTOR_SIZE / 2))
#define BOOTUF2_SECTORS_FOR_ENTRIES(n) \
(CONFIG_BOOTUF2_ROOT_ENTRIES / (CONFIG_BOOTUF2_SECTOR_SIZE / sizeof(struct bootuf2_ENTRY)))
#define BOOTUF2_SECTORS(n) \
(CONFIG_BOOTUF2_SECTOR_RESERVED + \
CONFIG_BOOTUF2_NUM_OF_FAT * BOOTUF2_SECTORS_PER_FAT(n) + \
BOOTUF2_SECTORS_FOR_ENTRIES(n) + \
BOOTUF2_CLUSTERSMAX * CONFIG_BOOTUF2_SECTOR_PER_CLUSTER)
#define BOOTUF2_YEAR_INT ( \
(__DATE__[7u] - '0') * 1000u + \
(__DATE__[8u] - '0') * 100u + \
(__DATE__[9u] - '0') * 10u + \
(__DATE__[10u] - '0') * 1u)
#define BOOTUF2_MONTH_INT ( \
(__DATE__[2u] == 'n' && __DATE__[1u] == 'a') ? 1u /*Jan*/ \
: (__DATE__[2u] == 'b') ? 2u /*Feb*/ \
: (__DATE__[2u] == 'r' && __DATE__[1u] == 'a') ? 3u /*Mar*/ \
: (__DATE__[2u] == 'r') ? 4u /*Apr*/ \
: (__DATE__[2u] == 'y') ? 5u /*May*/ \
: (__DATE__[2u] == 'n') ? 6u /*Jun*/ \
: (__DATE__[2u] == 'l') ? 7u /*Jul*/ \
: (__DATE__[2u] == 'g') ? 8u /*Aug*/ \
: (__DATE__[2u] == 'p') ? 9u /*Sep*/ \
: (__DATE__[2u] == 't') ? 10u /*Oct*/ \
: (__DATE__[2u] == 'v') ? 11u /*Nov*/ \
: 12u /*Dec*/)
#define BOOTUF2_DAY_INT ( \
(__DATE__[4u] == ' ' ? 0 : __DATE__[4u] - '0') * 10u + \
(__DATE__[5u] - '0'))
#define BOOTUF2_HOUR_INT ( \
(__TIME__[0u] == '?' ? 0 : __TIME__[0u] - '0') * 10u + (__TIME__[1u] == '?' ? 0 : __TIME__[1u] - '0'))
#define BOOTUF2_MINUTE_INT ( \
(__TIME__[3u] == '?' ? 0 : __TIME__[3u] - '0') * 10u + (__TIME__[4u] == '?' ? 0 : __TIME__[4u] - '0'))
#define BOOTUF2_SECONDS_INT ( \
(__TIME__[6u] == '?' ? 0 : __TIME__[6u] - '0') * 10u + (__TIME__[7u] == '?' ? 0 : __TIME__[7u] - '0'))
#define BOOTUF2_DOS_DATE ( \
((BOOTUF2_YEAR_INT - 1980u) << 9u) | \
(BOOTUF2_MONTH_INT << 5u) | \
(BOOTUF2_DAY_INT << 0u))
#define BOOTUF2_DOS_TIME ( \
(BOOTUF2_HOUR_INT << 11u) | \
(BOOTUF2_MINUTE_INT << 5u) | \
(BOOTUF2_SECONDS_INT << 0u))
void bootuf2_init(void);
int boot2uf2_read_sector(uint32_t start_sector, uint8_t *buff, uint32_t sector_count);
int bootuf2_write_sector(uint32_t start_sector, const uint8_t *buff, uint32_t sector_count);
uint16_t bootuf2_get_sector_size(void);
uint32_t bootuf2_get_sector_count(void);
bool bootuf2_is_write_done(void);
void boot2uf2_flash_init(void);
int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size);
#endif /* BOOTUF2_H */

View File

@@ -0,0 +1,25 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#ifndef BOOTUF2_CONFIG_H
#define BOOTUF2_CONFIG_H
#define CONFIG_PRODUCT "CherryUSB"
#define CONFIG_BOARD "CherryUSB BOARD"
#define CONFIG_BOOTUF2_INDEX_URL "https://github.com/cherry-embedded"
#define CONFIG_BOOTUF2_JOIN_URL "http://qm.qq.com/cgi-bin/qm/qr?_wv=1027&k=GyH2M5XfWTHQzmZis4ClpgvfdObPrvtk&authKey=LmcLhfno%2BiW51wmgVC%2F8WoYwUXqiclzWDHMU1Jy1d6S8cECJ4Q7bfJ%2FTe67RLakI&noverify=0&group_code=642693751"
#define CONFIG_BOOTUF2_CACHE_SIZE 4096
#define CONFIG_BOOTUF2_SECTOR_SIZE 512
#define CONFIG_BOOTUF2_SECTOR_PER_CLUSTER 2
#define CONFIG_BOOTUF2_SECTOR_RESERVED 1
#define CONFIG_BOOTUF2_NUM_OF_FAT 2
#define CONFIG_BOOTUF2_ROOT_ENTRIES 64
#define CONFIG_BOOTUF2_FAMILYID 0xFFFFFFFF
#define CONFIG_BOOTUF2_FLASHMAX 0x800000
#define CONFIG_BOOTUF2_PAGE_COUNTMAX 1024
#endif

Binary file not shown.

After

Width:  |  Height:  |  Size: 19 KiB

View File

@@ -0,0 +1,168 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_msc.h"
#include "bootuf2.h"
#define MSC_IN_EP 0x81
#define MSC_OUT_EP 0x02
#define USBD_VID 0xFFFF
#define USBD_PID 0xFFFF
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#define USB_CONFIG_SIZE (9 + MSC_DESCRIPTOR_LEN)
#ifdef CONFIG_USB_HS
#define MSC_MAX_MPS 512
#else
#define MSC_MAX_MPS 64
#endif
const uint8_t msc_bootuf2_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0200, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x01, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
MSC_DESCRIPTOR_INIT(0x00, MSC_OUT_EP, MSC_IN_EP, MSC_MAX_MPS, 0x02),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x26, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'U', 0x00, /* wcChar10 */
'F', 0x00, /* wcChar11 */
'2', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
bootuf2_init();
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
void usbd_msc_get_cap(uint8_t busid, uint8_t lun, uint32_t *block_num, uint32_t *block_size)
{
*block_num = bootuf2_get_sector_count();
*block_size = bootuf2_get_sector_size();
USB_LOG_INFO("sector count:%d, sector size:%d\n", *block_num, *block_size);
}
int usbd_msc_sector_read(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
boot2uf2_read_sector(sector, buffer, length / bootuf2_get_sector_size());
return 0;
}
int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *buffer, uint32_t length)
{
bootuf2_write_sector(sector, buffer, length / bootuf2_get_sector_size());
return 0;
}
static struct usbd_interface intf0;
void msc_bootuf2_init(uint8_t busid, uintptr_t reg_base)
{
boot2uf2_flash_init();
usbd_desc_register(busid, msc_bootuf2_descriptor);
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);
}
void boot2uf2_flash_init(void)
{
}
int bootuf2_flash_write(uint32_t address, const uint8_t *data, size_t size)
{
USB_LOG_INFO("address:%08x, size:%d\n", address, size);
return 0;
}

View File

@@ -5,7 +5,7 @@
*/
#include "usbd_core.h"
#include "usbd_msc.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
#include "usbd_hid.h"
/*!< endpoint address */
@@ -147,7 +147,7 @@ const uint8_t cdc_acm_hid_msc_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -301,7 +301,7 @@ struct usbd_interface intf1;
struct usbd_interface intf2;
struct usbd_interface intf3;
void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uint32_t reg_base)
void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, cdc_acm_hid_msc_descriptor);
@@ -332,14 +332,15 @@ void cdc_acm_hid_msc_descriptor_init(uint8_t busid, uint32_t reg_base)
*/
void hid_mouse_test(uint8_t busid)
{
if(usb_device_is_configured(busid) == false) {
return;
}
/*!< move mouse pointer */
mouse_cfg.x += 10;
mouse_cfg.y = 0;
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
}
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
#include "usbd_msc.h"
/*!< endpoint address */
@@ -58,7 +58,7 @@ static const uint8_t device_quality_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
};
@@ -173,7 +173,7 @@ static const uint8_t cdc_msc_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -247,7 +247,7 @@ struct usbd_interface intf0;
struct usbd_interface intf1;
struct usbd_interface intf2;
void cdc_acm_msc_init(uint8_t busid, uint32_t reg_base)
void cdc_acm_msc_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef CONFIG_USBDEV_ADVANCE_DESC
usbd_desc_register(busid, &cdc_msc_descriptor);

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
/*!< endpoint address */
#define CDC_IN_EP 0x81
@@ -113,7 +113,7 @@ static const uint8_t cdc_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -223,7 +223,7 @@ struct usbd_interface intf5;
struct usbd_interface intf6;
struct usbd_interface intf7;
void cdc_acm_multi_init(uint8_t busid, uint32_t reg_base)
void cdc_acm_multi_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, cdc_descriptor);

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
/*!< endpoint address */
#define CDC_IN_EP 0x81
@@ -98,7 +98,7 @@ static const uint8_t cdc_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -174,7 +174,7 @@ struct usbd_endpoint cdc_in_ep = {
static struct usbd_interface intf0;
static struct usbd_interface intf1;
void cdc_acm_init(uint8_t busid, uint32_t reg_base)
void cdc_acm_init(uint8_t busid, uintptr_t reg_base)
{
const uint8_t data[10] = { 0x31, 0x32, 0x33, 0x34, 0x35, 0x36, 0x37, 0x38, 0x39, 0x30 };

View File

@@ -6,6 +6,10 @@
#include "usbd_core.h"
#include "usbd_cdc_ecm.h"
#ifndef CONFIG_USBDEV_CDC_ECM_USING_LWIP
#error "Please enable CONFIG_USBDEV_CDC_ECM_USING_LWIP for this demo"
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02
@@ -124,7 +128,7 @@ static const uint8_t cdc_ecm_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -222,12 +226,12 @@ void cdc_ecm_lwip_init(void)
while (!netif_is_up(netif)) {
}
// while (dhserv_init(&dhcp_config)) {}
while (dhserv_init(&dhcp_config)) {}
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
}
void usbd_cdc_ecm_data_recv_done(uint8_t *buf, uint32_t len)
void usbd_cdc_ecm_data_recv_done(uint32_t len)
{
}
@@ -269,7 +273,7 @@ struct usbd_interface intf1;
* sudo ifconfig enxaabbccddeeff up
* sudo dhcpclient enxaabbccddeeff
*/
void cdc_ecm_init(uint8_t busid, uint32_t reg_base)
void cdc_ecm_init(uint8_t busid, uintptr_t reg_base)
{
cdc_ecm_lwip_init();

View File

@@ -6,6 +6,10 @@
#include "usbd_core.h"
#include "usbd_rndis.h"
#ifndef CONFIG_USBDEV_RNDIS_USING_LWIP
#error "Please enable CONFIG_USBDEV_RNDIS_USING_LWIP for this demo"
#endif
/*!< endpoint address */
#define CDC_IN_EP 0x81
#define CDC_OUT_EP 0x02
@@ -100,7 +104,7 @@ static const uint8_t cdc_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -170,7 +174,7 @@ rt_err_t rt_usbd_rndis_eth_tx(rt_device_t dev, struct pbuf *p)
return usbd_rndis_eth_tx(p);
}
void usbd_rndis_data_recv_done(void)
void usbd_rndis_data_recv_done(uint32_t len)
{
eth_device_ready(&rndis_dev);
}
@@ -258,12 +262,12 @@ void rndis_lwip_init(void)
while (!netif_is_up(netif)) {
}
// while (dhserv_init(&dhcp_config)) {}
while (dhserv_init(&dhcp_config)) {}
// while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
while (dnserv_init(&ipaddr, PORT_DNS, dns_query_proc)) {}
}
void usbd_rndis_data_recv_done(void)
void usbd_rndis_data_recv_done(uint32_t len)
{
}
@@ -304,7 +308,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
struct usbd_interface intf0;
struct usbd_interface intf1;
void cdc_rndis_init(uint8_t busid, uint32_t reg_base)
void cdc_rndis_init(uint8_t busid, uintptr_t reg_base)
{
#ifdef RT_USING_LWIP
rt_usbd_rndis_init();

View File

@@ -136,7 +136,7 @@ const uint8_t dfu_flash_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -169,7 +169,7 @@ static void usbd_event_handler(uint8_t busid, uint8_t event)
struct usbd_interface intf0;
void dfu_flash_init(uint8_t busid, uint32_t reg_base)
void dfu_flash_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, dfu_flash_descriptor);
usbd_add_interface(busid, usbd_dfu_init_intf(&intf0));

View File

@@ -146,7 +146,7 @@ static const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -272,7 +272,7 @@ static struct usbd_endpoint custom_out_ep = {
*/
struct usbd_interface intf0;
void hid_custom_init(uint8_t busid, uint32_t reg_base)
void hid_custom_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_custom_report_desc, HID_CUSTOM_REPORT_DESC_SIZE));

View File

@@ -122,7 +122,7 @@ static const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -221,7 +221,7 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface intf0;
void hid_keyboard_init(uint8_t busid, uint32_t reg_base)
void hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
@@ -236,12 +236,13 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(write_buffer, sendbuffer, 8);
int ret = usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
if (ret < 0) {
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -9,7 +9,7 @@
/*!< endpoint address */
#define HID_INT_EP 0x81
#define HID_INT_EP_SIZE 4
#define HID_INT_EP_INTERVAL 10
#define HID_INT_EP_INTERVAL 1
#define USBD_VID 0xffff
#define USBD_PID 0xffff
@@ -126,7 +126,7 @@ const uint8_t hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -239,7 +239,7 @@ static struct usbd_endpoint hid_in_ep = {
struct usbd_interface intf0;
void hid_mouse_init(uint8_t busid, uint32_t reg_base)
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
@@ -254,25 +254,65 @@ void hid_mouse_init(uint8_t busid, uint32_t reg_base)
mouse_cfg.y = 0;
}
/**
* @brief hid mouse test
* @pre none
* @param[in] none
* @retval none
*/
#define CURSOR_STEP 2U
#define CURSOR_WIDTH 20U
void draw_circle(uint8_t *buf)
{
static int32_t move_cnt = 0;
static uint8_t step_x_y = 0;
static int8_t x = 0, y = 0;
move_cnt++;
if (move_cnt > CURSOR_WIDTH) {
step_x_y++;
step_x_y = step_x_y % 4;
move_cnt = 0;
}
switch (step_x_y) {
case 0: {
y = 0;
x = CURSOR_STEP;
} break;
case 1: {
x = 0;
y = CURSOR_STEP;
} break;
case 2: {
y = 0;
x = (int8_t)(-CURSOR_STEP);
} break;
case 3: {
x = 0;
y = (int8_t)(-CURSOR_STEP);
} break;
}
buf[0] = 0;
buf[1] = x;
buf[2] = y;
buf[3] = 0;
}
/* https://cps-check.com/cn/polling-rate-check */
void hid_mouse_test(uint8_t busid)
{
if(usb_device_is_configured(busid) == false) {
return;
}
int counter = 0;
while (counter < 1000) {
/*!< move mouse pointer */
mouse_cfg.x += 40;
mouse_cfg.y += 0;
int ret = usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
if (ret < 0) {
return;
}
draw_circle((uint8_t *)&mouse_cfg);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}

View File

@@ -0,0 +1,331 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_hid.h"
/*!< endpoint address */
#define HID_INT_EP 0x81
#define HID_INT_EP_SIZE 4
#define HID_INT_EP_INTERVAL 1
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
/*!< config descriptor size */
#define USB_HID_CONFIG_DESC_SIZ 34
/*!< report descriptor size */
#define HID_MOUSE_REPORT_DESC_SIZE 74
/*!< global descriptor */
const uint8_t hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01, USB_CONFIG_REMOTE_WAKEUP | USB_CONFIG_SELF_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x02, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_MOUSE_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x26, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'H', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'D', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
/*!< hid mouse report descriptor */
static const uint8_t hid_mouse_report_desc[HID_MOUSE_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x02, // USAGE (Mouse)
0xA1, 0x01, // COLLECTION (Application)
0x09, 0x01, // USAGE (Pointer)
0xA1, 0x00, // COLLECTION (Physical)
0x05, 0x09, // USAGE_PAGE (Button)
0x19, 0x01, // USAGE_MINIMUM (Button 1)
0x29, 0x03, // USAGE_MAXIMUM (Button 3)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x95, 0x03, // REPORT_COUNT (3)
0x75, 0x01, // REPORT_SIZE (1)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x05, // REPORT_SIZE (5)
0x81, 0x01, // INPUT (Cnst,Var,Abs)
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x30, // USAGE (X)
0x09, 0x31, // USAGE (Y)
0x09, 0x38,
0x15, 0x81, // LOGICAL_MINIMUM (-127)
0x25, 0x7F, // LOGICAL_MAXIMUM (127)
0x75, 0x08, // REPORT_SIZE (8)
0x95, 0x03, // REPORT_COUNT (2)
0x81, 0x06, // INPUT (Data,Var,Rel)
0xC0, 0x09,
0x3c, 0x05,
0xff, 0x09,
0x01, 0x15,
0x00, 0x25,
0x01, 0x75,
0x01, 0x95,
0x02, 0xb1,
0x22, 0x75,
0x06, 0x95,
0x01, 0xb1,
0x01, 0xc0 // END_COLLECTION
};
/*!< mouse report struct */
struct hid_mouse {
uint8_t buttons;
int8_t x;
int8_t y;
int8_t wheel;
};
/*!< mouse report */
static USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX struct hid_mouse mouse_cfg;
#define HID_STATE_IDLE 0
#define HID_STATE_BUSY 1
/*!< hid state ! Data can be sent only when state is idle */
static volatile uint8_t hid_state = HID_STATE_IDLE;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
hid_state = HID_STATE_IDLE;
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
/* function ------------------------------------------------------------------*/
static void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
hid_state = HID_STATE_IDLE;
}
/*!< endpoint call back */
static struct usbd_endpoint hid_in_ep = {
.ep_cb = usbd_hid_int_callback,
.ep_addr = HID_INT_EP
};
static struct usbd_interface intf0;
void hid_mouse_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, hid_descriptor);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_mouse_report_desc, HID_MOUSE_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
/*!< init mouse report data */
mouse_cfg.buttons = 0;
mouse_cfg.wheel = 0;
mouse_cfg.x = 0;
mouse_cfg.y = 0;
}
#define CURSOR_STEP 2U
#define CURSOR_WIDTH 20U
void draw_circle(uint8_t *buf)
{
static int32_t move_cnt = 0;
static uint8_t step_x_y = 0;
static int8_t x = 0, y = 0;
move_cnt++;
if (move_cnt > CURSOR_WIDTH) {
step_x_y++;
step_x_y = step_x_y % 4;
move_cnt = 0;
}
switch (step_x_y) {
case 0: {
y = 0;
x = CURSOR_STEP;
} break;
case 1: {
x = 0;
y = CURSOR_STEP;
} break;
case 2: {
y = 0;
x = (int8_t)(-CURSOR_STEP);
} break;
case 3: {
x = 0;
y = (int8_t)(-CURSOR_STEP);
} break;
}
buf[0] = 0;
buf[1] = x;
buf[2] = y;
buf[3] = 0;
}
/* https://cps-check.com/cn/polling-rate-check */
void hid_mouse_test(uint8_t busid)
{
static uint32_t count = 1000;
int ret;
if(usb_device_is_configured(busid) == false) {
return;
}
// if (gpio_read_pin(GPIO_PIN) == 1) {
// ret = usbd_send_remote_wakeup(busid);
// if (ret < 0) {
// return;
// }
// count = 5000;
// }
while (count) {
draw_circle((uint8_t *)&mouse_cfg);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, (uint8_t *)&mouse_cfg, 4);
while (hid_state == HID_STATE_BUSY) {
}
count--;
}
}

View File

@@ -145,7 +145,7 @@ const uint8_t midi_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -202,7 +202,7 @@ struct usbd_endpoint midi_in_ep = {
.ep_cb = usbd_midi_bulk_in
};
void midi_init(uint8_t busid, uint32_t reg_base)
void midi_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, midi_descriptor);
usbd_add_interface(busid, &intf0);

View File

@@ -94,7 +94,7 @@ const uint8_t msc_ram_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -154,12 +154,19 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *
return 0;
}
struct usbd_interface intf0;
static struct usbd_interface intf0;
void msc_ram_init(uint8_t busid, uint32_t reg_base)
void msc_ram_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, msc_ram_descriptor);
usbd_add_interface(busid, usbd_msc_init_intf(busid, &intf0, MSC_OUT_EP, MSC_IN_EP));
usbd_initialize(busid, reg_base, usbd_event_handler);
}
#if defined(CONFIG_USBDEV_MSC_POLLING)
void msc_ram_polling(uint8_t busid)
{
usbd_msc_polling(busid);
}
#endif

View File

@@ -97,7 +97,7 @@ const uint8_t msc_storage_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -154,7 +154,7 @@ int usbd_msc_sector_write(uint8_t busid, uint8_t lun, uint32_t sector, uint8_t *
return 0;
}
void msc_storage_init(uint8_t busid, uint32_t reg_base)
void msc_storage_init(uint8_t busid, uintptr_t reg_base)
{
rt_err_t res;

View File

@@ -120,7 +120,7 @@ void usbh_hid_callback(void *arg, int nbytes)
struct usbh_hid *hid_class = (struct usbh_hid *)arg;
if (nbytes > 0) {
for (size_t i = 0; i < nbytes; i++) {
for (int i = 0; i < nbytes; i++) {
USB_LOG_RAW("0x%02x ", hid_buffer[i]);
}
USB_LOG_RAW("nbytes:%d\r\n", nbytes);
@@ -254,38 +254,38 @@ delete:
}
#endif
#if TEST_USBH_CDC_ACM
void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
{
#if TEST_USBH_CDC_ACM
usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, cdc_acm_class);
#endif
}
void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
{
}
#endif
#if TEST_USBH_HID
void usbh_hid_run(struct usbh_hid *hid_class)
{
#if TEST_USBH_HID
usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, hid_class);
#endif
}
void usbh_hid_stop(struct usbh_hid *hid_class)
{
}
#endif
#if TEST_USBH_MSC
void usbh_msc_run(struct usbh_msc *msc_class)
{
#if TEST_USBH_MSC
usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, msc_class);
#endif
}
void usbh_msc_stop(struct usbh_msc *msc_class)
{
}
#endif
#if TEST_USBH_AUDIO
#error "commercial charge"
@@ -294,3 +294,26 @@ void usbh_msc_stop(struct usbh_msc *msc_class)
#if TEST_USBH_VIDEO
#error "commercial charge"
#endif
#if 0
#include "usbh_aoa.h"
static struct aoa_string_info deviceinfo = {
.acc_manufacturer = "CherryUSB",
.acc_model = "CherryUSB",
.acc_description = "Android Open Accessory CherryUSB",
.acc_version = "1.0",
.acc_uri = "http://developer.android.com/tools/adk/index.html",
.acc_serial = "CherryUSB"
};
int aoa_switch(int argc, char **argv)
{
struct usbh_hubport *hport = usbh_find_hubport(0, 1, 1);
usbh_aoa_switch(hport, &deviceinfo);
return 0;
}
SHELL_CMD_EXPORT_ALIAS(aoa_switch, aoa_switch, aoa_switch);
#endif

View File

@@ -9,6 +9,8 @@
#include "usbd_hid.h"
#include "cherryusb_mjpeg.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x86
@@ -224,7 +226,7 @@ const uint8_t video_audio_hid_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -267,7 +269,7 @@ static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_read_buffer[AUDIO_OUT_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t audio_write_buffer[AUDIO_IN_PACKET];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t video_packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
volatile bool video_tx_flag = 0;
volatile bool audio_tx_flag = 0;
@@ -331,8 +333,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
video_iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
video_iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -416,7 +420,7 @@ struct audio_entity_info audio_entity_table[] = {
.ep = AUDIO_OUT_EP },
};
void composite_init(uint8_t busid, uint32_t reg_base)
void composite_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_audio_hid_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
@@ -458,56 +462,30 @@ void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
memcpy(hid_write_buffer, sendbuffer, 8);
int ret = usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
if (ret < 0) {
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(hid_write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, hid_write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(video_packet_buffer, 0, sizeof(video_packet_buffer));
(void)packets;
memset(video_packet_buffer, 0, 40 * 1024);
while (1) {
if (video_tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), video_packet_buffer, &out_len);
#if 1
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, video_packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[0][0], &video_packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
} else {
video_iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &video_packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (video_iso_tx_busy) {
if (video_tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_h264.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -129,7 +131,7 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -180,8 +182,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -192,7 +196,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
void video_init(uint8_t busid, uint32_t reg_base)
void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
@@ -202,7 +206,7 @@ void video_init(uint8_t busid, uint32_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][40 * 1024];
void video_test(uint8_t busid)
{
@@ -210,40 +214,16 @@ void video_test(uint8_t busid)
uint32_t packets;
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
memset(packet_buffer, 0, sizeof(packet_buffer));
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_h264, sizeof(cherryusb_h264));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_mjpeg.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -34,7 +36,7 @@
#define MAX_BIT_RATE (unsigned long)(WIDTH * HEIGHT * 16 * CAM_FPS)
#define MAX_FRAME_SIZE (unsigned long)(WIDTH * HEIGHT * 2)
#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1,1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1))
#define VS_HEADER_SIZ (unsigned int)(VIDEO_SIZEOF_VS_INPUT_HEADER_DESC(1, 1) + VIDEO_SIZEOF_VS_FORMAT_MJPEG_DESC + VIDEO_SIZEOF_VS_FRAME_MJPEG_DESC(1))
#define USB_VIDEO_DESC_SIZ (unsigned long)(9 + \
VIDEO_VC_NOEP_DESCRIPTOR_LEN + \
@@ -129,7 +131,7 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -180,8 +182,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -192,7 +196,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
void video_init(uint8_t busid, uint32_t reg_base)
void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
@@ -202,48 +206,21 @@ void video_init(uint8_t busid, uint32_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(packet_buffer, 0, sizeof(packet_buffer));
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_mjpeg, sizeof(cherryusb_mjpeg));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -7,6 +7,8 @@
#include "usbd_video.h"
#include "cherryusb_yuyv.h"
#define MAX_PACKETS_IN_ONE_TRANSFER 1
#define VIDEO_IN_EP 0x81
#define VIDEO_INT_EP 0x83
@@ -131,7 +133,7 @@ const uint8_t video_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -182,8 +184,10 @@ void usbd_video_close(uint8_t busid, uint8_t intf)
void usbd_video_iso_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
//USB_LOG_RAW("actual in len:%d\r\n", nbytes);
iso_tx_busy = false;
if (usbd_video_stream_split_transfer(busid, ep)) {
/* one frame has done */
iso_tx_busy = false;
}
}
static struct usbd_endpoint video_in_ep = {
@@ -194,7 +198,7 @@ static struct usbd_endpoint video_in_ep = {
struct usbd_interface intf0;
struct usbd_interface intf1;
void video_init(uint8_t busid, uint32_t reg_base)
void video_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, video_descriptor);
usbd_add_interface(busid, usbd_video_init_intf(busid, &intf0, INTERVAL, MAX_FRAME_SIZE, MAX_PAYLOAD_SIZE));
@@ -204,48 +208,21 @@ void video_init(uint8_t busid, uint32_t reg_base)
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[40 * 1024];
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t packet_buffer[2][MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE];
void video_test(uint8_t busid)
{
uint32_t out_len;
uint32_t packets;
memset(packet_buffer, 0, sizeof(packet_buffer));
(void)packets;
memset(packet_buffer, 0, 40 * 1024);
while (1) {
if (tx_flag) {
packets = usbd_video_payload_fill(busid, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv), packet_buffer, &out_len);
#if 1
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, packet_buffer, out_len);
usbd_video_stream_start_write(busid, VIDEO_IN_EP, &packet_buffer[0][0], &packet_buffer[1][0], MAX_PACKETS_IN_ONE_TRANSFER * MAX_PAYLOAD_SIZE, (uint8_t *)cherryusb_yuyv, sizeof(cherryusb_yuyv));
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
#else
/* dwc2 must use this method */
for (uint32_t i = 0; i < packets; i++) {
if (i == (packets - 1)) {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], out_len - (packets - 1) * MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
} else {
iso_tx_busy = true;
usbd_ep_start_write(busid, VIDEO_IN_EP, &packet_buffer[i * MAX_PAYLOAD_SIZE], MAX_PAYLOAD_SIZE);
while (iso_tx_busy) {
if (tx_flag == 0) {
break;
}
}
}
}
#endif
}
}
}

View File

@@ -0,0 +1,383 @@
/*
* Copyright (c) 2024, sakumisu
*
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_hid.h"
#define USBD_VID 0xffff
#define USBD_PID 0xffff
#define USBD_MAX_POWER 100
#define USBD_LANGID_STRING 1033
#define HID_INT_EP 0x81
#define HID_INT_EP_SIZE 8
#define HID_INT_EP_INTERVAL 10
#define USB_HID_CONFIG_DESC_SIZ (34 + 9)
#define HID_KEYBOARD_REPORT_DESC_SIZE 63
#define USBD_WEBUSB_VENDOR_CODE (0x22)
#define USBD_WINUSB_VENDOR_CODE (0x21)
#define USBD_WINUSB_DESC_SET_LEN (0xB2)
#define URL_DESCRIPTOR_LENGTH (3 + 36)
#define USBD_WEBUSB_INTF_NUM 0x01
#define WEBUSB_URL_STRINGS \
'g', 'i', 't', 'h', 'u', 'b', '.', 'c', 'o', 'm', '/', \
'c', 'h', 'e', 'r', 'r', 'y', '-', 'e', 'm', 'b', 'e', 'd', 'd', 'e', 'd', '/', 'C', 'h', 'e', 'r', 'r', 'y', 'U', 'S', 'B',
const uint8_t USBD_WinUSBDescriptorSetDescriptor[USBD_WINUSB_DESC_SET_LEN] = {
// Microsoft OS 2.0 描述符集标头
0x0A, 0x00, // Descriptor size (10 bytes)
0x00, 0x00, // MS OS 2.0 descriptor set header
0x00, 0x00, 0x03, 0x06, // Windows version (8.1) (0x06030000)
USBD_WINUSB_DESC_SET_LEN, 0x00, // Size, MS OS 2.0 descriptor set
// Microsoft OS 2.0 配置子集标头
0x08, 0x00, // wLength
0x01, 0x00, // wDescriptorType
0x00, // 适用于配置 1
0x00, // bReserved
0XA8, 0X00, // Size, MS OS 2.0 configuration subset
// Microsoft OS 2.0 功能子集头
0x08, 0x00, // Descriptor size (8 bytes)
0x02, 0x00, // MS OS 2.0 function subset header
USBD_WEBUSB_INTF_NUM, // bFirstInterface
0x00, // 必须设置为 0
0xA0, 0x00,
// Microsoft OS 2.0 兼容 ID 描述符
// 兼容 ID 描述符告诉 Windows 此设备与 WinUSB 驱动程序兼容
0x14, 0x00, // wLength 20
0x03, 0x00, // MS_OS_20_FEATURE_COMPATIBLE_ID
'W', 'I', 'N', 'U', 'S', 'B', 0x00, 0x00,
0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
// Microsoft OS 2.0 注册表属性描述符
// 注册表属性分配设备接口 GUID
0x84, 0x00, //wLength: 132
0x04, 0x00, // wDescriptorType: MS_OS_20_FEATURE_REG_PROPERTY: 0x04 (Table 9)
0x07, 0x00, //wPropertyDataType: REG_MULTI_SZ (Table 15)
0x2a, 0x00, //wPropertyNameLength:
//bPropertyName: “DeviceInterfaceGUID”
'D', 0x00, 'e', 0x00, 'v', 0x00, 'i', 0x00, 'c', 0x00, 'e', 0x00, 'I', 0x00, 'n', 0x00, 't', 0x00, 'e', 0x00,
'r', 0x00, 'f', 0x00, 'a', 0x00, 'c', 0x00, 'e', 0x00, 'G', 0x00, 'U', 0x00, 'I', 0x00, 'D', 0x00, 's', 0x00,
0x00, 0x00,
0x50, 0x00, // wPropertyDataLength
//bPropertyData: “{975F44D9-0D08-43FD-8B3E-127CA8AFFF9D}”.
'{', 0x00, '9', 0x00, 'd', 0x00, '7', 0x00, 'd', 0x00, 'e', 0x00, 'b', 0x00, 'b', 0x00, 'c', 0x00, '-', 0x00,
'c', 0x00, '8', 0x00, '5', 0x00, 'd', 0x00, '-', 0x00, '1', 0x00, '1', 0x00, 'd', 0x00, '1', 0x00, '-', 0x00,
'9', 0x00, 'e', 0x00, 'b', 0x00, '4', 0x00, '-', 0x00, '0', 0x00, '0', 0x00, '6', 0x00, '0', 0x00, '0', 0x00,
'8', 0x00, 'c', 0x00, '3', 0x00, 'a', 0x00, '1', 0x00, '9', 0x00, 'a', 0x00, '}', 0x00, 0x00, 0x00, 0x00, 0x00
};
const uint8_t USBD_WebUSBURLDescriptor[URL_DESCRIPTOR_LENGTH] = {
URL_DESCRIPTOR_LENGTH,
WEBUSB_URL_TYPE,
WEBUSB_URL_SCHEME_HTTPS,
WEBUSB_URL_STRINGS
};
#define USBD_BOS_WTOTALLENGTH 0x39
#define LANDING_PAGE 0x01
uint8_t USBD_BinaryObjectStoreDescriptor[USBD_BOS_WTOTALLENGTH] = {
// BOS描述符
0x05, // bLength 固长为5
0x0F, // bDescriptorType 固定为15
USBD_BOS_WTOTALLENGTH, 0x00, // wTotalLength BOS描述符的总大小
0x02, // bNumDeviceCaps BOS描述符中独立设备功能特性描述符的数量
// WebUSB 平台功能描述符
0x18, // Descriptor size (24 bytes)
0x10, // Descriptor type (Device Capability) 设备功能描述符
0x05, // Capability type (Platform) 平台描述符
0x00, // Reserved
// WebUSB Platform Capability ID (3408b638-09a9-47a0-8bfd-a0768815b665)
// 平台功能 UUID 将此标识为WebUSB 平台功能描述符,它提供有关设备的基本信息
0x38, 0xB6, 0x08, 0x34,
0xA9, 0x09,
0xA0, 0x47,
0x8B, 0xFD,
0xA0, 0x76, 0x88, 0x15, 0xB6, 0x65,
0x00, 0x01, // WebUSB version 1.0
USBD_WEBUSB_VENDOR_CODE, // Vendor-assigned WebUSB request code
LANDING_PAGE, // Landing page
// Microsoft 平台功能描述符
// 标头
0x1C, // Descriptor size (28 bytes)
0x10, // Descriptor type (Device Capability)
0x05, // Capability type (Platform)
0x00, // Reserved
0xDF, 0x60, 0xDD, 0xD8, /* PlatformCapabilityUUID */
0x89, 0x45, 0xC7, 0x4C,
0x9C, 0xD2, 0x65, 0x9D,
0x9E, 0x64, 0x8A, 0x9F,
// 描述符集信息结构
0x00, 0x00, 0x03, 0x06, /* >= Win 8.1 * dwWindowsVersion 最低兼容 Windows 版本 */
USBD_WINUSB_DESC_SET_LEN, 0X00, /* wDescriptorSetTotalLength */
USBD_WINUSB_VENDOR_CODE, /* bVendorCode */
0X00 /* bAltEnumCode */
};
struct usb_webusb_descriptor webusb_url_desc = {
.vendor_code = USBD_WEBUSB_VENDOR_CODE,
.string = USBD_WebUSBURLDescriptor,
.string_len = USBD_WINUSB_DESC_SET_LEN
};
struct usb_msosv2_descriptor msosv2_desc = {
.vendor_code = USBD_WINUSB_VENDOR_CODE,
.compat_id = USBD_WinUSBDescriptorSetDescriptor,
.compat_id_len = USBD_WINUSB_DESC_SET_LEN,
};
struct usb_bos_descriptor bos_desc = {
.string = USBD_BinaryObjectStoreDescriptor,
.string_len = USBD_BOS_WTOTALLENGTH
};
static const uint8_t webusb_hid_descriptor[] = {
USB_DEVICE_DESCRIPTOR_INIT(USB_2_1, 0x00, 0x00, 0x00, USBD_VID, USBD_PID, 0x0002, 0x01),
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER),
/************** Descriptor of Joystick Mouse interface ****************/
/* 09 */
0x09, /* bLength: Interface Descriptor size */
USB_DESCRIPTOR_TYPE_INTERFACE, /* bDescriptorType: Interface descriptor type */
0x00, /* bInterfaceNumber: Number of Interface */
0x00, /* bAlternateSetting: Alternate setting */
0x01, /* bNumEndpoints */
0x03, /* bInterfaceClass: HID */
0x01, /* bInterfaceSubClass : 1=BOOT, 0=no boot */
0x01, /* nInterfaceProtocol : 0=none, 1=keyboard, 2=mouse */
0, /* iInterface: Index of string descriptor */
/******************** Descriptor of Joystick Mouse HID ********************/
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
/******************** Descriptor of Mouse endpoint ********************/
/* 27 */
0x07, /* bLength: Endpoint Descriptor size */
USB_DESCRIPTOR_TYPE_ENDPOINT, /* bDescriptorType: */
HID_INT_EP, /* bEndpointAddress: Endpoint Address (IN) */
0x03, /* bmAttributes: Interrupt endpoint */
HID_INT_EP_SIZE, /* wMaxPacketSize: 4 Byte max */
0x00,
HID_INT_EP_INTERVAL, /* bInterval: Polling Interval */
/* 34 */
USB_INTERFACE_DESCRIPTOR_INIT(USBD_WEBUSB_INTF_NUM, 0x00, 0x00, 0xff, 0x00, 0x00, 0x00),
///////////////////////////////////////
/// string0 descriptor
///////////////////////////////////////
USB_LANGID_INIT(USBD_LANGID_STRING),
///////////////////////////////////////
/// string1 descriptor
///////////////////////////////////////
0x14, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
///////////////////////////////////////
/// string2 descriptor
///////////////////////////////////////
0x26, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'C', 0x00, /* wcChar0 */
'h', 0x00, /* wcChar1 */
'e', 0x00, /* wcChar2 */
'r', 0x00, /* wcChar3 */
'r', 0x00, /* wcChar4 */
'y', 0x00, /* wcChar5 */
'U', 0x00, /* wcChar6 */
'S', 0x00, /* wcChar7 */
'B', 0x00, /* wcChar8 */
' ', 0x00, /* wcChar9 */
'H', 0x00, /* wcChar10 */
'I', 0x00, /* wcChar11 */
'D', 0x00, /* wcChar12 */
' ', 0x00, /* wcChar13 */
'D', 0x00, /* wcChar14 */
'E', 0x00, /* wcChar15 */
'M', 0x00, /* wcChar16 */
'O', 0x00, /* wcChar17 */
///////////////////////////////////////
/// string3 descriptor
///////////////////////////////////////
0x16, /* bLength */
USB_DESCRIPTOR_TYPE_STRING, /* bDescriptorType */
'2', 0x00, /* wcChar0 */
'0', 0x00, /* wcChar1 */
'2', 0x00, /* wcChar2 */
'2', 0x00, /* wcChar3 */
'1', 0x00, /* wcChar4 */
'2', 0x00, /* wcChar5 */
'3', 0x00, /* wcChar6 */
'4', 0x00, /* wcChar7 */
'5', 0x00, /* wcChar8 */
'6', 0x00, /* wcChar9 */
#ifdef CONFIG_USB_HS
///////////////////////////////////////
/// device qualifier descriptor
///////////////////////////////////////
0x0a,
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
0x00,
0x02,
0x00,
0x00,
0x00,
0x40,
0x00,
0x00,
#endif
0x00
};
/* USB HID device Configuration Descriptor */
static uint8_t hid_desc[9] __ALIGN_END = {
/* 18 */
0x09, /* bLength: HID Descriptor size */
HID_DESCRIPTOR_TYPE_HID, /* bDescriptorType: HID */
0x11, /* bcdHID: HID Class Spec release number */
0x01,
0x00, /* bCountryCode: Hardware target country */
0x01, /* bNumDescriptors: Number of HID class descriptors to follow */
0x22, /* bDescriptorType */
HID_KEYBOARD_REPORT_DESC_SIZE, /* wItemLength: Total length of Report descriptor */
0x00,
};
static const uint8_t hid_keyboard_report_desc[HID_KEYBOARD_REPORT_DESC_SIZE] = {
0x05, 0x01, // USAGE_PAGE (Generic Desktop)
0x09, 0x06, // USAGE (Keyboard)
0xa1, 0x01, // COLLECTION (Application)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0xe0, // USAGE_MINIMUM (Keyboard LeftControl)
0x29, 0xe7, // USAGE_MAXIMUM (Keyboard Right GUI)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0x01, // LOGICAL_MAXIMUM (1)
0x75, 0x01, // REPORT_SIZE (1)
0x95, 0x08, // REPORT_COUNT (8)
0x81, 0x02, // INPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x08, // REPORT_SIZE (8)
0x81, 0x03, // INPUT (Cnst,Var,Abs)
0x95, 0x05, // REPORT_COUNT (5)
0x75, 0x01, // REPORT_SIZE (1)
0x05, 0x08, // USAGE_PAGE (LEDs)
0x19, 0x01, // USAGE_MINIMUM (Num Lock)
0x29, 0x05, // USAGE_MAXIMUM (Kana)
0x91, 0x02, // OUTPUT (Data,Var,Abs)
0x95, 0x01, // REPORT_COUNT (1)
0x75, 0x03, // REPORT_SIZE (3)
0x91, 0x03, // OUTPUT (Cnst,Var,Abs)
0x95, 0x06, // REPORT_COUNT (6)
0x75, 0x08, // REPORT_SIZE (8)
0x15, 0x00, // LOGICAL_MINIMUM (0)
0x25, 0xFF, // LOGICAL_MAXIMUM (255)
0x05, 0x07, // USAGE_PAGE (Keyboard)
0x19, 0x00, // USAGE_MINIMUM (Reserved (no event indicated))
0x29, 0x65, // USAGE_MAXIMUM (Keyboard Application)
0x81, 0x00, // INPUT (Data,Ary,Abs)
0xc0 // END_COLLECTION
};
#define HID_STATE_IDLE 0
#define HID_STATE_BUSY 1
/*!< hid state ! Data can be sent only when state is idle */
static volatile uint8_t hid_state = HID_STATE_IDLE;
static void usbd_event_handler(uint8_t busid, uint8_t event)
{
switch (event) {
case USBD_EVENT_RESET:
break;
case USBD_EVENT_CONNECTED:
break;
case USBD_EVENT_DISCONNECTED:
break;
case USBD_EVENT_RESUME:
break;
case USBD_EVENT_SUSPEND:
break;
case USBD_EVENT_CONFIGURED:
hid_state = HID_STATE_IDLE;
break;
case USBD_EVENT_SET_REMOTE_WAKEUP:
break;
case USBD_EVENT_CLR_REMOTE_WAKEUP:
break;
default:
break;
}
}
void usbd_hid_int_callback(uint8_t busid, uint8_t ep, uint32_t nbytes)
{
hid_state = HID_STATE_IDLE;
}
static struct usbd_endpoint hid_in_ep = {
.ep_cb = usbd_hid_int_callback,
.ep_addr = HID_INT_EP
};
static struct usbd_interface intf0;
void webusb_hid_keyboard_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, webusb_hid_descriptor);
usbd_bos_desc_register(busid, &bos_desc);
usbd_msosv2_desc_register(busid, &msosv2_desc);
usbd_webusb_desc_register(busid, &webusb_url_desc);
usbd_add_interface(busid, usbd_hid_init_intf(busid, &intf0, hid_keyboard_report_desc, HID_KEYBOARD_REPORT_DESC_SIZE));
usbd_add_endpoint(busid, &hid_in_ep);
usbd_initialize(busid, reg_base, usbd_event_handler);
}
USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[64];
void hid_keyboard_test(uint8_t busid)
{
const uint8_t sendbuffer[8] = { 0x00, 0x00, HID_KBD_USAGE_A, 0x00, 0x00, 0x00, 0x00, 0x00 };
if(usb_device_is_configured(busid) == false) {
return;
}
memcpy(write_buffer, sendbuffer, 8);
hid_state = HID_STATE_BUSY;
usbd_ep_start_write(busid, HID_INT_EP, write_buffer, 8);
while (hid_state == HID_STATE_BUSY) {
}
}

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
#define WCID_VENDOR_CODE 0x17
@@ -151,18 +151,16 @@ __ALIGN_BEGIN const uint8_t WINUSB_IF1_WCIDProperties [142] __ALIGN_END = {
const uint8_t *WINUSB_IFx_WCIDProperties[] = {
WINUSB_IF0_WCIDProperties,
#if DOUBLE_WINUSB == 1
WINUSB_IF1_WCIDProperties,
#endif
};
struct usb_msosv1_descriptor msosv1_desc = {
.string = WCID_StringDescriptor_MSOS,
.vendor_code = WCID_VENDOR_CODE,
.compat_id = WINUSB_WCIDDescriptor,
#if DOUBLE_WINUSB == 0
.comp_id_property = &WINUSB_IF0_WCIDProperties,
#else
.comp_id_property = WINUSB_IFx_WCIDProperties,
#endif
};
#define WINUSB_IN_EP 0x81
@@ -328,7 +326,7 @@ const uint8_t winusb_descriptor[] = {
0x02,
0x01,
0x40,
0x01,
0x00,
0x00,
#endif
0x00
@@ -446,7 +444,7 @@ struct usbd_interface intf1;
#endif
void winusb_init(uint8_t busid, uint32_t reg_base)
void winusb_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusb_descriptor);
usbd_msosv1_desc_register(busid, &msosv1_desc);

View File

@@ -4,7 +4,7 @@
* SPDX-License-Identifier: Apache-2.0
*/
#include "usbd_core.h"
#include "usbd_cdc.h"
#include "usbd_cdc_acm.h"
#define WINUSB_IN_EP 0x81
#define WINUSB_OUT_EP 0x02
@@ -219,7 +219,7 @@ const uint8_t winusbv2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
/* End */
@@ -318,7 +318,7 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
void winusbv2_init(uint8_t busid, uint32_t reg_base)
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusbv2_descriptor);
usbd_bos_desc_register(busid, &bos_desc);

View File

@@ -255,7 +255,7 @@ const uint8_t winusbv2_descriptor[] = {
0x00,
0x00,
0x40,
0x01,
0x00,
0x00,
#endif
/* End */
@@ -422,7 +422,7 @@ struct usb_bos_descriptor bos_desc = {
.string_len = USBD_BOS_WTOTALLENGTH
};
void winusbv2_init(uint8_t busid, uint32_t reg_base)
void winusbv2_init(uint8_t busid, uintptr_t reg_base)
{
usbd_desc_register(busid, winusbv2_descriptor);
usbd_bos_desc_register(busid, &bos_desc);