diff --git a/boards.txt b/boards.txt index dcaaa27c..204651f9 100644 --- a/boards.txt +++ b/boards.txt @@ -449,7 +449,7 @@ portentac33.upload.native_usb=true portentac33.upload.maximum_size=1966080 portentac33.upload.maximum_data_size=523624 portentac33.upload.address=0x100000 -portentac33.upload.dfuse=-Q +portentac33.upload.dfuse=-Q -w portentac33.bootloader.tool=dfu-util portentac33.bootloader.tool.default=dfu-util diff --git a/cores/arduino/SerialUSB.h b/cores/arduino/SerialUSB.h index be1377f8..80b9bde1 100644 --- a/cores/arduino/SerialUSB.h +++ b/cores/arduino/SerialUSB.h @@ -8,6 +8,11 @@ #include +#if defined(CONFIG_USB_DEVICE_STACK_NEXT) +#include +extern "C" struct usbd_context *usbd_init_device(usbd_msg_cb_t msg_cb); +#endif + namespace arduino { class SerialUSB_ : public ZephyrSerial { @@ -25,12 +30,17 @@ class SerialUSB_ : public ZephyrSerial { protected: uint32_t dtr = 0; uint32_t baudrate; - void _baudChangeHandler(); - static void _baudChangeDispatch(struct k_timer *timer); + static void baudChangeHandler(const struct device *dev, uint32_t rate); private: - struct k_timer baud_timer; bool started = false; + +#if defined(CONFIG_USB_DEVICE_STACK_NEXT) + struct usbd_context *_usbd; + int enable_usb_device_next(); + static void usbd_next_cb(struct usbd_context *const ctx, const struct usbd_msg *msg); + static int usb_disable(); +#endif }; } // namespace arduino diff --git a/cores/arduino/USB.cpp b/cores/arduino/USB.cpp index 60f5fc7a..d7288d23 100644 --- a/cores/arduino/USB.cpp +++ b/cores/arduino/USB.cpp @@ -13,28 +13,11 @@ #if ((DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm)) && (CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS)) const struct device *const usb_dev = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm, 0)); -void usb_status_cb(enum usb_dc_status_code cb_status, const uint8_t *param) { - (void)param; // unused - if (cb_status == USB_DC_CONFIGURED) { - - } -} - void __attribute__((weak)) _on_1200_bps() { NVIC_SystemReset(); } -void arduino::SerialUSB_::_baudChangeHandler() -{ - uart_line_ctrl_get(uart, UART_LINE_CTRL_BAUD_RATE, &baudrate); - if (baudrate == 1200) { - usb_disable(); - _on_1200_bps(); - } -} - -static void _baudChangeHandler(const struct device *dev, uint32_t rate) -{ +void arduino::SerialUSB_::baudChangeHandler(const struct device *dev, uint32_t rate) { (void)dev; // unused if (rate == 1200) { usb_disable(); @@ -43,77 +26,60 @@ static void _baudChangeHandler(const struct device *dev, uint32_t rate) } #if defined(CONFIG_USB_DEVICE_STACK_NEXT) - -extern "C" { - #include - struct usbd_context *usbd_init_device(usbd_msg_cb_t msg_cb); -} - -struct usbd_context *_usbd; - -int usb_disable() { - return usbd_disable(_usbd); +int arduino::SerialUSB_::usb_disable() { + //To avoid Cannot perform port reset: 1200-bps touch: setting DTR to OFF: protocol error + k_sleep(K_MSEC(100)); + return usbd_disable(Serial._usbd); } -static void usbd_next_cb(struct usbd_context *const ctx, const struct usbd_msg *msg) -{ - if (usbd_can_detect_vbus(ctx)) { - if (msg->type == USBD_MSG_VBUS_READY) { - usbd_enable(ctx); - } +void arduino::SerialUSB_::usbd_next_cb(struct usbd_context *const ctx, const struct usbd_msg *msg) { + if (usbd_can_detect_vbus(ctx)) { + if (msg->type == USBD_MSG_VBUS_READY) { + usbd_enable(ctx); + } - if (msg->type == USBD_MSG_VBUS_REMOVED) { - usbd_disable(ctx); - } - } + if (msg->type == USBD_MSG_VBUS_REMOVED) { + usbd_disable(ctx); + } + } - if (msg->type == USBD_MSG_CDC_ACM_LINE_CODING) { + if (msg->type == USBD_MSG_CDC_ACM_LINE_CODING) { uint32_t baudrate; - uart_line_ctrl_get(ctx->dev, UART_LINE_CTRL_BAUD_RATE, &baudrate); - _baudChangeHandler(nullptr, baudrate); - } + uart_line_ctrl_get(Serial.uart, UART_LINE_CTRL_BAUD_RATE, &baudrate); + Serial.baudChangeHandler(nullptr, baudrate); + } } -static int enable_usb_device_next(void) -{ - int err; - - //_usbd = usbd_init_device(usbd_next_cb); - _usbd = usbd_init_device(nullptr); - if (_usbd == NULL) { - return -ENODEV; - } - - if (!usbd_can_detect_vbus(_usbd)) { - err = usbd_enable(_usbd); - if (err) { - return err; - } - } - return 0; -} -#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ +int arduino::SerialUSB_::enable_usb_device_next(void) { + int err; -void arduino::SerialUSB_::_baudChangeDispatch(struct k_timer *timer) { - arduino::SerialUSB_* dev = (arduino::SerialUSB_*)k_timer_user_data_get(timer); - dev->_baudChangeHandler(); -} + _usbd = usbd_init_device(arduino::SerialUSB_::usbd_next_cb); + if (_usbd == NULL) { + return -ENODEV; + } + if (!usbd_can_detect_vbus(_usbd)) { + err = usbd_enable(_usbd); + if (err) { + return err; + } + } + return 0; +} +#endif /* defined(CONFIG_USB_DEVICE_STACK_NEXT) */ void arduino::SerialUSB_::begin(unsigned long baudrate, uint16_t config) { if (!started) { - #ifndef CONFIG_USB_DEVICE_STACK_NEXT +#ifndef CONFIG_USB_DEVICE_STACK_NEXT usb_enable(NULL); - #ifndef CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT - k_timer_init(&baud_timer, SerialUSB_::_baudChangeDispatch, NULL); - k_timer_user_data_set(&baud_timer, this); - k_timer_start(&baud_timer, K_MSEC(100), K_MSEC(100)); - #else - cdc_acm_dte_rate_callback_set(usb_dev, ::_baudChangeHandler); - #endif - #else +#ifndef CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT +#warning "Can't read CDC baud change, please enable CONFIG_CDC_ACM_DTE_RATE_CALLBACK_SUPPORT" +#else + cdc_acm_dte_rate_callback_set(usb_dev, SerialUSB_::baudChangeHandler); +#endif +#else enable_usb_device_next(); - #endif +#endif ZephyrSerial::begin(baudrate, config); started = true; } @@ -124,7 +90,6 @@ arduino::SerialUSB_::operator bool() { return dtr; } - size_t arduino::SerialUSB_::write(const uint8_t *buffer, size_t size) { if (!Serial) return 0; return arduino::ZephyrSerial::write(buffer, size); diff --git a/cores/arduino/main.cpp b/cores/arduino/main.cpp index 9359e745..533a3077 100644 --- a/cores/arduino/main.cpp +++ b/cores/arduino/main.cpp @@ -23,7 +23,7 @@ void __attribute__((weak))initVariant(void) { int main(void) { -#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_USB_CDC_ACM) +#if (DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && (CONFIG_USB_CDC_ACM || CONFIG_USBD_CDC_ACM_CLASS)) Serial.begin(115200); #endif diff --git a/loader/CMakeLists.txt b/loader/CMakeLists.txt index c62b3b3a..9cecfe1f 100644 --- a/loader/CMakeLists.txt +++ b/loader/CMakeLists.txt @@ -16,6 +16,11 @@ project(app LANGUAGES C CXX) add_subdirectory(${CMAKE_CURRENT_SOURCE_DIR}/blobs) +# for USB device stack NEXT +target_sources_ifdef(CONFIG_USB_DEVICE_STACK_NEXT app PRIVATE + ${CMAKE_CURRENT_LIST_DIR}/../cores/arduino/usb_device_descriptor.c +) + FILE(GLOB app_sources *.c) target_sources(app PRIVATE ${app_sources}) diff --git a/loader/main.c b/loader/main.c index 643da9d7..1d4ecf32 100644 --- a/loader/main.c +++ b/loader/main.c @@ -33,11 +33,31 @@ struct sketch_header_v1 { #define SKETCH_FLAG_LINKED 0x02 #define TARGET_HAS_USB_CDC_SHELL \ - DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_SHELL && CONFIG_USB_DEVICE_STACK + DT_NODE_HAS_PROP(DT_PATH(zephyr_user), cdc_acm) && CONFIG_SHELL && (CONFIG_USB_DEVICE_STACK || CONFIG_USB_DEVICE_STACK_NEXT) #if TARGET_HAS_USB_CDC_SHELL const struct device *const usb_dev = DEVICE_DT_GET(DT_PHANDLE_BY_IDX(DT_PATH(zephyr_user), cdc_acm, 0)); +#if CONFIG_USB_DEVICE_STACK_NEXT +#include +struct usbd_context *usbd_init_device(usbd_msg_cb_t msg_cb); +int usb_enable(usb_dc_status_callback status_cb) +{ + int err; + struct usbd_context *_usbd = usbd_init_device(NULL); + if (_usbd == NULL) { + return -ENODEV; + } + if (!usbd_can_detect_vbus(_usbd)) { + err = usbd_enable(_usbd); + if (err) { + return err; + } + } + return 0; +} +#endif + static int enable_shell_usb(void) { bool log_backend = CONFIG_SHELL_BACKEND_SERIAL_LOG_LEVEL > 0;