<?xml version="1.0" encoding="UTF-8"?>
<feed xmlns="http://www.w3.org/2005/Atom" xml:lang="en-gb">
	<link rel="self" type="application/atom+xml" href="https://forums.obdev.at/app.php/feed/topic/6098" />

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2011-10-17T18:33:17+02:00</updated>

	<author><name><![CDATA[Objective Development Forums]]></name></author>
	<id>https://forums.obdev.at/app.php/feed/topic/6098</id>

		<entry>
		<author><name><![CDATA[Kubax]]></name></author>
		<updated>2011-10-17T18:33:17+02:00</updated>

		<published>2011-10-17T18:33:17+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19886#p19886</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19886#p19886"/>
		<title type="html"><![CDATA[Re: [hid-custom-rq] add new Request with multiple Byte return]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19886#p19886"><![CDATA[
instead of hitting myself with my hand, and risk a broken heand, i'll give the head against wall thingy a try....<br /><br /><img src="http://forums.gamesquad.com/images/smilies2/wall.gif" class="postimage" alt="Image" /><br /><br />seems, that my head is less neaded (or even used) while trying around...<br /><br />manny manny thanks for pointing this out.. even if i should have seen it... just one line deeper -.-<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=5877">Kubax</a> — Mon Oct 17, 2011 6:33 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[Daid]]></name></author>
		<updated>2011-10-17T17:12:05+02:00</updated>

		<published>2011-10-17T17:12:05+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19885#p19885</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19885#p19885"/>
		<title type="html"><![CDATA[Re: [hid-custom-rq] add new Request with multiple Byte return]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19885#p19885"><![CDATA[
You're going to hit yourself in the head:<br /><div class="codebox"><p>Code: </p><pre><code>return 1;                       /* tell the driver to send 1 byte */</code></pre></div><br />Maybe you need to send 3 bytes instead of 1?<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=5154">Daid</a> — Mon Oct 17, 2011 5:12 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[Kubax]]></name></author>
		<updated>2011-10-17T15:15:47+02:00</updated>

		<published>2011-10-17T15:15:47+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19882#p19882</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19882#p19882"/>
		<title type="html"><![CDATA[[hid-custom-rq] add new Request with multiple Byte return]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=6098&amp;p=19882#p19882"><![CDATA[
Hi,<br /><br />i'm completely new to v-usb (and only got realy small knowledge to AVR)<br /><br />I've a Curcuit for USB Generic Hid (including an ISP-Port) and try to make a Generic HID device, to get the status of a potentiometer.<br /><br />I managed to get the &quot;hid-custom-rq&quot; example to work and now i'm trying to add a new request.<br /><br />The problem is, that i wanted to test multiple byte answer (to report back the value from the potentiometer) so i added the request id 3 (CUSTOM_RQ_GET_POTI) and set the dataBuffer to the size of 4 and then to [0] = 0 ; [1] = 1 ; [2] = 1. All works fine i think, but on the client side, i only get the first byte and the others are random (or zero if i first clear the buffer)<br /><br />could anybody give me a hint what i#m doing wrong?<br /><br />here is the code for the usb device<br /><br />request.h<div class="codebox"><p>Code: </p><pre><code>/* Name: requests.h<br /> * Project: custom-class, a basic USB example<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2008-04-09<br /> * Tabsize: 4<br /> * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH<br /> * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)<br /> * This Revision: $Id: requests.h 692 2008-11-07 15:07:40Z cs $<br /> */<br /><br />/* This header is shared between the firmware and the host software. It<br /> * defines the USB request numbers (and optionally data types) used to<br /> * communicate between the host and the device.<br /> */<br /><br />#ifndef __REQUESTS_H_INCLUDED__<br />#define __REQUESTS_H_INCLUDED__<br /><br />#define CUSTOM_RQ_SET_STATUS    1<br />/* Set the LED status. Control-OUT.<br /> * The requested status is passed in the &quot;wValue&quot; field of the control<br /> * transfer. No OUT data is sent. Bit 0 of the low byte of wValue controls<br /> * the LED.<br /> */<br /><br />#define CUSTOM_RQ_GET_STATUS    2<br />/* Get the current LED status. Control-IN.<br /> * This control transfer involves a 1 byte data phase where the device sends<br /> * the current status to the host. The status is in bit 0 of the byte.<br /> */<br /> <br /> #define CUSTOM_RQ_GET_POTI      3<br /> <br /><br />#endif /* __REQUESTS_H_INCLUDED__ */<br /></code></pre></div><br /><br />main.c<br /><div class="codebox"><p>Code: </p><pre><code>/* Name: main.c<br /> * Project: hid-custom-rq example<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2008-04-07<br /> * Tabsize: 4<br /> * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH<br /> * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)<br /> * This Revision: $Id: main.c 790 2010-05-30 21:00:26Z cs $<br /> */<br /><br />/*<br />This example should run on most AVRs with only little changes. No special<br />hardware resources except INT0 are used. You may have to change usbconfig.h for<br />different I/O pins for USB. Please note that USB D+ must be the INT0 pin, or<br />at least be connected to INT0 as well.<br />We assume that an LED is connected to port B bit 0. If you connect it to a<br />different port or bit, change the macros below:<br />*/<br />#define LED_PORT_DDR        DDRB<br />#define LED_PORT_OUTPUT     PORTB<br />#define LED_BIT             0<br /><br />#include &lt;avr/io.h&gt;<br />#include &lt;avr/wdt.h&gt;<br />#include &lt;avr/interrupt.h&gt;  /* for sei() */<br />#include &lt;util/delay.h&gt;     /* for _delay_ms() */<br /><br />#include &lt;avr/pgmspace.h&gt;   /* required by usbdrv.h */<br />#include &quot;usbdrv.h&quot;<br />#include &quot;oddebug.h&quot;        /* This is also an example for using debug macros */<br />#include &quot;requests.h&quot;       /* The custom request numbers we use */<br /><br />/* ------------------------------------------------------------------------- */<br />/* ----------------------------- USB interface ----------------------------- */<br />/* ------------------------------------------------------------------------- */<br /><br />PROGMEM char usbHidReportDescriptor&#91;22&#93; = {    /* USB report descriptor */<br />    0x06, 0x00, 0xff,              // USAGE_PAGE (Generic Desktop)<br />    0x09, 0x01,                    // USAGE (Vendor Usage 1)<br />    0xa1, 0x01,                    // COLLECTION (Application)<br />    0x15, 0x00,                    //   LOGICAL_MINIMUM (0)<br />    0x26, 0xff, 0x00,              //   LOGICAL_MAXIMUM (255)<br />    0x75, 0x08,                    //   REPORT_SIZE (8)<br />    0x95, 0x01,                    //   REPORT_COUNT (1)<br />    0x09, 0x00,                    //   USAGE (Undefined)<br />    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)<br />    0xc0                           // END_COLLECTION<br />};<br />/* The descriptor above is a dummy only, it silences the drivers. The report<br /> * it describes consists of one byte of undefined data.<br /> * We don't transfer our data through HID reports, we use custom requests<br /> * instead.<br /> */<br /><br />/* ------------------------------------------------------------------------- */<br /><br />usbMsgLen_t usbFunctionSetup(uchar data&#91;8&#93;)<br />{<br />usbRequest_t    *rq = (void *)data;<br /><br />    if((rq-&gt;bmRequestType &amp; USBRQ_TYPE_MASK) == USBRQ_TYPE_VENDOR){<br />        DBG1(0x50, &amp;rq-&gt;bRequest, 1);   /* debug output: print our request */<br />        if(rq-&gt;bRequest == CUSTOM_RQ_SET_STATUS){<br />            if(rq-&gt;wValue.bytes&#91;0&#93; &amp; 1){    /* set LED */<br />                LED_PORT_OUTPUT |= _BV(LED_BIT);<br />            }else{                          /* clear LED */<br />                LED_PORT_OUTPUT &amp;= ~_BV(LED_BIT);<br />            }<br />        }else if(rq-&gt;bRequest == CUSTOM_RQ_GET_STATUS){<br />            static uchar dataBuffer&#91;1&#93;;     /* buffer must stay valid when usbFunctionSetup returns */<br />            dataBuffer&#91;0&#93; = ((LED_PORT_OUTPUT &amp; _BV(LED_BIT)) != 0);<br />            usbMsgPtr = dataBuffer;         /* tell the driver which data to return */<br />            return 1;                       /* tell the driver to send 1 byte */<br />        }else if(rq-&gt;bRequest == CUSTOM_RQ_GET_POTI) {<br />         static uchar dataBuffer&#91;3&#93;;     /* buffer must stay valid when usbFunctionSetup returns */<br />            //dataBuffer&#91;0&#93; = ((LED_PORT_OUTPUT &amp; _BV(LED_BIT)) != 0);<br />         <br />         dataBuffer&#91;0&#93; = 0;<br />         dataBuffer&#91;1&#93; = 1;<br />         dataBuffer&#91;2&#93; = 1;<br />            usbMsgPtr = dataBuffer;         /* tell the driver which data to return */<br />            return 1;                       /* tell the driver to send 1 byte */<br />      }<br />    }else{<br />        /* calss requests USBRQ_HID_GET_REPORT and USBRQ_HID_SET_REPORT are<br />         * not implemented since we never call them. The operating system<br />         * won't call them either because our descriptor defines no meaning.<br />         */<br />    }<br />    return 0;   /* default for not implemented requests: return no data back to host */<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /><br />int __attribute__((noreturn)) main(void)<br />{<br />uchar   i;<br /><br />    wdt_enable(WDTO_1S);<br />    /* Even if you don't use the watchdog, turn it off here. On newer devices,<br />     * the status of the watchdog (on/off, period) is PRESERVED OVER RESET!<br />     */<br />    /* RESET status: all port bits are inputs without pull-up.<br />     * That's the way we need D+ and D-. Therefore we don't need any<br />     * additional hardware initialization.<br />     */<br />    odDebugInit();<br />    DBG1(0x00, 0, 0);       /* debug output: main starts */<br />    usbInit();<br />    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */<br />    i = 0;<br />    while(--i){             /* fake USB disconnect for &gt; 250 ms */<br />        wdt_reset();<br />        _delay_ms(1);<br />    }<br />    usbDeviceConnect();<br />    LED_PORT_DDR |= _BV(LED_BIT);   /* make the LED bit an output */<br />    sei();<br />    DBG1(0x01, 0, 0);       /* debug output: main loop starts */<br />    for(;;){                /* main event loop */<br />#if 0   /* this is a bit too aggressive for a debug output */<br />        DBG2(0x02, 0, 0);   /* debug output: main loop iterates */<br />#endif<br />        wdt_reset();<br />        usbPoll();<br />    }<br />}<br /><br />/* ------------------------------------------------------------------------- */<br /></code></pre></div><br /><br />and here the code for the client.<br /><br />set_led.cpp<br /><div class="codebox"><p>Code: </p><pre><code>/* Name: set-led.c<br /> * Project: hid-custom-rq example<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2008-04-10<br /> * Tabsize: 4<br /> * Copyright: (c) 2008 by OBJECTIVE DEVELOPMENT Software GmbH<br /> * License: GNU GPL v2 (see License.txt), GNU GPL v3 or proprietary (CommercialLicense.txt)<br /> * This Revision: $Id: set-led.c 692 2008-11-07 15:07:40Z cs $<br /> */<br /><br />/*<br />General Description:<br />This is the host-side driver for the custom-class example device. It searches<br />the USB for the LEDControl device and sends the requests understood by this<br />device.<br />This program must be linked with libusb on Unix and libusb-win32 on Windows.<br />See http://libusb.sourceforge.net/ or http://libusb-win32.sourceforge.net/<br />respectively.<br />*/<br /><br />#include &lt;stdio.h&gt;<br />#include &lt;stdlib.h&gt;<br />#include &lt;string.h&gt;<br />//#include &lt;usb.h&gt;        /* this is libusb */<br />#include &lt;lusb0_usb.h&gt;<br />#include &quot;opendevice.h&quot; /* common code moved to separate module */<br /><br />#include &quot;requests.h&quot;   /* custom request numbers */<br />#include &quot;usbconfig.h&quot;  /* device's VID/PID and names */<br /><br />static void usage(char *name)<br />{<br />    fprintf(stderr, &quot;usage:\n&quot;);<br />    fprintf(stderr, &quot;  %s on ....... turn on LED\n&quot;, name);<br />    fprintf(stderr, &quot;  %s off ...... turn off LED\n&quot;, name);<br />    fprintf(stderr, &quot;  %s status ... ask current status of LED\n&quot;, name);<br />#if ENABLE_TEST<br />    fprintf(stderr, &quot;  %s test ..... run driver reliability test\n&quot;, name);<br />#endif /* ENABLE_TEST */<br />}<br /><br />int main(int argc, char **argv)<br />{<br />usb_dev_handle      *handle = NULL;<br />const unsigned char rawVid&#91;2&#93; = {USB_CFG_VENDOR_ID}, rawPid&#91;2&#93; = {USB_CFG_DEVICE_ID};<br />char                vendor&#91;&#93; = {USB_CFG_VENDOR_NAME, 0}, product&#91;&#93; = {USB_CFG_DEVICE_NAME, 0};<br />char                buffer&#91;4&#93;;<br />int                 cnt, vid, pid, isOn;<br />buffer&#91;0&#93; = 0;<br />buffer&#91;1&#93; = 0;<br />buffer&#91;2&#93; = 0;<br />buffer&#91;3&#93; = 0;<br />    usb_init();<br />    if(argc &lt; 2){   /* we need at least one argument */<br />        usage(argv&#91;0&#93;);<br />        exit(1);<br />    }<br />    /* compute VID/PID from usbconfig.h so that there is a central source of information */<br />    vid = rawVid&#91;1&#93; * 256 + rawVid&#91;0&#93;;<br />    pid = rawPid&#91;1&#93; * 256 + rawPid&#91;0&#93;;<br />    /* The following function is in opendevice.c: */<br />    if(usbOpenDevice(&amp;handle, vid, vendor, pid, product, NULL, NULL, NULL) != 0){<br />        fprintf(stderr, &quot;Could not find USB device \&quot;%s\&quot; with vid=0x%x pid=0x%x\n&quot;, product, vid, pid);<br />        exit(1);<br />    }<br />    /* Since we use only control endpoint 0, we don't need to choose a<br />     * configuration and interface. Reading device descriptor and setting a<br />     * configuration and interface is done through endpoint 0 after all.<br />     * However, newer versions of Linux require that we claim an interface<br />     * even for endpoint 0. Enable the following code if your operating system<br />     * needs it: */<br />#if 0<br />    int retries = 1, usbConfiguration = 1, usbInterface = 0;<br />    if(usb_set_configuration(handle, usbConfiguration) &amp;&amp; showWarnings){<br />        fprintf(stderr, &quot;Warning: could not set configuration: %s\n&quot;, usb_strerror());<br />    }<br />    /* now try to claim the interface and detach the kernel HID driver on<br />     * Linux and other operating systems which support the call. */<br />    while((len = usb_claim_interface(handle, usbInterface)) != 0 &amp;&amp; retries-- &gt; 0){<br />#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP<br />        if(usb_detach_kernel_driver_np(handle, 0) &lt; 0 &amp;&amp; showWarnings){<br />            fprintf(stderr, &quot;Warning: could not detach kernel driver: %s\n&quot;, usb_strerror());<br />        }<br />#endif<br />    }<br />#endif<br /><br />    //if(strcasecmp(argv&#91;1&#93;, &quot;status&quot;) == 0){<br />   if(_stricmp(argv&#91;1&#93;, &quot;status&quot;) == 0){<br />        cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_GET_STATUS, 0, 0, buffer, sizeof(buffer), 5000);<br />        if(cnt &lt; 1){<br />            if(cnt &lt; 0){<br />                fprintf(stderr, &quot;USB error: %s\n&quot;, usb_strerror());<br />            }else{<br />                fprintf(stderr, &quot;only %d bytes received.\n&quot;, cnt);<br />            }<br />        }else{<br />            printf(&quot;LED is %s\n&quot;, buffer&#91;0&#93; ? &quot;on&quot; : &quot;off&quot;);<br />        }<br />   }else if(_stricmp(argv&#91;1&#93;, &quot;poti&quot;) == 0){<br />        cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, 3, 0, 0, buffer, sizeof(buffer), 5000);<br />        if(cnt &lt; 1){<br />            if(cnt &lt; 0){<br />                fprintf(stderr, &quot;USB error: %s\n&quot;, usb_strerror());<br />            }else{<br />                fprintf(stderr, &quot;only %d bytes received.\n&quot;, cnt);<br />            }<br />        }else{<br />            printf(&quot;LED is %d %d %d\n&quot;, buffer&#91;0&#93;,buffer&#91;1&#93;,buffer&#91;2&#93;);<br />        }<br />//    }else if((isOn = (strcasecmp(argv&#91;1&#93;, &quot;on&quot;) == 0)) || strcasecmp(argv&#91;1&#93;, &quot;off&quot;) == 0){<br />   }else if((isOn = (_stricmp(argv&#91;1&#93;, &quot;on&quot;) == 0)) || _stricmp(argv&#91;1&#93;, &quot;off&quot;) == 0){<br />        cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_OUT, CUSTOM_RQ_SET_STATUS, isOn, 0, buffer, 0, 5000);<br />        if(cnt &lt; 0){<br />            fprintf(stderr, &quot;USB error: %s\n&quot;, usb_strerror());<br />        }<br />#if ENABLE_TEST<br />    }else if(strcasecmp(argv&#91;1&#93;, &quot;test&quot;) == 0){<br />        int i;<br />        srandomdev();<br />        for(i = 0; i &lt; 50000; i++){<br />            int value = random() &amp; 0xffff, index = random() &amp; 0xffff;<br />            int rxValue, rxIndex;<br />            if((i+1) % 100 == 0){<br />                fprintf(stderr, &quot;\r%05d&quot;, i+1);<br />                fflush(stderr);<br />            }<br />            cnt = usb_control_msg(handle, USB_TYPE_VENDOR | USB_RECIP_DEVICE | USB_ENDPOINT_IN, CUSTOM_RQ_ECHO, value, index, buffer, sizeof(buffer), 5000);<br />            if(cnt &lt; 0){<br />                fprintf(stderr, &quot;\nUSB error in iteration %d: %s\n&quot;, i, usb_strerror());<br />                break;<br />            }else if(cnt != 4){<br />                fprintf(stderr, &quot;\nerror in iteration %d: %d bytes received instead of 4\n&quot;, i, cnt);<br />                break;<br />            }<br />            rxValue = ((int)buffer&#91;0&#93; &amp; 0xff) | (((int)buffer&#91;1&#93; &amp; 0xff) &lt;&lt; 8);<br />            rxIndex = ((int)buffer&#91;2&#93; &amp; 0xff) | (((int)buffer&#91;3&#93; &amp; 0xff) &lt;&lt; 8);<br />            if(rxValue != value || rxIndex != index){<br />                fprintf(stderr, &quot;\ndata error in iteration %d:\n&quot;, i);<br />                fprintf(stderr, &quot;rxValue = 0x%04x value = 0x%04x\n&quot;, rxValue, value);<br />                fprintf(stderr, &quot;rxIndex = 0x%04x index = 0x%04x\n&quot;, rxIndex, index);<br />            }<br />        }<br />        fprintf(stderr, &quot;\nTest completed.\n&quot;);<br />#endif /* ENABLE_TEST */<br />    }else{<br />        usage(argv&#91;0&#93;);<br />        exit(1);<br />    }<br />    usb_close(handle);<br />    return 0;<br />}<br /></code></pre></div><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=5877">Kubax</a> — Mon Oct 17, 2011 3:15 pm</p><hr />
]]></content>
	</entry>
	</feed>
