Skip to content

Commit 36daa53

Browse files
committed
samples: debug: add CMSIS DAP sample using USB HID as interface
Add cmsis dap sample using USB HID as interface. Signed-off-by: Johann Fischer <[email protected]>
1 parent 5685c38 commit 36daa53

File tree

6 files changed

+255
-0
lines changed

6 files changed

+255
-0
lines changed

samples/subsys/dap/CMakeLists.txt

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
# Copyright (c) 2023 Nordic Semiconductor ASA
2+
# SPDX-License-Identifier: Apache-2.0
3+
4+
cmake_minimum_required(VERSION 3.20.0)
5+
find_package(Zephyr REQUIRED HINTS $ENV{ZEPHYR_BASE})
6+
project(dap)
7+
8+
FILE(GLOB app_sources src/*.c)
9+
target_sources(app PRIVATE ${app_sources})

samples/subsys/dap/README.rst

Lines changed: 55 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,55 @@
1+
.. _dap-sample:
2+
3+
DAP Sample Application
4+
######################
5+
6+
Overview
7+
********
8+
9+
This sample app demonstrates use of a SWDP interface driver and CMSIS DAP
10+
controller through USB HID interface.
11+
12+
Requirements
13+
************
14+
15+
This sample requires simple circuit consisting of a few Dual-Supply Bus
16+
Transceivers connected to Arduino GPIOs, look for ARM microcontroller-based
17+
Hardware Interface Circuits (HICs) for detailed information.
18+
19+
Building and Running
20+
********************
21+
22+
In order for our debug adapter to be recognized by pyOCD we need to change
23+
Zephyr's VID/PID to IDs known to pyOCD, this is up to the user.
24+
The following commands build and flash DAP sample.
25+
26+
.. zephyr-app-commands::
27+
:zephyr-app: samples/subsys/dap
28+
:board: nrf52840dk_nrf52840
29+
:goals: flash
30+
:compact:
31+
32+
Connect HIC to the target and try some pyOCD commands, for example:
33+
34+
.. code-block:: console
35+
36+
pyocd commander -t nrf52840
37+
38+
0029527 W Board ID FE5D is not recognized [mbed_board]
39+
Connected to NRF52840 [Sleeping]: FE5D244DFE1F33DB
40+
pyocd> read32 0x20004f18 32
41+
20004f18: 20001160 2000244c 00000000 0000e407 | ..` .$L........|
42+
20004f28: ffffffff ffffffff 00000000 aaaaaaaa |................|
43+
pyocd> halt
44+
Successfully halted device
45+
pyocd> reg
46+
general registers:
47+
lr: 0x00009cdd r7: 0x00000000 (0)
48+
pc: 0x000033ca r8: 0x00000000 (0)
49+
r0: 0x00000000 (0) r9: 0x00000000 (0)
50+
r1: 0x20002854 (536881236) r10: 0x00000000 (0)
51+
r2: 0x20000be4 (536873956) r11: 0x00000000 (0)
52+
r3: 0x00000000 (0) r12: 0x00000000 (0)
53+
r4: 0x200017e8 (536877032) sp: 0x20002898
54+
r5: 0x20001867 (536877159) xpsr: 0x61000000 (1627389952)
55+
r6: 0x00000000 (0)

samples/subsys/dap/app.overlay

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
/*
2+
* Copyright (c) 2023 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
/ {
8+
dp0 {
9+
compatible = "zephyr,swdp-gpio";
10+
status = "okay";
11+
clk-gpios = <&arduino_header 10 GPIO_ACTIVE_HIGH>; /* D4 */
12+
dout-gpios = <&arduino_header 9 GPIO_ACTIVE_HIGH>; /* D3 */
13+
din-gpios = <&arduino_header 8 GPIO_PULL_UP>; /* D2 */
14+
dnoe-gpios = <&arduino_header 12 GPIO_ACTIVE_HIGH>; /* D6 */
15+
noe-gpios = <&arduino_header 11 GPIO_ACTIVE_HIGH>; /* D5 */
16+
reset-gpios = <&arduino_header 13 GPIO_ACTIVE_HIGH>; /* D7 */
17+
port-write-cycles = <2>;
18+
};
19+
};

samples/subsys/dap/prj.conf

Lines changed: 19 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
CONFIG_USB_DEVICE_STACK=y
2+
CONFIG_USB_DEVICE_PRODUCT="Zephyr CMSIS-DAP"
3+
CONFIG_USB_DEVICE_INITIALIZE_AT_BOOT=n
4+
5+
CONFIG_USB_DEVICE_HID=y
6+
CONFIG_ENABLE_HID_INT_OUT_EP=y
7+
CONFIG_HID_INTERRUPT_EP_MPS=64
8+
CONFIG_USB_HID_POLL_INTERVAL_MS=1
9+
10+
# Change to VID/PID from a known HIC or it will not be recognized.
11+
CONFIG_USB_DEVICE_VID=0x2fe3
12+
CONFIG_USB_DEVICE_PID=0x0204
13+
14+
CONFIG_DAP=y
15+
CONFIG_NET_BUF=y
16+
17+
CONFIG_LOG=y
18+
CONFIG_DAP_LOG_LEVEL_INF=y
19+
CONFIG_DP_DRIVER_LOG_LEVEL_INF=y

samples/subsys/dap/sample.yaml

Lines changed: 10 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
sample:
2+
name: DAP HID
3+
tests:
4+
sample.dap.hid:
5+
build_only: true
6+
platform_allow: nrf52840dk_nrf52840
7+
integration_platforms:
8+
- nrf52840dk_nrf52840
9+
depends_on: usb_device
10+
tags: usb

samples/subsys/dap/src/main.c

Lines changed: 143 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,143 @@
1+
/*
2+
* Copyright (c) 2023 Nordic Semiconductor ASA
3+
*
4+
* SPDX-License-Identifier: Apache-2.0
5+
*/
6+
7+
#include <zephyr/kernel.h>
8+
#include <zephyr/init.h>
9+
#include <zephyr/device.h>
10+
#include <zephyr/usb/usb_device.h>
11+
#include <zephyr/usb/class/usb_hid.h>
12+
#include <zephyr/net/buf.h>
13+
14+
#include <zephyr/logging/log.h>
15+
LOG_MODULE_REGISTER(dap_hid, LOG_LEVEL_INF);
16+
17+
#include <cmsis_dap.h>
18+
19+
#define DAP_PACKET_SIZE CONFIG_HID_INTERRUPT_EP_MPS
20+
21+
#if (DAP_PACKET_SIZE < 64U)
22+
#error "Minimum packet size is 64"
23+
#endif
24+
#if (DAP_PACKET_SIZE > 32768U)
25+
#error "Maximum packet size is 32768"
26+
#endif
27+
28+
const static struct device *hid0_dev;
29+
30+
NET_BUF_POOL_FIXED_DEFINE(ep_out_pool, CONFIG_CMSIS_DAP_PACKET_COUNT,
31+
DAP_PACKET_SIZE, 0, NULL);
32+
33+
K_SEM_DEFINE(hid_epin_sem, 0, 1);
34+
K_FIFO_DEFINE(ep_out_queue);
35+
36+
static const uint8_t hid_report_desc[] = {
37+
HID_ITEM(HID_ITEM_TAG_USAGE_PAGE, HID_ITEM_TYPE_GLOBAL, 2), 0x00, 0xFF,
38+
HID_USAGE(HID_USAGE_GEN_DESKTOP_POINTER),
39+
HID_COLLECTION(HID_COLLECTION_APPLICATION),
40+
HID_LOGICAL_MIN8(0x00),
41+
HID_LOGICAL_MAX16(0xFF, 0x00),
42+
HID_REPORT_SIZE(8),
43+
HID_REPORT_COUNT(64),
44+
HID_USAGE(HID_USAGE_GEN_DESKTOP_POINTER),
45+
HID_INPUT(0x02),
46+
HID_REPORT_COUNT(64),
47+
HID_USAGE(HID_USAGE_GEN_DESKTOP_POINTER),
48+
HID_OUTPUT(0x02),
49+
HID_REPORT_COUNT(0x01),
50+
HID_USAGE(HID_USAGE_GEN_DESKTOP_POINTER),
51+
HID_FEATURE(0x02),
52+
HID_END_COLLECTION,
53+
};
54+
55+
static void int_in_ready_cb(const struct device *dev)
56+
{
57+
ARG_UNUSED(dev);
58+
59+
k_sem_give(&hid_epin_sem);
60+
}
61+
62+
void int_out_ready_cb(const struct device *dev)
63+
{
64+
struct net_buf *buf;
65+
size_t len = 0;
66+
67+
buf = net_buf_alloc(&ep_out_pool, K_FOREVER);
68+
hid_int_ep_read(dev, buf->data, buf->size, &len);
69+
net_buf_add(buf, len);
70+
71+
if (len == 0) {
72+
LOG_WRN("drop empty packet");
73+
net_buf_unref(buf);
74+
return;
75+
}
76+
77+
k_fifo_put(&ep_out_queue, buf);
78+
}
79+
80+
static const struct hid_ops ops = {
81+
.int_in_ready = int_in_ready_cb,
82+
.int_out_ready = int_out_ready_cb,
83+
};
84+
85+
int main(void)
86+
{
87+
const struct device *const swd_dev = DEVICE_DT_GET_ONE(zephyr_swdp_gpio);
88+
uint8_t response_buf[DAP_PACKET_SIZE];
89+
int ret;
90+
91+
if (!device_is_ready(swd_dev)) {
92+
LOG_ERR("SWD device is not ready");
93+
return -ENODEV;
94+
}
95+
96+
ret = dap_setup(swd_dev);
97+
if (ret) {
98+
LOG_ERR("Failed to initialize DAP controller (%d)", ret);
99+
return ret;
100+
}
101+
102+
ret = usb_enable(NULL);
103+
if (ret) {
104+
LOG_ERR("Failed to enable USB (%d)", ret);
105+
return ret;
106+
}
107+
108+
while (1) {
109+
struct net_buf *buf;
110+
size_t len;
111+
112+
buf = k_fifo_get(&ep_out_queue, K_FOREVER);
113+
114+
len = dap_execute_cmd(buf->data, response_buf);
115+
LOG_DBG("response length %u", len);
116+
net_buf_unref(buf);
117+
118+
if (hid_int_ep_write(hid0_dev, response_buf, len, NULL)) {
119+
LOG_ERR("Failed to send a response");
120+
continue;
121+
}
122+
123+
k_sem_take(&hid_epin_sem, K_FOREVER);
124+
}
125+
126+
return 0;
127+
}
128+
129+
static int hid_dap_preinit(void)
130+
{
131+
hid0_dev = device_get_binding("HID_0");
132+
if (hid0_dev == NULL) {
133+
LOG_ERR("Cannot get HID_0");
134+
return -ENODEV;
135+
}
136+
137+
usb_hid_register_device(hid0_dev, hid_report_desc,
138+
sizeof(hid_report_desc), &ops);
139+
140+
return usb_hid_init(hid0_dev);
141+
}
142+
143+
SYS_INIT(hid_dap_preinit, APPLICATION, CONFIG_APPLICATION_INIT_PRIORITY);

0 commit comments

Comments
 (0)