diff --git a/CMakeLists.txt b/CMakeLists.txt index a1d6cbd..372fbe7 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -38,6 +38,12 @@ if(CONFIG_CTSHELL_PORT_ESP32) list(APPEND CTSHELL_DEFINITIONS "CONFIG_CTSHELL_PORT_ESP32=1") endif() +if(CONFIG_CTSHELL_PORT_CHERRYUSB) + list(APPEND ctshell_srcs "${CMAKE_CURRENT_SOURCE_DIR}/port/cherryusb/ctshell_cherryusb.c") + list(APPEND ctshell_incs "${CMAKE_CURRENT_SOURCE_DIR}/port/cherryusb") + list(APPEND CTSHELL_DEFINITIONS "CONFIG_CTSHELL_PORT_CHERRYUSB=1") +endif() + if(CONFIG_CTSHELL_USE_FS) list(APPEND CTSHELL_DEFINITIONS "CONFIG_CTSHELL_USE_FS=1") if(CONFIG_CTSHELL_USE_FS_FATFS) diff --git a/Kconfig b/Kconfig index 7516039..910f8cf 100644 --- a/Kconfig +++ b/Kconfig @@ -110,6 +110,10 @@ config CTSHELL_PORT_WINDOWS bool prompt "Windows(for test use)" +config CTSHELL_PORT_CHERRYUSB + bool + prompt "CherryUSB" + endchoice if CTSHELL_PORT_ESP32 diff --git a/port/cherryusb/README.md b/port/cherryusb/README.md new file mode 100644 index 0000000..ac98029 --- /dev/null +++ b/port/cherryusb/README.md @@ -0,0 +1,5 @@ +# Note + +You need to configure CherryUSB by yourself first. + +This port is modified from CherryUSB cdc acm template. diff --git a/port/cherryusb/ctshell_cherryusb.c b/port/cherryusb/ctshell_cherryusb.c new file mode 100644 index 0000000..0d8dd86 --- /dev/null +++ b/port/cherryusb/ctshell_cherryusb.c @@ -0,0 +1,242 @@ +/* + * Copyright (c) 2024, sakumisu + * Copyright (c) 2026, MDLZCOOL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#include "usbd_core.h" +#include "usbd_cdc_acm.h" +#include "ctshell_cherryusb.h" + +static ctshell_ctx_t shell_ctx; + +/*!< endpoint address */ +#define CDC_IN_EP 0x81 +#define CDC_OUT_EP 0x02 +#define CDC_INT_EP 0x83 + +#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 + CDC_ACM_DESCRIPTOR_LEN) + +#ifdef CONFIG_USB_HS +#define CDC_MAX_MPS 512 +#else +#define CDC_MAX_MPS 64 +#endif + +/*!< global descriptor */ +static const uint8_t cdc_descriptor[] = { + USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0xEF, 0x02, 0x01, USBD_VID, USBD_PID, 0x0100, 0x01), + USB_CONFIG_DESCRIPTOR_INIT(USB_CONFIG_SIZE, 0x02, 0x01, USB_CONFIG_BUS_POWERED, USBD_MAX_POWER), + CDC_ACM_DESCRIPTOR_INIT(0x00, CDC_INT_EP, CDC_OUT_EP, CDC_IN_EP, CDC_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 */ + 'C', 0x00, /* wcChar10 */ + 'D', 0x00, /* wcChar11 */ + 'C', 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, + 0x02, + 0x02, + 0x01, + 0x40, + 0x00, + 0x00, +#endif + 0x00 +}; + +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_buffer[2048]; /* 2048 is only for test speed , please use CDC_MAX_MPS for common*/ +USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t write_buffer[2048]; + +volatile bool ep_tx_busy_flag = false; + +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: + ep_tx_busy_flag = false; + /* setup first out ep read transfer */ + usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048); + break; + case USBD_EVENT_SET_REMOTE_WAKEUP: + break; + case USBD_EVENT_CLR_REMOTE_WAKEUP: + break; + + default: + break; + } +} + +void usbd_cdc_acm_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + for (uint32_t i = 0; i < nbytes; i++) { + ctshell_input(&shell_ctx, read_buffer[i]); + } + /* setup next out ep read transfer */ + usbd_ep_start_read(busid, CDC_OUT_EP, read_buffer, 2048); +} + +void usbd_cdc_acm_bulk_in(uint8_t busid, uint8_t ep, uint32_t nbytes) +{ + //USB_LOG_RAW("actual in len:%d\r\n", nbytes); + + if ((nbytes % usbd_get_ep_mps(busid, ep)) == 0 && nbytes) { + /* send zlp */ + usbd_ep_start_write(busid, CDC_IN_EP, NULL, 0); + } else { + ep_tx_busy_flag = false; + } +} + +/*!< endpoint call back */ +struct usbd_endpoint cdc_out_ep = { + .ep_addr = CDC_OUT_EP, + .ep_cb = usbd_cdc_acm_bulk_out +}; + +struct usbd_endpoint cdc_in_ep = { + .ep_addr = CDC_IN_EP, + .ep_cb = usbd_cdc_acm_bulk_in +}; + +static struct usbd_interface intf0; +static struct usbd_interface intf1; + +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 }; + + memcpy(&write_buffer[0], data, 10); + memset(&write_buffer[10], 'a', 2038); + + usbd_desc_register(busid, cdc_descriptor); + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf0)); + usbd_add_interface(busid, usbd_cdc_acm_init_intf(busid, &intf1)); + usbd_add_endpoint(busid, &cdc_out_ep); + usbd_add_endpoint(busid, &cdc_in_ep); + usbd_initialize(busid, reg_base, usbd_event_handler); +} + +volatile uint8_t dtr_enable = 0; + +void usbd_cdc_acm_set_dtr(uint8_t busid, uint8_t intf, bool dtr) +{ + if (dtr) { + dtr_enable = 1; + } else { + dtr_enable = 0; + } +} + +void cdc_acm_data_send_with_dtr_test(uint8_t busid) +{ + if (dtr_enable) { + ep_tx_busy_flag = true; + usbd_ep_start_write(busid, CDC_IN_EP, write_buffer, 2048); + while (ep_tx_busy_flag) { + } + } +} + +static uint8_t priv_busid; + +void shell_usb_write(const char *buf, uint16_t len, void *priv) +{ + if (!dtr_enable || len == 0) { + return; + } + uint16_t send_len = (len > 2048) ? 2048 : len; + uint32_t timeout = 0xFFFFF; + while (ep_tx_busy_flag && timeout > 0) { + timeout--; + } + if (timeout == 0) return; + memcpy(write_buffer, buf, send_len); + ep_tx_busy_flag = true; + usbd_ep_start_write(priv_busid, CDC_IN_EP, write_buffer, send_len); +} + +void ctshell_port_cherryusb_init(ctshell_ctx_t *ctx, uint8_t busid, uintptr_t reg_base) +{ + ctshell_io_t shell_io = { + .write = shell_usb_write, + }; + priv_busid = busid; + + ctshell_init(ctx, shell_io, NULL); + cdc_acm_init(busid, reg_base); +} \ No newline at end of file diff --git a/port/cherryusb/ctshell_cherryusb.h b/port/cherryusb/ctshell_cherryusb.h new file mode 100644 index 0000000..00e032d --- /dev/null +++ b/port/cherryusb/ctshell_cherryusb.h @@ -0,0 +1,19 @@ +/* + * Copyright (c) 2026, MDLZCOOL + * + * SPDX-License-Identifier: Apache-2.0 + */ +#pragma once + +#include "ctshell.h" +#include + +#ifdef __cplusplus +extern "C" { +#endif + +void ctshell_port_cherryusb_init(ctshell_ctx_t *ctx, uint8_t busid, uintptr_t reg_base); + +#ifdef __cplusplus +} +#endif