• Home
  • Line#
  • Scopes#
  • Navigate#
  • Raw
  • Download
1 #include "usbh_core.h"
2 #include "usbh_cdc_acm.h"
3 #include "usbh_hid.h"
4 #include "usbh_msc.h"
5 #include "usbh_video.h"
6 #include "usbh_audio.h"
7 
8 #define TEST_USBH_CDC_ACM   1
9 #define TEST_USBH_HID       1
10 #define TEST_USBH_MSC       1
11 #define TEST_USBH_MSC_FATFS 0
12 #define TEST_USBH_AUDIO     0
13 #define TEST_USBH_VIDEO     0
14 #define TEST_USBH_CDC_ECM   0
15 
16 #if TEST_USBH_CDC_ACM
17 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t cdc_buffer[512];
18 
19 struct usbh_urb cdc_bulkin_urb;
20 struct usbh_urb cdc_bulkout_urb;
21 
usbh_cdc_acm_callback(void * arg,int nbytes)22 void usbh_cdc_acm_callback(void *arg, int nbytes)
23 {
24     //struct usbh_cdc_acm *cdc_acm_class = (struct usbh_cdc_acm *)arg;
25 
26     if (nbytes > 0) {
27         for (size_t i = 0; i < nbytes; i++) {
28             USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
29         }
30         USB_LOG_RAW("nbytes:%d\r\n", nbytes);
31     }
32 }
33 
usbh_cdc_acm_thread(void * argument)34 static void usbh_cdc_acm_thread(void *argument)
35 {
36     int ret;
37     struct usbh_cdc_acm *cdc_acm_class;
38 
39     while (1) {
40         // clang-format off
41 find_class:
42         // clang-format on
43         cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
44         if (cdc_acm_class == NULL) {
45             USB_LOG_RAW("do not find /dev/ttyACM0\r\n");
46             usb_osal_msleep(1000);
47             continue;
48         }
49         memset(cdc_buffer, 0, 512);
50 
51         usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, NULL, NULL);
52         ret = usbh_submit_urb(&cdc_bulkin_urb);
53         if (ret < 0) {
54             USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
55         } else {
56             USB_LOG_RAW("recv over:%d\r\n", cdc_bulkin_urb.actual_length);
57             for (size_t i = 0; i < cdc_bulkin_urb.actual_length; i++) {
58                 USB_LOG_RAW("0x%02x ", cdc_buffer[i]);
59             }
60         }
61 
62         USB_LOG_RAW("\r\n");
63         const uint8_t data1[10] = { 0x02, 0x00, 0x00, 0x00, 0x02, 0x02, 0x08, 0x14 };
64 
65         memcpy(cdc_buffer, data1, 8);
66         usbh_bulk_urb_fill(&cdc_bulkout_urb, cdc_acm_class->bulkout, cdc_buffer, 8, 3000, NULL, NULL);
67         ret = usbh_submit_urb(&cdc_bulkout_urb);
68         if (ret < 0) {
69             USB_LOG_RAW("bulk out error,ret:%d\r\n", ret);
70         } else {
71             USB_LOG_RAW("send over:%d\r\n", cdc_bulkout_urb.actual_length);
72         }
73 
74         usbh_bulk_urb_fill(&cdc_bulkin_urb, cdc_acm_class->bulkin, cdc_buffer, 64, 3000, usbh_cdc_acm_callback, cdc_acm_class);
75         ret = usbh_submit_urb(&cdc_bulkin_urb);
76         if (ret < 0) {
77             USB_LOG_RAW("bulk in error,ret:%d\r\n", ret);
78         } else {
79         }
80 
81         while (1) {
82             cdc_acm_class = (struct usbh_cdc_acm *)usbh_find_class_instance("/dev/ttyACM0");
83             if (cdc_acm_class == NULL) {
84                 goto find_class;
85             }
86             usb_osal_msleep(1000);
87         }
88     }
89 }
90 #endif
91 
92 #if TEST_USBH_HID
93 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t hid_buffer[128];
94 
95 struct usbh_urb hid_intin_urb;
96 
usbh_hid_callback(void * arg,int nbytes)97 void usbh_hid_callback(void *arg, int nbytes)
98 {
99     //struct usbh_hid *hid_class = (struct usbh_hid *)arg;
100 
101     if (nbytes > 0) {
102         for (size_t i = 0; i < nbytes; i++) {
103             USB_LOG_RAW("0x%02x ", hid_buffer[i]);
104         }
105         USB_LOG_RAW("nbytes:%d\r\n", nbytes);
106         usbh_submit_urb(&hid_intin_urb);
107     }
108 }
109 
usbh_hid_thread(void * argument)110 static void usbh_hid_thread(void *argument)
111 {
112     int ret;
113     struct usbh_hid *hid_class;
114 
115     while (1) {
116         // clang-format off
117 find_class:
118         // clang-format on
119         hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
120         if (hid_class == NULL) {
121             USB_LOG_RAW("do not find /dev/input0\r\n");
122             usb_osal_msleep(1500);
123             continue;
124         }
125         usbh_int_urb_fill(&hid_intin_urb, hid_class->intin, hid_buffer, 8, 0, usbh_hid_callback, hid_class);
126         ret = usbh_submit_urb(&hid_intin_urb);
127         if (ret < 0) {
128             usb_osal_msleep(1500);
129             goto find_class;
130         }
131 
132         while (1) {
133             hid_class = (struct usbh_hid *)usbh_find_class_instance("/dev/input0");
134             if (hid_class == NULL) {
135                 goto find_class;
136             }
137             usb_osal_msleep(1500);
138         }
139     }
140 }
141 #endif
142 
143 #if TEST_USBH_MSC
144 
145 #if TEST_USBH_MSC_FATFS
146 #include "ff.h"
147 
148 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t read_write_buffer[25 * 100];
149 
150 USB_NOCACHE_RAM_SECTION FATFS fs;
151 USB_NOCACHE_RAM_SECTION FIL fnew;
152 UINT fnum;
153 FRESULT res_sd = 0;
154 
usb_msc_fatfs_test()155 int usb_msc_fatfs_test()
156 {
157     const char *tmp_data = "cherryusb fatfs demo...\r\n";
158 
159     USB_LOG_RAW("data len:%d\r\n", strlen(tmp_data));
160     for (uint32_t i = 0; i < 100; i++) {
161         memcpy(&read_write_buffer[i * 25], tmp_data, strlen(tmp_data));
162     }
163 
164     res_sd = f_mount(&fs, "2:", 1);
165     if (res_sd != FR_OK) {
166         USB_LOG_RAW("mount fail,res:%d\r\n", res_sd);
167         return -1;
168     }
169 
170     USB_LOG_RAW("test fatfs write\r\n");
171     res_sd = f_open(&fnew, "2:test.txt", FA_CREATE_ALWAYS | FA_WRITE);
172     if (res_sd == FR_OK) {
173         res_sd = f_write(&fnew, read_write_buffer, sizeof(read_write_buffer), &fnum);
174         if (res_sd == FR_OK) {
175             USB_LOG_RAW("write success, write len:%d\n", fnum);
176         } else {
177             USB_LOG_RAW("write fail\r\n");
178             goto unmount;
179         }
180         f_close(&fnew);
181     } else {
182         USB_LOG_RAW("open fail\r\n");
183         goto unmount;
184     }
185     USB_LOG_RAW("test fatfs read\r\n");
186 
187     res_sd = f_open(&fnew, "2:test.txt", FA_OPEN_EXISTING | FA_READ);
188     if (res_sd == FR_OK) {
189         res_sd = f_read(&fnew, read_write_buffer, sizeof(read_write_buffer), &fnum);
190         if (res_sd == FR_OK) {
191             USB_LOG_RAW("read success, read len:%d\n", fnum);
192         } else {
193             USB_LOG_RAW("read fail\r\n");
194             goto unmount;
195         }
196         f_close(&fnew);
197     } else {
198         USB_LOG_RAW("open fail\r\n");
199         goto unmount;
200     }
201     f_mount(NULL, "2:", 1);
202     return 0;
203 unmount:
204     f_mount(NULL, "2:", 1);
205     return -1;
206 }
207 #endif
208 
209 USB_NOCACHE_RAM_SECTION USB_MEM_ALIGNX uint8_t partition_table[512];
210 
usbh_msc_thread(void * argument)211 static void usbh_msc_thread(void *argument)
212 {
213     int ret;
214     struct usbh_msc *msc_class;
215 
216     while (1) {
217         // clang-format off
218 find_class:
219         // clang-format on
220         msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
221         if (msc_class == NULL) {
222             USB_LOG_RAW("do not find /dev/sda\r\n");
223             usb_osal_msleep(2000);
224             continue;
225         }
226 
227 #if 1
228         /* get the partition table */
229         ret = usbh_msc_scsi_read10(msc_class, 0, partition_table, 1);
230         if (ret < 0) {
231             USB_LOG_RAW("scsi_read10 error,ret:%d\r\n", ret);
232             usb_osal_msleep(2000);
233             goto find_class;
234         }
235         for (uint32_t i = 0; i < 512; i++) {
236             if (i % 16 == 0) {
237                 USB_LOG_RAW("\r\n");
238             }
239             USB_LOG_RAW("%02x ", partition_table[i]);
240         }
241         USB_LOG_RAW("\r\n");
242 #endif
243 
244 #if TEST_USBH_MSC_FATFS
245         usb_msc_fatfs_test();
246 #endif
247         while (1) {
248             msc_class = (struct usbh_msc *)usbh_find_class_instance("/dev/sda");
249             if (msc_class == NULL) {
250                 goto find_class;
251             }
252             usb_osal_msleep(2000);
253         }
254     }
255 }
256 #endif
257 
258 #if 0
259 void usbh_videostreaming_parse_mjpeg(struct usbh_urb *urb, struct usbh_videostreaming *stream)
260 {
261     struct usbh_iso_frame_packet *iso_packet;
262     uint32_t num_of_iso_packets;
263     uint8_t data_offset;
264     uint32_t data_len;
265     uint8_t header_len = 0;
266 
267     num_of_iso_packets = urb->num_of_iso_packets;
268     iso_packet = urb->iso_packet;
269 
270     for (uint32_t i = 0; i < num_of_iso_packets; i++) {
271         /*
272             uint8_t frameIdentifier : 1U;
273             uint8_t endOfFrame      : 1U;
274             uint8_t presentationTimeStamp    : 1U;
275             uint8_t sourceClockReference : 1U;
276             uint8_t reserved             : 1U;
277             uint8_t stillImage           : 1U;
278             uint8_t errorBit             : 1U;
279             uint8_t endOfHeader          : 1U;
280         */
281         if (iso_packet[i].actual_length == 0) { /* skip no data */
282             continue;
283         }
284 
285         header_len = iso_packet[i].transfer_buffer[0];
286 
287         if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
288             while (1) {
289             }
290         }
291         if (iso_packet[i].transfer_buffer[1] & (1 << 6)) { /* error bit, re-receive */
292             stream->bufoffset = 0;
293             continue;
294         }
295 
296         if ((stream->bufoffset == 0) && ((iso_packet[i].transfer_buffer[header_len] != 0xff) || (iso_packet[i].transfer_buffer[header_len + 1] != 0xd8))) {
297             stream->bufoffset = 0;
298             continue;
299         }
300 
301         data_offset = header_len;
302         data_len = iso_packet[i].actual_length - header_len;
303 
304         /** do something here */
305 
306         stream->bufoffset += data_len;
307 
308         if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
309             if ((iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 2] != 0xff) || (iso_packet[i].transfer_buffer[iso_packet[i].actual_length - 1] != 0xd9)) {
310                 stream->bufoffset = 0;
311                 continue;
312             }
313 
314             /** do something here */
315 
316             if (stream->video_one_frame_callback) {
317                 stream->video_one_frame_callback(stream);
318             }
319             stream->bufoffset = 0;
320         }
321     }
322     /** do something here */
323 }
324 
325 void usbh_videostreaming_parse_yuyv2(struct usbh_urb *urb, struct usbh_videostreaming *stream)
326 {
327     struct usbh_iso_frame_packet *iso_packet;
328     uint32_t num_of_iso_packets;
329     uint8_t data_offset;
330     uint32_t data_len;
331     uint8_t header_len = 0;
332 
333     num_of_iso_packets = urb->num_of_iso_packets;
334     iso_packet = urb->iso_packet;
335 
336     for (uint32_t i = 0; i < num_of_iso_packets; i++) {
337         /*
338             uint8_t frameIdentifier : 1U;
339             uint8_t endOfFrame      : 1U;
340             uint8_t presentationTimeStamp    : 1U;
341             uint8_t sourceClockReference : 1U;
342             uint8_t reserved             : 1U;
343             uint8_t stillImage           : 1U;
344             uint8_t errorBit             : 1U;
345             uint8_t endOfHeader          : 1U;
346         */
347 
348         if (iso_packet[i].actual_length == 0) { /* skip no data */
349             continue;
350         }
351 
352         header_len = iso_packet[i].transfer_buffer[0];
353 
354         if ((header_len > 12) || (header_len == 0)) { /* do not be illegal */
355             while (1) {
356             }
357         }
358         if (iso_packet[i].transfer_buffer[1] & (1 << 6)) { /* error bit, re-receive */
359             stream->bufoffset = 0;
360             continue;
361         }
362 
363         data_offset = header_len;
364         data_len = iso_packet[i].actual_length - header_len;
365 
366         /** do something here */
367 
368         stream->bufoffset += data_len;
369 
370         if (iso_packet[i].transfer_buffer[1] & (1 << 1)) {
371             /** do something here */
372 
373             if (stream->video_one_frame_callback && (stream->bufoffset == stream->buflen)) {
374                 stream->video_one_frame_callback(stream);
375             }
376             stream->bufoffset = 0;
377         }
378     }
379 
380     /** do something here */
381 }
382 #endif
383 
384 #if TEST_USBH_CDC_ECM
385 #include "usbh_cdc_ecm.h"
386 
387 #include "netif/etharp.h"
388 #include "lwip/netif.h"
389 #include "lwip/pbuf.h"
390 #include "lwip/tcpip.h"
391 #if LWIP_DHCP
392 #include "lwip/dhcp.h"
393 #endif
394 
395 struct netif g_cdc_ecm_netif;
396 
usbh_cdc_ecm_if_init(struct netif * netif)397 static err_t usbh_cdc_ecm_if_init(struct netif *netif)
398 {
399     LWIP_ASSERT("netif != NULL", (netif != NULL));
400 
401     netif->mtu = 1500;
402     netif->flags = NETIF_FLAG_BROADCAST | NETIF_FLAG_ETHARP | NETIF_FLAG_LINK_UP | NETIF_FLAG_UP;
403     netif->state = NULL;
404     netif->name[0] = 'E';
405     netif->name[1] = 'X';
406     netif->output = etharp_output;
407     netif->linkoutput = usbh_cdc_ecm_linkoutput;
408     return ERR_OK;
409 }
410 
usbh_cdc_ecm_run(struct usbh_cdc_ecm * cdc_ecm_class)411 void usbh_cdc_ecm_run(struct usbh_cdc_ecm *cdc_ecm_class)
412 {
413     struct netif *netif = &g_cdc_ecm_netif;
414 
415     netif->hwaddr_len = 6;
416     memcpy(netif->hwaddr, cdc_ecm_class->mac, 6);
417 
418     IP4_ADDR(&cdc_ecm_class->ipaddr, 0, 0, 0, 0);
419     IP4_ADDR(&cdc_ecm_class->netmask, 0, 0, 0, 0);
420     IP4_ADDR(&cdc_ecm_class->gateway, 0, 0, 0, 0);
421 
422     netif = netif_add(netif, &cdc_ecm_class->ipaddr, &cdc_ecm_class->netmask, &cdc_ecm_class->gateway, NULL, usbh_cdc_ecm_if_init, tcpip_input);
423     netif_set_default(netif);
424     while (!netif_is_up(netif)) {
425     }
426 
427 #if LWIP_DHCP
428     dhcp_start(netif);
429 #endif
430 }
431 
usbh_cdc_ecm_stop(struct usbh_cdc_ecm * cdc_ecm_class)432 void usbh_cdc_ecm_stop(struct usbh_cdc_ecm *cdc_ecm_class)
433 {
434     struct netif *netif = &g_cdc_ecm_netif;
435 #if LWIP_DHCP
436     dhcp_stop(netif);
437     dhcp_cleanup(netif);
438 #endif
439     netif_set_down(netif);
440     netif_remove(netif);
441 }
442 #endif
443 
usbh_cdc_acm_run(struct usbh_cdc_acm * cdc_acm_class)444 void usbh_cdc_acm_run(struct usbh_cdc_acm *cdc_acm_class)
445 {
446 }
447 
usbh_cdc_acm_stop(struct usbh_cdc_acm * cdc_acm_class)448 void usbh_cdc_acm_stop(struct usbh_cdc_acm *cdc_acm_class)
449 {
450 }
451 
usbh_hid_run(struct usbh_hid * hid_class)452 void usbh_hid_run(struct usbh_hid *hid_class)
453 {
454 }
455 
usbh_hid_stop(struct usbh_hid * hid_class)456 void usbh_hid_stop(struct usbh_hid *hid_class)
457 {
458 }
459 
usbh_msc_run(struct usbh_msc * msc_class)460 void usbh_msc_run(struct usbh_msc *msc_class)
461 {
462 }
463 
usbh_msc_stop(struct usbh_msc * msc_class)464 void usbh_msc_stop(struct usbh_msc *msc_class)
465 {
466 }
467 
usbh_audio_run(struct usbh_audio * audio_class)468 void usbh_audio_run(struct usbh_audio *audio_class)
469 {
470 }
471 
usbh_audio_stop(struct usbh_audio * audio_class)472 void usbh_audio_stop(struct usbh_audio *audio_class)
473 {
474 }
475 
usbh_video_run(struct usbh_video * video_class)476 void usbh_video_run(struct usbh_video *video_class)
477 {
478 }
479 
usbh_video_stop(struct usbh_video * video_class)480 void usbh_video_stop(struct usbh_video *video_class)
481 {
482 }
483 
usbh_class_test(void)484 void usbh_class_test(void)
485 {
486 #if TEST_USBH_CDC_ACM
487     usb_osal_thread_create("usbh_cdc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_cdc_acm_thread, NULL);
488 #endif
489 #if TEST_USBH_HID
490     usb_osal_thread_create("usbh_hid", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_hid_thread, NULL);
491 #endif
492 #if TEST_USBH_MSC
493     usb_osal_thread_create("usbh_msc", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_msc_thread, NULL);
494 #endif
495 #if TEST_USBH_AUDIO
496 #error "if you want to use iso, please contact with me"
497     usb_osal_thread_create("usbh_audio", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_audio_thread, NULL);
498 #endif
499 #if TEST_USBH_VIDEO
500 #error "if you want to use iso, please contact with me"
501     usb_osal_thread_create("usbh_video", 2048, CONFIG_USBHOST_PSC_PRIO + 1, usbh_video_thread, NULL);
502 #endif
503 #if TEST_USBH_CDC_ECM
504     /* Initialize the LwIP stack */
505     tcpip_init(NULL, NULL);
506 
507     usbh_cdc_ecm_lwip_thread_init(&g_cdc_ecm_netif);
508 #endif
509 }