1 /*
2 * Copyright (c) 2025, sakumisu
3 *
4 * SPDX-License-Identifier: Apache-2.0
5 */
6 #include <rtthread.h>
7 #include <rtdevice.h>
8
9 #include "usbd_core.h"
10 #include "usbd_adb.h"
11
12 #ifndef CONFIG_USBDEV_SHELL_RX_BUFSIZE
13 #define CONFIG_USBDEV_SHELL_RX_BUFSIZE (2048)
14 #endif
15
16 struct usbd_adb_shell {
17 struct rt_device parent;
18 usb_osal_sem_t tx_done;
19 struct rt_ringbuffer rx_rb;
20 rt_uint8_t rx_rb_buffer[CONFIG_USBDEV_SHELL_RX_BUFSIZE];
21 } g_usbd_adb_shell;
22
usbd_adb_notify_shell_read(uint8_t * data,uint32_t len)23 void usbd_adb_notify_shell_read(uint8_t *data, uint32_t len)
24 {
25 rt_ringbuffer_put(&g_usbd_adb_shell.rx_rb, data, len);
26
27 if (g_usbd_adb_shell.parent.rx_indicate) {
28 g_usbd_adb_shell.parent.rx_indicate(&g_usbd_adb_shell.parent, len);
29 }
30 }
31
usbd_adb_notify_write_done(void)32 void usbd_adb_notify_write_done(void)
33 {
34 if (g_usbd_adb_shell.tx_done) {
35 usb_osal_sem_give(g_usbd_adb_shell.tx_done);
36 }
37 }
38
usbd_adb_shell_open(struct rt_device * dev,rt_uint16_t oflag)39 static rt_err_t usbd_adb_shell_open(struct rt_device *dev, rt_uint16_t oflag)
40 {
41 while (!usb_device_is_configured(0)) {
42 rt_thread_mdelay(10);
43 }
44 return RT_EOK;
45 }
46
usbd_adb_shell_close(struct rt_device * dev)47 static rt_err_t usbd_adb_shell_close(struct rt_device *dev)
48 {
49 if (g_usbd_adb_shell.tx_done) {
50 usb_osal_sem_give(g_usbd_adb_shell.tx_done);
51 }
52
53 return RT_EOK;
54 }
55
usbd_adb_shell_read(struct rt_device * dev,rt_off_t pos,void * buffer,rt_size_t size)56 static rt_ssize_t usbd_adb_shell_read(struct rt_device *dev,
57 rt_off_t pos,
58 void *buffer,
59 rt_size_t size)
60 {
61 return rt_ringbuffer_get(&g_usbd_adb_shell.rx_rb, (rt_uint8_t *)buffer, size);
62 }
63
usbd_adb_shell_write(struct rt_device * dev,rt_off_t pos,const void * buffer,rt_size_t size)64 static rt_ssize_t usbd_adb_shell_write(struct rt_device *dev,
65 rt_off_t pos,
66 const void *buffer,
67 rt_size_t size)
68 {
69 int ret = 0;
70
71 RT_ASSERT(dev != RT_NULL);
72
73 if (!usb_device_is_configured(0)) {
74 return size;
75 }
76
77 if (usbd_adb_can_write() && size) {
78 usb_osal_sem_reset(g_usbd_adb_shell.tx_done);
79 usbd_abd_write(ADB_SHELL_LOALID, buffer, size);
80 usb_osal_sem_take(g_usbd_adb_shell.tx_done, 0xffffffff);
81 }
82
83 return size;
84 }
85
86 #ifdef RT_USING_DEVICE_OPS
87 const static struct rt_device_ops usbd_adb_shell_ops = {
88 NULL,
89 usbd_adb_shell_open,
90 usbd_adb_shell_close,
91 usbd_adb_shell_read,
92 usbd_adb_shell_write,
93 NULL
94 };
95 #endif
96
usbd_adb_shell_init(uint8_t in_ep,uint8_t out_ep)97 void usbd_adb_shell_init(uint8_t in_ep, uint8_t out_ep)
98 {
99 rt_err_t ret;
100 struct rt_device *device;
101
102 device = &(g_usbd_adb_shell.parent);
103
104 device->type = RT_Device_Class_Char;
105 device->rx_indicate = RT_NULL;
106 device->tx_complete = RT_NULL;
107
108 #ifdef RT_USING_DEVICE_OPS
109 device->ops = &usbd_adb_shell_ops;
110 #else
111 device->init = NULL;
112 device->open = usbd_adb_shell_open;
113 device->close = usbd_adb_shell_close;
114 device->read = usbd_adb_shell_read;
115 device->write = usbd_adb_shell_write;
116 device->control = NULL;
117 #endif
118 device->user_data = NULL;
119
120 /* register a character device */
121 ret = rt_device_register(device, "adb-sh", RT_DEVICE_FLAG_RDWR | RT_DEVICE_FLAG_REMOVABLE);
122
123 #ifdef RT_USING_POSIX_DEVIO
124 /* set fops */
125 device->fops = NULL;
126 #endif
127
128 g_usbd_adb_shell.tx_done = usb_osal_sem_create(0);
129 rt_ringbuffer_init(&g_usbd_adb_shell.rx_rb, g_usbd_adb_shell.rx_rb_buffer, sizeof(g_usbd_adb_shell.rx_rb_buffer));
130 }
131
adb_enter(int argc,char ** argv)132 static int adb_enter(int argc, char **argv)
133 {
134 (void)argc;
135 (void)argv;
136
137 finsh_set_device("adb-sh");
138 rt_console_set_device("adb-sh");
139
140 return 0;
141 }
142 MSH_CMD_EXPORT(adb_enter, adb_enter);
143
adb_exit(int argc,char ** argv)144 static int adb_exit(int argc, char **argv)
145 {
146 (void)argc;
147 (void)argv;
148
149 usbd_adb_close(ADB_SHELL_LOALID);
150
151 finsh_set_device(RT_CONSOLE_DEVICE_NAME);
152 rt_console_set_device(RT_CONSOLE_DEVICE_NAME);
153
154 return 0;
155 }
156 MSH_CMD_EXPORT(adb_exit, adb_exit);
157