1 #include <app.h>
2 #include <lk/debug.h>
3 #include <lk/err.h>
4 #include <string.h>
5 #include <stdlib.h>
6 #include <lk/trace.h>
7 #include <dev/usb.h>
8 #include <dev/usbc.h>
9 #include <kernel/debug.h>
10 #include <kernel/thread.h>
11 #include <kernel/event.h>
12 
13 #define LOCAL_TRACE 1
14 
15 extern void usbtest_usb_setup(void);
16 
17 static status_t rx_callback(ep_t endpoint, struct usbc_transfer *transfer);
18 static usbc_transfer_t rx;
19 static uint8_t rxbuf[4096];
20 static volatile bool rxqueued;
21 
22 static status_t tx_callback(ep_t endpoint, struct usbc_transfer *transfer);
23 static usbc_transfer_t tx;
24 static uint8_t txbuf[4095];
25 static volatile bool txqueued;
26 
27 static event_t testevent;
28 
29 /* RX */
queue_rx_transfer(void)30 static void queue_rx_transfer(void) {
31     rx.callback = rx_callback;
32     rx.result = 0;
33     rx.buf = rxbuf;
34     rx.buflen = sizeof(rxbuf);
35     rx.bufpos = 0;
36     rx.extra = NULL;
37 
38     memset(rxbuf, 0x99, sizeof(rxbuf));
39 
40     rxqueued = true;
41     usbc_queue_rx(1, &rx);
42 }
43 
rx_callback(ep_t endpoint,struct usbc_transfer * transfer)44 static status_t rx_callback(ep_t endpoint, struct usbc_transfer *transfer) {
45     LTRACEF("ep %u, transfer %p\n", endpoint, transfer);
46 
47     rxqueued = false;
48     event_signal(&testevent, false);
49 
50     return NO_ERROR;
51 }
52 
53 /* TX */
queue_tx_transfer(void)54 static void queue_tx_transfer(void) {
55     tx.callback = tx_callback;
56     tx.result = 0;
57     tx.buf = txbuf;
58     tx.buflen = sizeof(txbuf);
59     tx.bufpos = 0;
60     tx.extra = NULL;
61 
62     for (uint i = 0; i < sizeof(txbuf); i++)
63         txbuf[i] = i * 3;
64 
65     txqueued = true;
66     usbc_queue_tx(1, &tx);
67 }
68 
tx_callback(ep_t endpoint,struct usbc_transfer * transfer)69 static status_t tx_callback(ep_t endpoint, struct usbc_transfer *transfer) {
70     LTRACEF("ep %u, transfer %p\n", endpoint, transfer);
71 
72     txqueued = false;
73     event_signal(&testevent, false);
74 
75     return NO_ERROR;
76 }
77 
usbtest_init(const struct app_descriptor * app)78 static void usbtest_init(const struct app_descriptor *app) {
79     LTRACE_ENTRY;
80     event_init(&testevent, false, EVENT_FLAG_AUTOUNSIGNAL);
81     usbtest_usb_setup();
82     LTRACE_EXIT;
83 }
84 
usbtest_entry(const struct app_descriptor * app,void * args)85 static void usbtest_entry(const struct app_descriptor *app, void *args) {
86     LTRACE_ENTRY;
87 
88     TRACEF("starting usb stack\n");
89     usb_start();
90 
91     // XXX get callback from stack
92     thread_sleep(2000);
93 
94     TRACEF("queuing transfers\n");
95     queue_rx_transfer();
96     queue_tx_transfer();
97 
98     while (event_wait(&testevent) == NO_ERROR) {
99         if (!rxqueued) {
100             /* dump the state of the transfer */
101             LTRACEF("rx transfer completed\n");
102             usbc_dump_transfer(&rx);
103             hexdump8(rx.buf, MIN(128, rx.bufpos));
104 
105             queue_rx_transfer();
106         }
107         if (!txqueued) {
108             /* dump the state of the transfer */
109             LTRACEF("tx transfer completed\n");
110             usbc_dump_transfer(&tx);
111 
112             queue_tx_transfer();
113         }
114     }
115 
116     LTRACE_EXIT;
117 }
118 
119 APP_START(usbtest)
120 .init = usbtest_init,
121 .entry = usbtest_entry,
122 APP_END
123 
124 
125