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