diff --git a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.conf b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.conf index c59f3dc49430..78bd70dd95ca 100644 --- a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.conf +++ b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.conf @@ -34,3 +34,12 @@ CONFIG_REBOOT=y CONFIG_GPIO=y CONFIG_DK_LIBRARY=y + +# Bootloader firmware information +CONFIG_FW_INFO=y +CONFIG_SECURE_BOOT_STORAGE=y +CONFIG_DAP=y +CONFIG_DP_DRIVER=y + +CONFIG_CMSIS_DAP_DEVICE_VENDOR="Nordic Semiconductor ASA" +CONFIG_CMSIS_DAP_DEVICE_NAME="nrf91" diff --git a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.overlay b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.overlay index 79263b90b033..5efee746b0d4 100644 --- a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.overlay +++ b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp.overlay @@ -12,7 +12,7 @@ clk-gpios = <&gpio0 25 GPIO_ACTIVE_HIGH>; dio-gpios = <&gpio0 27 GPIO_ACTIVE_HIGH>; reset-gpios = <&gpio1 7 GPIO_ACTIVE_HIGH>; - port-write-cycles = <2>; + port-write-cycles = <12>; }; zephyr,user { diff --git a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp_readme.txt b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp_readme.txt index a3fa4e224f03..e4458f6c9185 100644 --- a/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp_readme.txt +++ b/applications/connectivity_bridge/boards/thingy91x_nrf5340_cpuapp_readme.txt @@ -5,6 +5,7 @@ This USB interface has the following functions: * Disk drive containing this file and others * COM ports for nRF91 debug, trace, and firmware update +* CMSIS-DAP 2.1 compliant debug probe interface for accessing the nRF91 SiP COM Ports ==================== diff --git a/applications/connectivity_bridge/src/modules/usb_bulk_commands.c b/applications/connectivity_bridge/src/modules/usb_bulk_commands.c index 55367dc403ba..74091c2cd0e4 100644 --- a/applications/connectivity_bridge/src/modules/usb_bulk_commands.c +++ b/applications/connectivity_bridge/src/modules/usb_bulk_commands.c @@ -8,6 +8,11 @@ #include #include #include +#include +#include +#include + +#include #include LOG_MODULE_REGISTER(bulk_commands, CONFIG_BRIDGE_BULK_LOG_LEVEL); @@ -16,10 +21,12 @@ LOG_MODULE_REGISTER(bulk_commands, CONFIG_BRIDGE_BULK_LOG_LEVEL); #define ID_DAP_VENDOR15 (0x80 + 15) #define ID_DAP_VENDOR16 (0x80 + 16) #define ID_DAP_VENDOR17 (0x80 + 17) +#define ID_DAP_VENDOR18 (0x80 + 18) #define ID_DAP_VENDOR_NRF53_BOOTLOADER ID_DAP_VENDOR14 #define ID_DAP_VENDOR_NRF91_BOOTLOADER ID_DAP_VENDOR15 #define ID_DAP_VENDOR_NRF53_RESET ID_DAP_VENDOR16 #define ID_DAP_VENDOR_NRF91_RESET ID_DAP_VENDOR17 +#define ID_DAP_VENDOR_NRF53_VERSION ID_DAP_VENDOR18 #define DAP_COMMAND_SUCCESS 0x00 #define DAP_COMMAND_FAILED 0xFF @@ -27,6 +34,8 @@ LOG_MODULE_REGISTER(bulk_commands, CONFIG_BRIDGE_BULK_LOG_LEVEL); #define NRF91_RESET_DURATION K_MSEC(100) #define NRF91_BUTTON1_DURATION K_MSEC(1000) +#define USB_BULK_PACKET_SIZE 64 + static const struct gpio_dt_spec reset_pin = GPIO_DT_SPEC_GET_OR(DT_PATH(zephyr_user), reset_gpios, {}); static const struct gpio_dt_spec button1_pin = @@ -93,12 +102,17 @@ static void nrf53_reset_work_handler(struct k_work *work) /* This is a placeholder implementation until proper CMSIS-DAP support is available. * Only custom vendor commands are supported. */ -size_t dap_execute_cmd(uint8_t *in, uint8_t *out) +size_t dap_execute_vendor_cmd(uint8_t *in, uint8_t *out) { LOG_DBG("got command 0x%02X", in[0]); - int ret; + + if (in[0] < ID_DAP_VENDOR0) { + return dap_execute_cmd(in, out); + } #if IS_ENABLED(CONFIG_RETENTION_BOOT_MODE) + int ret; + if (in[0] == ID_DAP_VENDOR_NRF53_BOOTLOADER) { ret = bootmode_set(BOOT_MODE_TYPE_BOOTLOADER); if (ret) { @@ -125,6 +139,24 @@ size_t dap_execute_cmd(uint8_t *in, uint8_t *out) } goto success; } + if (in[0] == ID_DAP_VENDOR_NRF53_VERSION) { + const struct fw_info *s0_info = fw_info_find(s0_address_read()); + const struct fw_info *s1_info = fw_info_find(s1_address_read()); + const size_t VERSION_STRING_LEN = USB_BULK_PACKET_SIZE - 2; + + __ASSERT_NO_MSG(s0_info != NULL); + __ASSERT_NO_MSG(s1_info != NULL); + int len = snprintf(out + 2, VERSION_STRING_LEN, + "S0: %u, S1: %u, app: " NCS_COMMIT_STRING, + s0_info->version, s1_info->version); + if (len < 0 || len >= VERSION_STRING_LEN) { + LOG_ERR("Failed to format version string"); + goto error; + } + out[0] = in[0]; + out[1] = len; + return len + 2; + } error: /* default reply: command failed */ diff --git a/applications/connectivity_bridge/src/modules/usb_bulk_interface.c b/applications/connectivity_bridge/src/modules/usb_bulk_interface.c index 650561e224c0..ac86c946c3b8 100644 --- a/applications/connectivity_bridge/src/modules/usb_bulk_interface.c +++ b/applications/connectivity_bridge/src/modules/usb_bulk_interface.c @@ -23,6 +23,8 @@ LOG_MODULE_REGISTER(MODULE, CONFIG_BRIDGE_BULK_LOG_LEVEL); /* needs to be included after defining logging config */ #include "usb_bulk_msosv2.h" +#include + #define USB_BULK_PACKET_SIZE 64 #define USB_BULK_PACKET_COUNT 4 @@ -41,7 +43,7 @@ static K_FIFO_DEFINE(dap_rx_queue); NET_BUF_POOL_FIXED_DEFINE(dapusb_rx_pool, USB_BULK_PACKET_COUNT, USB_BULK_PACKET_SIZE, 0, NULL); /* Execute CMSIS-DAP command and write reply into output buffer */ -size_t dap_execute_cmd(uint8_t *in, uint8_t *out); +size_t dap_execute_vendor_cmd(uint8_t *in, uint8_t *out); /* string descriptor for the interface */ #define DAP_IFACE_STR_DESC "CMSIS-DAP v2" @@ -172,7 +174,7 @@ static int dap_usb_process(void) struct net_buf *buf = k_fifo_get(&dap_rx_queue, K_FOREVER); uint8_t ep = dapusb_config.endpoint[DAP_USB_EP_IN_IDX].ep_addr; - len = dap_execute_cmd(buf->data, tx_buf); + len = dap_execute_vendor_cmd(buf->data, tx_buf); LOG_DBG("response length %u, starting with [0x%02X, 0x%02X]", len, tx_buf[0], tx_buf[1]); net_buf_unref(buf); @@ -196,6 +198,8 @@ static int dap_usb_thread_fn(const struct device *dev) return 0; } +const struct device *const swd_dev = DEVICE_DT_GET_ONE(zephyr_swdp_gpio); + K_THREAD_DEFINE(dap_usb_thread, CONFIG_BULK_USB_THREAD_STACK_SIZE, dap_usb_thread_fn, NULL, NULL, NULL, 5, 0, 0); @@ -208,11 +212,21 @@ static bool app_event_handler(const struct app_event_header *aeh) /* tell the rest of the system that we are busy. */ module_set_state(MODULE_STATE_READY); - /* Add MS OS 2.0 BOS descriptor to BOS structure */ + /* add MS OS 2.0 BOS descriptor to BOS structure. */ usb_bos_register_cap((void *)&bos_cap_msosv2); - /* Point interface index to string descriptor */ + /* point interface index to string descriptor. */ iface_string_desc_init(&dapusb_config); + if (!device_is_ready(swd_dev)) { + LOG_ERR("SWD device is not ready"); + } + + int ret = dap_setup(swd_dev); + + if (ret) { + LOG_ERR("Failed to initialize DAP controller, %d", ret); + } + /* tell the usb_cdc_handler we are done. */ module_set_state(MODULE_STATE_STANDBY); } diff --git a/applications/connectivity_bridge/sysbuild/mcuboot/boards/thingy91x_nrf5340_cpuapp.conf b/applications/connectivity_bridge/sysbuild/mcuboot/boards/thingy91x_nrf5340_cpuapp.conf index 37c7e95b15ca..8bbd4ddf9454 100644 --- a/applications/connectivity_bridge/sysbuild/mcuboot/boards/thingy91x_nrf5340_cpuapp.conf +++ b/applications/connectivity_bridge/sysbuild/mcuboot/boards/thingy91x_nrf5340_cpuapp.conf @@ -58,3 +58,5 @@ CONFIG_BOOT_SERIAL_IMG_GRP_IMAGE_STATE=y # Skip checks on the secondary image to make it possible to update MCUBoot on S1/S0 CONFIG_MCUBOOT_VERIFY_IMG_ADDRESS=n + +CONFIG_BOOT_SERIAL_NO_APPLICATION=y