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