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

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2011-02-12T17:39:22+02:00</updated>

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

		<entry>
		<author><name><![CDATA[klaute_]]></name></author>
		<updated>2011-02-12T17:39:22+02:00</updated>

		<published>2011-02-12T17:39:22+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=5450&amp;p=17591#p17591</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=5450&amp;p=17591#p17591"/>
		<title type="html"><![CDATA[Dynamic HidReportDescriptor length]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=5450&amp;p=17591#p17591"><![CDATA[
Hello,<br /><br />i got a problem with the dynamic and ram declaration of the HidReportDescriptor.<br /><br />My circuit is based on the with-zener.sch with a atmega168-20pu (running at 20MHz) which also contains a working<br />USBASP bootloader. I tested my hardware with the Hid-Mouse example successful and I'm using the V-USB 20100715 version.<br /><br />Now to my firmware, it is able to change mostly all of the possible usb-hid, -string and -configuration values at runtime.<br />Have a look at the code sniplet of my usbconfig.h.<br /><br />usbconfig.h:<br /><div class="codebox"><p>Code: </p><pre><code>...<br /><br />/* See USB specification if you want to conform to an existing device class or<br /> * protocol. The following classes must be set at interface level:<br /> * HID class is 3, no subclass and protocol required (but may be useful!)<br /> * CDC class is 2, use subclass 2 and protocol 1 for ACM<br /> */<br />#define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH        100<br />/* Define this to the length of the HID report descriptor, if you implement<br /> * an HID device. Otherwise don't define it or define it to 0.<br /> * If you use this define, you must add a PROGMEM character array named<br /> * &quot;usbHidReportDescriptor&quot; to your code which contains the report descriptor.<br /> * Don't forget to keep the array and this define in sync!<br /> */<br /><br />...<br /><br />#define USB_CFG_DESCR_PROPS_DEVICE                  ( USB_PROP_IS_RAM | USB_PROP_LENGTH(18) )<br />#define USB_CFG_DESCR_PROPS_CONFIGURATION           0<br />#define USB_CFG_DESCR_PROPS_STRINGS                 0<br />#define USB_CFG_DESCR_PROPS_STRING_0                0<br />#define USB_CFG_DESCR_PROPS_STRING_VENDOR           ( USB_PROP_IS_RAM | USB_PROP_IS_DYNAMIC )<br />#define USB_CFG_DESCR_PROPS_STRING_PRODUCT          ( USB_PROP_IS_RAM | USB_PROP_IS_DYNAMIC )<br />#define USB_CFG_DESCR_PROPS_STRING_SERIAL_NUMBER    ( USB_PROP_IS_RAM | USB_PROP_IS_DYNAMIC )<br />#define USB_CFG_DESCR_PROPS_HID                     0<br />#define USB_CFG_DESCR_PROPS_HID_REPORT              ( USB_PROP_IS_RAM | USB_PROP_IS_DYNAMIC )<br />#define USB_CFG_DESCR_PROPS_UNKNOWN                 0<br /><br />...<br /></code></pre></div><br /><br />The firmware is also able to change the HidReportDescriptors at runtime, so i put this into the RAM and marked it as dynamic.<br />As you can see in my code sniplet of the usbFunctionDescriptor, this function returns maxUSBHidReportDescriptorBytes.<br />It represent the actual amount of the HidReportDescriptor bytes.<br /><br />main.c:<br /><div class="codebox"><p>Code: </p><pre><code>...<br /><br />uchar usbFunctionDescriptor(usbRequest_t *rq)<br />{<br /><br />    switch ( rq-&gt;wValue.bytes&#91;1&#93; )<br />    {<br />        case USBDESCR_HID_REPORT :<br />            cleanDescriptor();<br />            usbMsgPtr = (uchar *)usbHidReportDescriptor; <br />            return maxUSBHidReportDescriptorBytes; // return size<br /><br />...<br /><br /></code></pre></div><br /><br />This works fine if the descriptor is smaller as, or it's size equals to, the in<br />USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH defined size. But only if I plug my hardware into a Linux<br />system (tested on Ubuntu 10.4 with a 2.6.32-29-generic kernel).<br /><br />But it does not work on Windows (tested on XP professional x86, Win Vista x86 Home premium, Win 7 x86 prof, Win 7 x64 prof/home premium).<br />The windows error message is something like &quot;The device could not started (Code 10)&quot;.<br /><br />After many hours of debugging,  using the search function of this forum and google i figured out that<br />USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH has to be the correct size of the actual amount of bytes of the<br />given HidReportDescriptor to get it work on a Windows system.<br /><br />If i define USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH to the correct size of the startup HidReportDescriptor,<br />it works well at windows and linux.<br /><br />Here is the part of the usbdrv.c, which i figured out as the problem. The USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH is<br />placed in FLASH memory, so the HidReportDescriptor could not be defined as &quot;is dynamic&quot; without defining USB_CFG_DESCR_PROPS_CONFIGURATION as &quot;in ram&quot; and &quot;is dynamic&quot; too.<br /><br />usbdrv.c:<br /><div class="codebox"><p>Code: </p><pre><code>    USB_CFG_INTERFACE_SUBCLASS,<br />    USB_CFG_INTERFACE_PROTOCOL,<br />    0,          /* string index for interface */<br />#if (USB_CFG_DESCR_PROPS_HID &amp; 0xff)    /* HID descriptor */<br />    9,          /* sizeof(usbDescrHID): length of descriptor in bytes */<br />    USBDESCR_HID,   /* descriptor type: HID */<br />    0x01, 0x01, /* BCD representation of HID version */<br />    0x00,       /* target country code */<br />    0x01,       /* number of HID Report (or other HID class) Descriptor infos to follow */<br />    0x22,       /* descriptor type: report */<br />    USB_CFG_HID_REPORT_DESCRIPTOR_LENGTH, 0,  /* total length of report descriptor */<br />#endif<br />#if USB_CFG_HAVE_INTRIN_ENDPOINT    /* endpoint descriptor for endpoint 1 */<br />    7,          /* sizeof(usbDescrEndpoint) */<br />    USBDESCR_ENDPOINT,  /* descriptor type = endpoint */<br />    (char)0x81, /* IN endpoint number 1 */<br />    0x03,       /* attrib: Interrupt endpoint */<br /></code></pre></div><br /><br />It looks like it could solve my problem by defining it like this, in order to change the size in<br />usbDescriptorConfiguration[25,26 !?] at runtime.<br /><br />But i'm not sure, so feel free to post any suggestions, questions...<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=3522">klaute_</a> — Sat Feb 12, 2011 5:39 pm</p><hr />
]]></content>
	</entry>
	</feed>
