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