Skip to content

Fix Sketch upload on Portenta C33 #183

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 3 commits into
base: main
Choose a base branch
from
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 1 addition & 1 deletion boards.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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
Expand Down
16 changes: 13 additions & 3 deletions cores/arduino/SerialUSB.h
Original file line number Diff line number Diff line change
Expand Up @@ -8,6 +8,11 @@

#include <zephyrSerial.h>

#if defined(CONFIG_USB_DEVICE_STACK_NEXT)
#include <zephyr/usb/usbd.h>
extern "C" struct usbd_context *usbd_init_device(usbd_msg_cb_t msg_cb);
#endif

namespace arduino {

class SerialUSB_ : public ZephyrSerial {
Expand All @@ -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

Expand Down
117 changes: 41 additions & 76 deletions cores/arduino/USB.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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();
Expand All @@ -43,77 +26,60 @@ static void _baudChangeHandler(const struct device *dev, uint32_t rate)
}

#if defined(CONFIG_USB_DEVICE_STACK_NEXT)

extern "C" {
#include <zephyr/usb/usbd.h>
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;
}
Expand All @@ -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);
Expand Down
2 changes: 1 addition & 1 deletion cores/arduino/main.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -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

Expand Down
5 changes: 5 additions & 0 deletions loader/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -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})

Expand Down
22 changes: 21 additions & 1 deletion loader/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -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 <zephyr/usb/usbd.h>
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;
Expand Down