<?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/3401" />

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2009-10-19T15:07:49+02:00</updated>

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

		<entry>
		<author><name><![CDATA[SA007]]></name></author>
		<updated>2009-10-19T15:07:49+02:00</updated>

		<published>2009-10-19T15:07:49+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=3401&amp;p=11425#p11425</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=3401&amp;p=11425#p11425"/>
		<title type="html"><![CDATA[HID device won't communicate under windows.]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=3401&amp;p=11425#p11425"><![CDATA[
I've based a hardware PWM RGB controller on USB-HID, mostly copied from the Automator example.<br /><br />Under Linux I've got almost everything working (GET_REPORT still acts funny, but I don't really have to use that)<br /><br />Under windows is another story, It detects the device (no error on connect) but if I try to send a report I get USB_ERROR_IO back from usb-windows.c.<br /><br />I compile the windows application using mingw with the usb files from Automator.<br /><br />Here are what I think are the relevant code segments for this problem:<br />Control app (set-led.c)<br /><div class="codebox"><p>Code: </p><pre><code>#include &quot;usbcalls.h&quot;<br />&#91;...&#93;<br />    if(usbOpenDevice(&amp;dev, vid, vendor, pid, product, 1) != 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 />&#91;...&#93;<br />        buffer&#91;0&#93; = CUSTOM_RQ_SET_RED;<br />        buffer&#91;1&#93; = atoi(argv&#91;2&#93;);<br />        if((err = usbSetReport(dev, USB_HID_REPORT_TYPE_FEATURE, buffer, 2)) != 0){<br />                fprintf(stderr, &quot;Error sending value: %s\n&quot;, usbErrorMessage(err));<br />                goto errorOccurred;<br />        }<br />&#91;...&#93;<br />errorOccurred:<br />    if(dev != NULL)<br />        usbCloseDevice(dev);<br />    return 0;<br />}</code></pre></div><br /><br />The pieces of relevant firmware code:<br /><div class="codebox"><p>Code: </p><pre><code>static uchar expectWrite;<br /><br />/* ------------------------------------------------------------------------- */<br />/* ------------------------ interface to USB driver ------------------------ */<br />/* ------------------------------------------------------------------------- */<br /><br />PROGMEM char usbHidReportDescriptor&#91;33&#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 />    0x85, 0x01,                    //   REPORT_ID (1)<br />    0x95, 0x02,                    //   REPORT_COUNT (2)<br />    0x09, 0x00,                    //   USAGE (Undefined)<br />    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)<br />    0x85, 0x02,                    //   REPORT_ID (2)<br />    0x95, 0x80,                    //   REPORT_COUNT (128)<br />    0x09, 0x00,                    //   USAGE (Undefined)<br />    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)<br />    0xc0                           // END_COLLECTION<br />};<br /><br />uchar   usbFunctionRead(uchar *data, uchar len)<br />{<br />        data&#91;0&#93; = CUSTOM_RQ_GET_STATUS;<br />        data&#91;1&#93; = 255 - OCR0B;<br />        data&#91;2&#93; = 255 - OCR0A;<br />        data&#91;3&#93; = 255 - OCR1B;<br />        return 4;<br />}<br /><br />uchar   usbFunctionWrite(uchar *data, uchar len)<br />{<br />  if (expectWrite == 0) return 1;<br />  if ((expectWrite == CUSTOM_RQ_SET_RED)|(expectWrite == CUSTOM_RQ_SET_GREEN)|(expectWrite == CUSTOM_RQ_SET_BLUE)) {<br />        expectWrite = 0;<br />        if(len &lt; 2)<br />            return 0xff;        /* stall */<br />        switch (data&#91;0&#93;) {<br />                case CUSTOM_RQ_SET_RED:<br />                        OCR0B = 255 - data&#91;1&#93;;<br />                        break;<br />                case CUSTOM_RQ_SET_GREEN:<br />                        OCR0A = 255 - data&#91;1&#93;;<br />                        break;<br />                case CUSTOM_RQ_SET_BLUE:<br />                        OCR1B = 255 - data&#91;1&#93;;<br />                        break;<br />        }<br />        return 1;<br />  }<br />  if (expectWrite == CUSTOM_RQ_SET_ALL) {<br />        expectWrite = 0;<br />        if(len &lt; 4)<br />            return 0xff;        /* stall */<br />        OCR0B = 255 - data&#91;1&#93;;<br />        OCR0A = 255 - data&#91;2&#93;;<br />        OCR1B = 255 - data&#91;3&#93;;<br />        return 1;<br />  }<br />  return 0;<br />}<br /><br />uchar   usbFunctionSetup(uchar data&#91;8&#93;)<br />{<br />    static uchar    replyBuf&#91;4&#93;;<br />    usbRequest_t    *rq = (void *)data;<br /><br />    usbMsgPtr = replyBuf;<br />    if((rq-&gt;bmRequestType &amp; USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {<br />        if(rq-&gt;bRequest == USBRQ_HID_GET_REPORT){<br />            if(rq-&gt;wValue.bytes&#91;0&#93; == CUSTOM_RQ_GET_STATUS){<br />                return 0xff;<br />            }<br />        }else if(rq-&gt;bRequest == USBRQ_HID_SET_REPORT){<br />          expectWrite = rq-&gt;wValue.bytes&#91;0&#93;;<br />          return 0xff;<br />        }<br />    }<br />    return 0;<br />}</code></pre></div><br />The rest is just some includes and register settings for the pwm timers and stuff.<br /><br />Almost all of the HID stuff is like a 1-on-1 copy from Automator, but I can't really get it to work at all.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=1649">SA007</a> — Mon Oct 19, 2009 3:07 pm</p><hr />
]]></content>
	</entry>
	</feed>
