[app][usbtest] add default usb test app
Continually tries to send and receive 4K usb packets.
This commit is contained in:
110
app/usbtest/descriptor.c
Normal file
110
app/usbtest/descriptor.c
Normal file
@@ -0,0 +1,110 @@
|
||||
#include <err.h>
|
||||
#include <debug.h>
|
||||
#include <stdio.h>
|
||||
#include <target.h>
|
||||
#include <compiler.h>
|
||||
#include <dev/usb.h>
|
||||
#include <dev/usbc.h>
|
||||
#include <hw/usb.h>
|
||||
|
||||
#define W(w) (w & 0xff), (w >> 8)
|
||||
#define W3(w) (w & 0xff), ((w >> 8) & 0xff), ((w >> 16) & 0xff)
|
||||
|
||||
/* top level device descriptor */
|
||||
static const uint8_t dev_descr[] = {
|
||||
0x12, /* descriptor length */
|
||||
DEVICE, /* Device Descriptor type */
|
||||
W(0x0200), /* USB Version */
|
||||
0xff, /* class */
|
||||
0xff, /* subclass */
|
||||
0xff, /* protocol */
|
||||
64, /* max packet size, ept0 */
|
||||
W(0x9999), /* vendor */
|
||||
W(0x9999), /* product */
|
||||
W(0x9999), /* release */
|
||||
0x0, /* manufacturer string */
|
||||
0x0, /* product string */
|
||||
0x0, /* serialno string */
|
||||
0x1, /* num configs */
|
||||
};
|
||||
|
||||
/* high/low speed device qualifier */
|
||||
static const uint8_t devqual_descr[] = {
|
||||
0x0a, /* len */
|
||||
DEVICE_QUALIFIER, /* Device Qualifier type */
|
||||
W(0x0200), /* USB version */
|
||||
0x00, /* class */
|
||||
0x00, /* subclass */
|
||||
0x00, /* protocol */
|
||||
64, /* max packet size, ept0 */
|
||||
0x01, /* num configs */
|
||||
0x00 /* reserved */
|
||||
};
|
||||
|
||||
static const uint8_t cfg_descr[] = {
|
||||
0x09, /* Length of Cfg Descr */
|
||||
CONFIGURATION, /* Type of Cfg Descr */
|
||||
W(0x09), /* Total Length (incl ifc, ept) */
|
||||
0x00, /* # Interfaces */
|
||||
0x01, /* Cfg Value */
|
||||
0x00, /* Cfg String */
|
||||
0xc0, /* Attributes -- self powered */
|
||||
250, /* Power Consumption - 500mA */
|
||||
};
|
||||
|
||||
static const uchar langid[] = { 0x04, 0x03, 0x09, 0x04 };
|
||||
|
||||
static const uint8_t if_descriptor_lowspeed[] = {
|
||||
0x09, /* length */
|
||||
INTERFACE, /* type */
|
||||
0x01, /* interface num */
|
||||
0x00, /* alternates */
|
||||
0x02, /* endpoint count */
|
||||
0xff, /* interface class */
|
||||
0xff, /* interface subclass */
|
||||
0x00, /* interface protocol */
|
||||
0x00, /* string index */
|
||||
|
||||
/* endpoint 1 IN */
|
||||
0x07, /* length */
|
||||
ENDPOINT, /* type */
|
||||
0x81, /* address: 1 IN */
|
||||
0x02, /* type: bulk */
|
||||
W(64), /* max packet size: 64 */
|
||||
00, /* interval */
|
||||
|
||||
/* endpoint 1 OUT */
|
||||
0x07, /* length */
|
||||
ENDPOINT, /* type */
|
||||
0x01, /* address: 1 OUT */
|
||||
0x02, /* type: bulk */
|
||||
W(64), /* max packet size: 64 */
|
||||
00, /* interval */
|
||||
};
|
||||
|
||||
static usb_config config = {
|
||||
.lowspeed = {
|
||||
.device = USB_DESC_STATIC(dev_descr),
|
||||
.device_qual = USB_DESC_STATIC(devqual_descr),
|
||||
.config = USB_DESC_STATIC(cfg_descr),
|
||||
},
|
||||
.highspeed = {
|
||||
.device = USB_DESC_STATIC(dev_descr),
|
||||
.device_qual = USB_DESC_STATIC(devqual_descr),
|
||||
.config = USB_DESC_STATIC(cfg_descr),
|
||||
},
|
||||
|
||||
.langid = USB_DESC_STATIC(langid),
|
||||
};
|
||||
|
||||
void usbtest_usb_setup(void)
|
||||
{
|
||||
usb_setup(&config);
|
||||
printf("appending interfaces\n");
|
||||
usb_append_interface_lowspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
|
||||
usb_append_interface_highspeed(if_descriptor_lowspeed, sizeof(if_descriptor_lowspeed));
|
||||
usbc_setup_endpoint(1, USB_OUT, 64);
|
||||
usbc_setup_endpoint(1, USB_IN, 64);
|
||||
}
|
||||
|
||||
// vim: set ts=4 sw=4 expandtab:
|
||||
15
app/usbtest/rules.mk
Normal file
15
app/usbtest/rules.mk
Normal file
@@ -0,0 +1,15 @@
|
||||
LOCAL_DIR := $(GET_LOCAL_DIR)
|
||||
|
||||
MODULE := $(LOCAL_DIR)
|
||||
|
||||
#GLOBAL_INCLUDES += $(LOCAL_DIR)/include
|
||||
|
||||
MODULE_DEPS += \
|
||||
dev/usb
|
||||
|
||||
MODULE_SRCS += \
|
||||
$(LOCAL_DIR)/usbtest.c \
|
||||
$(LOCAL_DIR)/descriptor.c \
|
||||
|
||||
include make/module.mk
|
||||
|
||||
129
app/usbtest/usbtest.c
Normal file
129
app/usbtest/usbtest.c
Normal file
@@ -0,0 +1,129 @@
|
||||
#include <app.h>
|
||||
#include <debug.h>
|
||||
#include <err.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <dev/usb.h>
|
||||
#include <dev/usbc.h>
|
||||
#include <kernel/debug.h>
|
||||
#include <kernel/thread.h>
|
||||
#include <kernel/event.h>
|
||||
|
||||
#define LOCAL_TRACE 1
|
||||
|
||||
extern void usbtest_usb_setup(void);
|
||||
|
||||
static status_t rx_callback(ep_t endpoint, struct usbc_transfer *transfer);
|
||||
static usbc_transfer_t rx;
|
||||
static uint8_t rxbuf[4096];
|
||||
static volatile bool rxqueued;
|
||||
|
||||
static status_t tx_callback(ep_t endpoint, struct usbc_transfer *transfer);
|
||||
static usbc_transfer_t tx;
|
||||
static uint8_t txbuf[4095];
|
||||
static volatile bool txqueued;
|
||||
|
||||
static event_t testevent;
|
||||
|
||||
/* RX */
|
||||
static void queue_rx_transfer(void)
|
||||
{
|
||||
rx.callback = rx_callback;
|
||||
rx.result = 0;
|
||||
rx.buf = rxbuf;
|
||||
rx.buflen = sizeof(rxbuf);
|
||||
rx.bufpos = 0;
|
||||
rx.extra = NULL;
|
||||
|
||||
memset(rxbuf, 0x99, sizeof(rxbuf));
|
||||
|
||||
rxqueued = true;
|
||||
usbc_queue_rx(1, &rx);
|
||||
}
|
||||
|
||||
static status_t rx_callback(ep_t endpoint, struct usbc_transfer *transfer)
|
||||
{
|
||||
LTRACEF("ep %u, transfer %p\n", endpoint, transfer);
|
||||
|
||||
rxqueued = false;
|
||||
event_signal(&testevent, false);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
/* TX */
|
||||
static void queue_tx_transfer(void)
|
||||
{
|
||||
tx.callback = tx_callback;
|
||||
tx.result = 0;
|
||||
tx.buf = txbuf;
|
||||
tx.buflen = sizeof(txbuf);
|
||||
tx.bufpos = 0;
|
||||
tx.extra = NULL;
|
||||
|
||||
for (uint i = 0; i < sizeof(txbuf); i++)
|
||||
txbuf[i] = i * 3;
|
||||
|
||||
txqueued = true;
|
||||
usbc_queue_tx(1, &tx);
|
||||
}
|
||||
|
||||
static status_t tx_callback(ep_t endpoint, struct usbc_transfer *transfer)
|
||||
{
|
||||
LTRACEF("ep %u, transfer %p\n", endpoint, transfer);
|
||||
|
||||
txqueued = false;
|
||||
event_signal(&testevent, false);
|
||||
|
||||
return NO_ERROR;
|
||||
}
|
||||
|
||||
static void usbtest_init(const struct app_descriptor *app)
|
||||
{
|
||||
LTRACE_ENTRY;
|
||||
event_init(&testevent, false, EVENT_FLAG_AUTOUNSIGNAL);
|
||||
usbtest_usb_setup();
|
||||
LTRACE_EXIT;
|
||||
}
|
||||
|
||||
static void usbtest_entry(const struct app_descriptor *app, void *args)
|
||||
{
|
||||
LTRACE_ENTRY;
|
||||
|
||||
TRACEF("starting usb stack\n");
|
||||
usb_start();
|
||||
|
||||
// XXX get callback from stack
|
||||
thread_sleep(2000);
|
||||
|
||||
TRACEF("queuing transfers\n");
|
||||
queue_rx_transfer();
|
||||
queue_tx_transfer();
|
||||
|
||||
while (event_wait(&testevent) == NO_ERROR) {
|
||||
if (!rxqueued) {
|
||||
/* dump the state of the transfer */
|
||||
LTRACEF("rx transfer completed\n");
|
||||
usbc_dump_transfer(&rx);
|
||||
hexdump8(rx.buf, MIN(128, rx.bufpos));
|
||||
|
||||
queue_rx_transfer();
|
||||
}
|
||||
if (!txqueued) {
|
||||
/* dump the state of the transfer */
|
||||
LTRACEF("tx transfer completed\n");
|
||||
usbc_dump_transfer(&tx);
|
||||
|
||||
queue_tx_transfer();
|
||||
}
|
||||
}
|
||||
|
||||
LTRACE_EXIT;
|
||||
}
|
||||
|
||||
APP_START(usbtest)
|
||||
.init = usbtest_init,
|
||||
.entry = usbtest_entry,
|
||||
APP_END
|
||||
|
||||
|
||||
Reference in New Issue
Block a user