From dfcb2cf64a95e99e5325bf3290697ac7823994bc Mon Sep 17 00:00:00 2001 From: Christian Starkjohann Date: Tue, 13 May 2008 15:15:13 +0000 Subject: - added (optional) reliability test in custom-class example --- examples/custom-class/commandline/set-led.c | 34 ++++++++++++++++++++++++++++- examples/custom-class/firmware/main.c | 11 ++++++++-- examples/custom-class/firmware/requests.h | 4 ++++ tests/Makefile | 20 +++++++++++++---- 4 files changed, 62 insertions(+), 7 deletions(-) diff --git a/examples/custom-class/commandline/set-led.c b/examples/custom-class/commandline/set-led.c index 07ba094..807adac 100644 --- a/examples/custom-class/commandline/set-led.c +++ b/examples/custom-class/commandline/set-led.c @@ -33,6 +33,9 @@ static void usage(char *name) fprintf(stderr, " %s on ....... turn on LED\n", name); fprintf(stderr, " %s off ...... turn off LED\n", name); fprintf(stderr, " %s status ... ask current status of LED\n", name); +#if HAVE_TEST + fprintf(stderr, " %s test ..... run driver reliability test\n", name); +#endif } int main(int argc, char **argv) @@ -40,7 +43,7 @@ int main(int argc, char **argv) usb_dev_handle *handle = NULL; const unsigned char rawVid[2] = {USB_CFG_VENDOR_ID}, rawPid[2] = {USB_CFG_DEVICE_ID}; char vendor[] = {USB_CFG_VENDOR_NAME, 0}, product[] = {USB_CFG_DEVICE_NAME, 0}; -char buffer[1]; +char buffer[4]; int cnt, vid, pid, isOn; usb_init(); @@ -75,6 +78,35 @@ int cnt, vid, pid, isOn; if(cnt < 0){ fprintf(stderr, "USB error: %s\n", usb_strerror()); } +#if HAVE_TEST + }else if(strcasecmp(argv[1], "test") == 0){ + int i; + srandomdev(); + for(i = 0; i < 5000; i++){ + int value = random() & 0xffff, index = random() & 0xffff; + int rxValue, rxIndex; + if((i+1) % 100 == 0){ + fprintf(stderr, "\r%04d", i+1); + fflush(stderr); + } + cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000); + if(cnt < 0){ + fprintf(stderr, "\nUSB error in iteration %d: %s\n", i, usb_strerror()); + break; + }else if(cnt != 4){ + fprintf(stderr, "\nerror in iteration %d: %d bytes received instead of 4\n", i, cnt); + break; + } + rxValue = ((int)buffer[0] & 0xff) | (((int)buffer[1] & 0xff) << 8); + rxIndex = ((int)buffer[2] & 0xff) | (((int)buffer[3] & 0xff) << 8); + if(rxValue != value || rxIndex != index){ + fprintf(stderr, "\ndata error in iteration %d:\n", i); + fprintf(stderr, "rxValue = 0x%04x value = 0x%04x\n", rxValue, value); + fprintf(stderr, "rxIndex = 0x%04x index = 0x%04x\n", rxIndex, index); + } + } + fprintf(stderr, "\nTest completed.\n"); +#endif }else{ usage(argv[0]); exit(1); diff --git a/examples/custom-class/firmware/main.c b/examples/custom-class/firmware/main.c index 940f62e..e12ef00 100644 --- a/examples/custom-class/firmware/main.c +++ b/examples/custom-class/firmware/main.c @@ -37,15 +37,22 @@ different port or bit, change the macros below: usbMsgLen_t usbFunctionSetup(uchar data[8]) { usbRequest_t *rq = (void *)data; +static uchar dataBuffer[4]; /* buffer must stay valid when usbFunctionSetup returns */ - if(rq->bRequest == CUSTOM_RQ_SET_STATUS){ + if(rq->bRequest == CUSTOM_RQ_ECHO){ /* echo -- used for reliability tests */ + dataBuffer[0] = rq->wValue.bytes[0]; + dataBuffer[1] = rq->wValue.bytes[1]; + dataBuffer[2] = rq->wIndex.bytes[0]; + dataBuffer[3] = rq->wIndex.bytes[1]; + usbMsgPtr = dataBuffer; /* tell the driver which data to return */ + return 4; + }else if(rq->bRequest == CUSTOM_RQ_SET_STATUS){ if(rq->wValue.bytes[0] & 1){ /* set LED */ LED_PORT_OUTPUT |= _BV(LED_BIT); }else{ /* clear LED */ LED_PORT_OUTPUT &= ~_BV(LED_BIT); } }else if(rq->bRequest == CUSTOM_RQ_GET_STATUS){ - static uchar dataBuffer[1]; /* buffer must stay valid when usbFunctionSetup returns */ dataBuffer[0] = ((LED_PORT_OUTPUT & _BV(LED_BIT)) != 0); usbMsgPtr = dataBuffer; /* tell the driver which data to return */ return 1; /* tell the driver to send 1 byte */ diff --git a/examples/custom-class/firmware/requests.h b/examples/custom-class/firmware/requests.h index b6a3c2b..2e7fac3 100644 --- a/examples/custom-class/firmware/requests.h +++ b/examples/custom-class/firmware/requests.h @@ -16,6 +16,10 @@ #ifndef __REQUESTS_H_INCLUDED__ #define __REQUESTS_H_INCLUDED__ +#define CUSTOM_RQ_ECHO 0 +/* Request that the device sends back wValue and wIndex. This is used with + * random data to test the reliability of the communication. + */ #define CUSTOM_RQ_SET_STATUS 1 /* Set the LED status. Control-OUT. * The requested status is passed in the "wValue" field of the control diff --git a/tests/Makefile b/tests/Makefile index f8a7517..6c8a1fc 100644 --- a/tests/Makefile +++ b/tests/Makefile @@ -66,13 +66,25 @@ sizes sizes.txt: test: for freq in 12000000 15000000 16000000 16500000 20000000; do \ for opt in USB_COUNT_SOF USB_CFG_HAVE_INTRIN_ENDPOINT USB_CFG_HAVE_INTRIN_ENDPOINT3 USB_CFG_HAVE_MEASURE_FRAME_LENGTH USB_CFG_LONG_TRANSFERS; do \ - $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1"; \ - $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1 -DDUSB_CFG_IMPLEMENT_FN_WRITEOUT=1"; \ + $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1" || exit 1; \ + $(MAKE) clean; $(MAKE) main.elf F_CPU=$$freq "DEFINES=-D$$opt=1 -DDUSB_CFG_IMPLEMENT_FN_WRITEOUT=1" || exit 1; \ done \ done -# $(MAKE) clean; $(MAKE) main_i.elf "DEFINES=-DUSBPUBLIC=static -DUSE_INCLUDE=1" -# avr-size main_i.elf | tail -1 | awk '{print "static", $$1+$$2, $$3}' >>$(SIZES_TMP) +# The following rule is used to check the compiler +devices: #exclude devices without RAM for stack and atmega603 for gcc 3 + excludes="at90s1200 attiny11 attiny12 attiny15 attiny28"; \ + for gccVersion in 3 4; do \ + avr-gcc-select $$gccVersion; \ + for device in `echo | avr-gcc -xc -mmcu=x - 2>&1 | egrep '^ *at[a-zA-Z0-9_-]+$$'`; do \ + if echo "$$excludes" | grep "$$device" >/dev/null; then continue; fi; \ + if [ "$$gccVersion" = 3 -a "$$device" = atmega603 ]; then continue; fi; \ + $(MAKE) clean; $(MAKE) null.elf DEVICE=$$device || exit 1; \ + done \ + done + $(MAKE) clean + avr-gcc-select 3 + @echo "+++ Device test succeeded!" # rule for deleting dependent files (those which can be built by Make): clean: -- cgit v1.2.3