Skip to content

Commit 7955dd0

Browse files
committed
1
Signed-off-by: sakumisu <1203593632@qq.com>
1 parent b5f2b13 commit 7955dd0

9 files changed

Lines changed: 691 additions & 68 deletions

File tree

class/adb/usbd_adb.c

Lines changed: 19 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -6,8 +6,8 @@
66
#include "usbd_core.h"
77
#include "usbd_adb.h"
88

9-
#define ADB_OUT_EP_IDX 0
10-
#define ADB_IN_EP_IDX 1
9+
#define ADB_OUT_EP_IDX 0
10+
#define ADB_IN_EP_IDX 1
1111

1212
#define ADB_STATE_READ_MSG 0
1313
#define ADB_STATE_READ_DATA 1
@@ -16,18 +16,18 @@
1616
#define ADB_STATE_AWRITE_MSG 4
1717
#define ADB_STATE_AWRITE_DATA 5
1818

19-
#define MAX_PAYLOAD_V1 (4 * 1024)
20-
#define MAX_PAYLOAD_V2 (256 * 1024)
21-
#define MAX_PAYLOAD MAX_PAYLOAD_V1
22-
#define A_VERSION 0x01000000
19+
#define MAX_PAYLOAD_V1 (4 * 1024)
20+
#define MAX_PAYLOAD_V2 (256 * 1024)
21+
#define MAX_PAYLOAD MAX_PAYLOAD_V1
22+
#define A_VERSION 0x01000000
2323

24-
#define A_SYNC 0x434e5953
25-
#define A_CNXN 0x4e584e43
26-
#define A_OPEN 0x4e45504f
27-
#define A_OKAY 0x59414b4f
28-
#define A_CLSE 0x45534c43
29-
#define A_WRTE 0x45545257
30-
#define A_AUTH 0x48545541
24+
#define A_SYNC 0x434e5953
25+
#define A_CNXN 0x4e584e43
26+
#define A_OPEN 0x4e45504f
27+
#define A_OKAY 0x59414b4f
28+
#define A_CLSE 0x45534c43
29+
#define A_WRTE 0x45545257
30+
#define A_AUTH 0x48545541
3131

3232
struct adb_msg {
3333
uint32_t command; /* command identifier constant (A_CNXN, ...) */
@@ -118,10 +118,10 @@ void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
118118
USB_ASSERT(rx_packet.msg.data_length <= sizeof(rx_packet.payload));
119119

120120
USB_LOG_DBG("command:%x arg0:%x arg1:%x len:%d\r\n",
121-
rx_packet.msg.command,
122-
rx_packet.msg.arg0,
123-
rx_packet.msg.arg1,
124-
rx_packet.msg.data_length);
121+
rx_packet.msg.command,
122+
rx_packet.msg.arg0,
123+
rx_packet.msg.arg1,
124+
rx_packet.msg.data_length);
125125

126126
if (rx_packet.msg.data_length) {
127127
/* setup next out ep read transfer */
@@ -143,6 +143,7 @@ void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
143143

144144
break;
145145
case A_CNXN: /* CONNECT(version, maxdata, "system-id-string") */
146+
{
146147
char *support_feature = "device::"
147148
"ro.product.name=cherryadb;"
148149
"ro.product.model=cherrysh;"
@@ -158,7 +159,7 @@ void usbd_adb_bulk_out(uint8_t busid, uint8_t ep, uint32_t nbytes)
158159
adb_send_msg(&tx_packet);
159160

160161
adb_client.writable = false;
161-
break;
162+
} break;
162163
case A_OPEN: /* OPEN(local-id, 0, "destination") */
163164
rx_packet.payload[rx_packet.msg.data_length] = '\0';
164165

class/adb/usbd_adb.h

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -8,13 +8,13 @@
88

99
#include <stdint.h>
1010

11-
#define ADB_SHELL_LOALID 0x01
12-
#define ADB_FILE_LOALID 0x02
11+
#define ADB_SHELL_LOALID 0x01
12+
#define ADB_FILE_LOALID 0x02
1313

1414
// clang-format off
15-
#define ADB_DESCRIPTOR_INIT(bFirstInterface, in_ep, out_ep, wMaxPacketSize) \
15+
#define ADB_DESCRIPTOR_INIT(bFirstInterface, in_ep, out_ep, wMaxPacketSize) \
1616
USB_INTERFACE_DESCRIPTOR_INIT(bFirstInterface, 0x00, 0x02, 0xff, 0x42, 0x01, 0x02), \
17-
USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x02, wMaxPacketSize, 0x00), \
17+
USB_ENDPOINT_DESCRIPTOR_INIT(in_ep, 0x02, wMaxPacketSize, 0x00), \
1818
USB_ENDPOINT_DESCRIPTOR_INIT(out_ep, 0x02, wMaxPacketSize, 0x00)
1919
// clang-format on
2020

docs/zh/demo/usbd_cdc_acm.rst

Lines changed: 7 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -100,5 +100,11 @@ CDC ACM Device
100100
- 上述我们需要注意,长度设置为 2048 是为了测试 ZLP 功能,通常实际使用时,接收长度应该使用 CDC_MAX_MPS 。具体原因参考 :ref:`usb_ext`
101101
- 如果需要做性能测试,使用 tools/test_srcipts/test_cdc_speed.py 进行测试,并在测试之前删除 `usbd_cdc_acm_bulk_out` 和 `usbd_cdc_acm_bulk_in` 中的打印,否则会影响测试结果。
102102

103+
测试命令如下:
103104

104-
此外,对于 CDC ACM 搭配 OS 的情况,通常我们 read 使用异步并将数据存储到 ringbuffer 中,write 使用同步搭配 sem 使用。
105+
.. code-block:: python
106+
107+
python test_cdc_speed.py --port COM17 --mode tx --chunk-length 4M
108+
python test_cdc_speed.py --port COM17 --mode rx --chunk-length 4M
109+
110+
.. note:: 对于 CDC ACM 搭配 OS 的情况,通常我们 read 使用异步并将数据存储到 ringbuffer 中,write 使用同步搭配 sem 使用。

docs/zh/quick_start/opensource.rst

Lines changed: 4 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -71,3 +71,7 @@
7171
* - MuseCube
7272
- dydcyy-gh
7373
- https://github.com/dydcyy-gh/MuseCube
74+
* - zmk
75+
- OpenSiFli
76+
- https://github.com/OpenSiFli/zmk
77+

platform/zmk/usb.c

Lines changed: 226 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,226 @@
1+
/*
2+
* Copyright (c) 2020 The ZMK Contributors
3+
*
4+
* SPDX-License-Identifier: MIT
5+
*/
6+
7+
#include <zephyr/device.h>
8+
#include <zephyr/init.h>
9+
#include <zephyr/kernel.h>
10+
#include <zephyr/logging/log.h>
11+
12+
#include "usbd_core.h"
13+
#include "usbd_hid.h"
14+
15+
#include <zmk/usb.h>
16+
#include <zmk/hid.h>
17+
#include <zmk/event_manager.h>
18+
#include <zmk/events/usb_conn_state_changed.h>
19+
20+
LOG_MODULE_DECLARE(zmk, CONFIG_ZMK_LOG_LEVEL);
21+
22+
#define CHERRYUSB_BUS_ID 0
23+
24+
/* USB status tracking, mirroring the CherryUSB event states */
25+
enum cherryusb_status {
26+
CUSB_STATUS_UNKNOWN,
27+
CUSB_STATUS_CONNECTED,
28+
CUSB_STATUS_DISCONNECTED,
29+
CUSB_STATUS_CONFIGURED,
30+
CUSB_STATUS_SUSPEND,
31+
CUSB_STATUS_RESUME,
32+
CUSB_STATUS_RESET,
33+
CUSB_STATUS_ERROR,
34+
};
35+
36+
static enum cherryusb_status usb_status = CUSB_STATUS_UNKNOWN;
37+
38+
static void raise_usb_status_changed_event(struct k_work *_work) {
39+
raise_zmk_usb_conn_state_changed(
40+
(struct zmk_usb_conn_state_changed){.conn_state = zmk_usb_get_conn_state()});
41+
}
42+
43+
K_WORK_DEFINE(usb_status_notifier_work, raise_usb_status_changed_event);
44+
45+
enum zmk_usb_conn_state zmk_usb_get_conn_state(void) {
46+
LOG_DBG("state: %d", usb_status);
47+
switch (usb_status) {
48+
case CUSB_STATUS_CONFIGURED:
49+
case CUSB_STATUS_SUSPEND:
50+
case CUSB_STATUS_RESUME:
51+
return ZMK_USB_CONN_HID;
52+
53+
case CUSB_STATUS_DISCONNECTED:
54+
case CUSB_STATUS_UNKNOWN:
55+
return ZMK_USB_CONN_NONE;
56+
57+
default:
58+
return ZMK_USB_CONN_POWERED;
59+
}
60+
}
61+
62+
bool zmk_usb_is_hid_ready(void) {
63+
return usb_status == CUSB_STATUS_CONFIGURED || usb_status == CUSB_STATUS_RESUME;
64+
}
65+
66+
/* ---- USB Descriptors ---- */
67+
68+
#define USBD_VID CONFIG_USB_DEVICE_VID
69+
#define USBD_PID CONFIG_USB_DEVICE_PID
70+
#define USBD_MAX_POWER 100
71+
#define USBD_LANGID_STRING 1033
72+
73+
#define HID_INT_EP 0x81
74+
#define HID_INT_EP_SIZE 64
75+
#define HID_INT_EP_INTERVAL 1
76+
77+
#define USB_HID_CONFIG_DESC_SIZ (9 + HID_KEYBOARD_DESCRIPTOR_LEN)
78+
79+
static const uint8_t device_descriptor[] = {
80+
USB_DEVICE_DESCRIPTOR_INIT(USB_2_0, 0x00, 0x00, 0x00,
81+
USBD_VID, USBD_PID, 0x0001, 0x01),
82+
};
83+
84+
static const uint8_t config_descriptor[] = {
85+
USB_CONFIG_DESCRIPTOR_INIT(USB_HID_CONFIG_DESC_SIZ, 0x01, 0x01,
86+
USB_CONFIG_BUS_POWERED | USB_CONFIG_REMOTE_WAKEUP,
87+
USBD_MAX_POWER),
88+
HID_KEYBOARD_DESCRIPTOR_INIT(0x00,
89+
#if IS_ENABLED(CONFIG_ZMK_USB_BOOT)
90+
0x01, /* boot interface subclass */
91+
#else
92+
0x00, /* no boot */
93+
#endif
94+
sizeof(zmk_hid_report_desc),
95+
HID_INT_EP, HID_INT_EP_SIZE, HID_INT_EP_INTERVAL),
96+
};
97+
98+
static const uint8_t device_quality_descriptor[] = {
99+
0x0a,
100+
USB_DESCRIPTOR_TYPE_DEVICE_QUALIFIER,
101+
0x00, 0x02,
102+
0x00, 0x00, 0x00,
103+
0x40,
104+
0x00, 0x00,
105+
};
106+
107+
#ifndef CONFIG_USB_DEVICE_MANUFACTURER
108+
#define CONFIG_USB_DEVICE_MANUFACTURER "ZMK Project"
109+
#endif
110+
111+
static const char *string_descriptors[] = {
112+
(const char[]){ 0x09, 0x04 }, /* Langid */
113+
CONFIG_USB_DEVICE_MANUFACTURER, /* Manufacturer */
114+
CONFIG_ZMK_KEYBOARD_NAME, /* Product */
115+
"ZMK000000", /* Serial Number */
116+
};
117+
118+
static const uint8_t *device_descriptor_callback(uint8_t speed) {
119+
(void)speed;
120+
return device_descriptor;
121+
}
122+
123+
static const uint8_t *config_descriptor_callback(uint8_t speed) {
124+
(void)speed;
125+
return config_descriptor;
126+
}
127+
128+
static const uint8_t *device_quality_descriptor_callback(uint8_t speed) {
129+
(void)speed;
130+
return device_quality_descriptor;
131+
}
132+
133+
static const char *string_descriptor_callback(uint8_t speed, uint8_t index) {
134+
(void)speed;
135+
if (index >= ARRAY_SIZE(string_descriptors)) {
136+
return NULL;
137+
}
138+
return string_descriptors[index];
139+
}
140+
141+
const struct usb_descriptor zmk_cherryusb_descriptor = {
142+
.device_descriptor_callback = device_descriptor_callback,
143+
.config_descriptor_callback = config_descriptor_callback,
144+
.device_quality_descriptor_callback = device_quality_descriptor_callback,
145+
.string_descriptor_callback = string_descriptor_callback,
146+
};
147+
148+
/* ---- CherryUSB event handler ---- */
149+
150+
static void usbd_event_handler(uint8_t busid, uint8_t event) {
151+
LOG_DBG("USB event: bus %d, event %d\n", busid, event);
152+
switch (event) {
153+
case USBD_EVENT_RESET:
154+
#if IS_ENABLED(CONFIG_ZMK_USB_BOOT)
155+
extern void zmk_usb_hid_set_protocol(uint8_t protocol);
156+
zmk_usb_hid_set_protocol(1); /* HID_PROTOCOL_REPORT */
157+
#endif
158+
usb_status = CUSB_STATUS_RESET;
159+
break;
160+
case USBD_EVENT_CONNECTED:
161+
usb_status = CUSB_STATUS_CONNECTED;
162+
break;
163+
case USBD_EVENT_DISCONNECTED:
164+
usb_status = CUSB_STATUS_DISCONNECTED;
165+
break;
166+
case USBD_EVENT_CONFIGURED:
167+
usb_status = CUSB_STATUS_CONFIGURED;
168+
break;
169+
case USBD_EVENT_SUSPEND:
170+
usb_status = CUSB_STATUS_SUSPEND;
171+
break;
172+
case USBD_EVENT_RESUME:
173+
usb_status = CUSB_STATUS_RESUME;
174+
break;
175+
case USBD_EVENT_ERROR:
176+
usb_status = CUSB_STATUS_ERROR;
177+
break;
178+
default:
179+
return;
180+
}
181+
k_work_submit(&usb_status_notifier_work);
182+
}
183+
184+
/* ---- HID interface and endpoint (shared with usb_hid.c) ---- */
185+
186+
struct usbd_interface zmk_cherryusb_hid_intf;
187+
188+
static void hid_in_ep_callback(uint8_t busid, uint8_t ep, uint32_t nbytes);
189+
190+
struct usbd_endpoint zmk_cherryusb_hid_in_ep = {
191+
.ep_cb = hid_in_ep_callback,
192+
.ep_addr = HID_INT_EP,
193+
};
194+
195+
/* Semaphore for EP write completion, given from endpoint callback */
196+
K_SEM_DEFINE(zmk_cherryusb_hid_sem, 1, 1);
197+
198+
static void hid_in_ep_callback(uint8_t busid, uint8_t ep, uint32_t nbytes) {
199+
(void)busid;
200+
(void)ep;
201+
(void)nbytes;
202+
k_sem_give(&zmk_cherryusb_hid_sem);
203+
}
204+
205+
static int zmk_usb_init(void) {
206+
usbd_desc_register(CHERRYUSB_BUS_ID, &zmk_cherryusb_descriptor);
207+
208+
usbd_add_interface(CHERRYUSB_BUS_ID,
209+
usbd_hid_init_intf(CHERRYUSB_BUS_ID, &zmk_cherryusb_hid_intf,
210+
zmk_hid_report_desc,
211+
sizeof(zmk_hid_report_desc)));
212+
usbd_add_endpoint(CHERRYUSB_BUS_ID, &zmk_cherryusb_hid_in_ep);
213+
214+
int ret = usbd_initialize(CHERRYUSB_BUS_ID,
215+
(uintptr_t)CONFIG_CHERRYUSB_DEV_BASE_ADDR,
216+
usbd_event_handler);
217+
if (ret != 0) {
218+
LOG_ERR("CherryUSB initialization failed (err %d)", ret);
219+
return -EINVAL;
220+
}
221+
222+
LOG_INF("CherryUSB initialized");
223+
return 0;
224+
}
225+
226+
SYS_INIT(zmk_usb_init, APPLICATION, CONFIG_ZMK_USB_INIT_PRIORITY);

0 commit comments

Comments
 (0)