From cd404022b45f77a3f552c3e19924439ee1a9050f Mon Sep 17 00:00:00 2001 From: Ricard Rosson Date: Sat, 11 Jul 2026 05:38:28 +0100 Subject: [PATCH] rp23xx/raspberrypi-pico-2-w: CDC-ACM + CDC-NCM composite USB device Add a composite USB device that presents a CDC-ACM serial console and a CDC-NCM network interface (eth0) at once, for the Pico 2 W access device: the host gets a console and a USB NIC over a single connection. The two classes must use disjoint endpoint numbers or they collide, so board_composite_connect() assigns CDC-ACM 1/2/3 and CDC-NCM 4/5/6. Build the new rp23xx_composite.c under CONFIG_USBDEV_COMPOSITE (CMake and Make.defs). The common bringup optionally autostarts the "portalup" helper (CONFIG_EXAMPLES_PORTALUP) which connects the composite, brings up the interfaces and starts the mDNS responder. Assisted-by: Claude (Anthropic Claude Code) Signed-off-by: Ricard Rosson --- .../rp23xx/common/src/rp23xx_common_bringup.c | 26 ++++ .../raspberrypi-pico-2-w/src/CMakeLists.txt | 4 + .../rp23xx/raspberrypi-pico-2-w/src/Make.defs | 4 + .../src/rp23xx_composite.c | 123 ++++++++++++++++++ 4 files changed, 157 insertions(+) create mode 100644 boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c diff --git a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c index 10b941ce3c6..75cb29a9238 100644 --- a/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c +++ b/boards/arm/rp23xx/common/src/rp23xx_common_bringup.c @@ -28,6 +28,11 @@ #include #include #include +#ifdef CONFIG_EXAMPLES_PORTALUP +# include +# include +# include +#endif #include @@ -74,6 +79,11 @@ int rp23xx_common_bringup(void) { int ret = 0; +#ifdef CONFIG_EXAMPLES_PORTALUP + FAR char *portalup_argv[2]; + pid_t portalup_pid; +#endif + #ifdef CONFIG_RP23XX_I2C_DRIVER #ifdef CONFIG_RP23XX_I2C0 ret = board_i2cdev_initialize(0); @@ -520,5 +530,21 @@ int rp23xx_common_bringup(void) } #endif + +#ifdef CONFIG_EXAMPLES_PORTALUP + /* Autostart the access-device boot helper: bring up wlan0 and start the + * mDNS responder so the board is reachable by name at boot. + */ + + portalup_argv[0] = "portalup"; + portalup_argv[1] = NULL; + + if (posix_spawn(&portalup_pid, "portalup", NULL, NULL, + portalup_argv, NULL) != 0) + { + syslog(LOG_ERR, "ERROR: failed to spawn portalup: %d\n", errno); + } +#endif + return ret; } diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt index 7f459ff9cef..7c2dd142f34 100644 --- a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/CMakeLists.txt @@ -38,6 +38,10 @@ if(CONFIG_BOARDCTL) list(APPEND SRCS rp23xx_appinit.c) endif() +if(CONFIG_USBDEV_COMPOSITE) + list(APPEND SRCS rp23xx_composite.c) +endif() + target_sources(board PRIVATE ${SRCS}) if(CONFIG_BOOT_RUNFROMFLASH) diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs index 6af8d704a88..c31c11f4054 100644 --- a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/Make.defs @@ -89,3 +89,7 @@ distclean:: $(call DELFILE, board$(DELIM)cyw43439.firmware.image) endif + +ifeq ($(CONFIG_USBDEV_COMPOSITE),y) +CSRCS += rp23xx_composite.c +endif diff --git a/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c new file mode 100644 index 00000000000..8dd9a8e4b61 --- /dev/null +++ b/boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c @@ -0,0 +1,123 @@ +/**************************************************************************** + * boards/arm/rp23xx/raspberrypi-pico-2-w/src/rp23xx_composite.c + * + * SPDX-License-Identifier: Apache-2.0 + * + * Licensed to the Apache Software Foundation (ASF) under one or more + * contributor license agreements. See the NOTICE file distributed with + * this work for additional information regarding copyright ownership. The + * ASF licenses this file to you under the Apache License, Version 2.0 (the + * "License"); you may not use this file except in compliance with the + * License. You may obtain a copy of the License at + * + * http://www.apache.org/licenses/LICENSE-2.0 + * + * Unless required by applicable law or agreed to in writing, software + * distributed under the License is distributed on an "AS IS" BASIS, WITHOUT + * WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. See the + * License for the specific language governing permissions and limitations + * under the License. + * + ****************************************************************************/ + +/**************************************************************************** + * Included Files + ****************************************************************************/ + +#include +#include +#include +#include + +#include +#include + +#ifdef CONFIG_CDCACM_COMPOSITE +# include +#endif +#ifdef CONFIG_CDCNCM_COMPOSITE +# include +#endif + +#if defined(CONFIG_BOARDCTL_USBDEVCTRL) && defined(CONFIG_USBDEV_COMPOSITE) + +/**************************************************************************** + * Public Functions + ****************************************************************************/ + +/**************************************************************************** + * Name: board_composite_initialize + ****************************************************************************/ + +int board_composite_initialize(int port) +{ + return OK; +} + +/**************************************************************************** + * Name: board_composite_connect + * + * Description: + * Connect the CDC/ACM serial console + CDC/NCM network composite device. + * The two classes use disjoint endpoint numbers (ACM: 1/2/3, NCM: 4/5/6) + * so they can coexist in one configuration. + * + ****************************************************************************/ + +void *board_composite_connect(int port, int configid) +{ + if (configid == 0) + { + struct composite_devdesc_s dev[2]; + int ifnobase = 0; + int strbase = COMPOSITE_NSTRIDS; + int n = 0; + +#ifdef CONFIG_CDCACM_COMPOSITE + /* CDC/ACM serial console */ + + cdcacm_get_composite_devdesc(&dev[n]); + + dev[n].classobject = cdcacm_classobject; + dev[n].uninitialize = cdcacm_uninitialize; + + dev[n].devinfo.ifnobase = ifnobase; + dev[n].minor = 0; + dev[n].devinfo.strbase = strbase; + + dev[n].devinfo.epno[CDCACM_EP_INTIN_IDX] = 1; + dev[n].devinfo.epno[CDCACM_EP_BULKIN_IDX] = 2; + dev[n].devinfo.epno[CDCACM_EP_BULKOUT_IDX] = 3; + + ifnobase += dev[n].devinfo.ninterfaces; + strbase += dev[n].devinfo.nstrings; + n++; +#endif + +#ifdef CONFIG_CDCNCM_COMPOSITE + /* CDC/NCM network device */ + + cdcncm_get_composite_devdesc(&dev[n]); + + dev[n].devinfo.ifnobase = ifnobase; + dev[n].minor = 0; + dev[n].devinfo.strbase = strbase; + + dev[n].devinfo.epno[CDCNCM_EP_INTIN_IDX] = 4; + dev[n].devinfo.epno[CDCNCM_EP_BULKIN_IDX] = 5; + dev[n].devinfo.epno[CDCNCM_EP_BULKOUT_IDX] = 6; + + ifnobase += dev[n].devinfo.ninterfaces; + strbase += dev[n].devinfo.nstrings; + n++; +#endif + + return composite_initialize(composite_getdevdescs(), dev, n); + } + else + { + return NULL; + } +} + +#endif /* CONFIG_BOARDCTL_USBDEVCTRL && CONFIG_USBDEV_COMPOSITE */