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

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2009-06-05T00:01:56+02:00</updated>

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

		<entry>
		<author><name><![CDATA[dts]]></name></author>
		<updated>2009-05-15T14:01:02+02:00</updated>

		<published>2009-05-15T14:01:02+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=2190&amp;p=9345#p9345</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=2190&amp;p=9345#p9345"/>
		<title type="html"><![CDATA[Re: Using AVRUSB with Delphi TJvHidDevice]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=2190&amp;p=9345#p9345"><![CDATA[
Hello!<br />i was trying to use your code to communicate with Microchip PIC18F67J50 controller with HID demo firmware.<br />I got as far as &quot;Simple HID Device demo connected&quot; message.<br />When i try to use SetOutputReport function i get &quot;CRC error&quot; message.<br />With WriteFile i get error also.<br />Byte is not sent.<br />Hardware works with Microchip demo application. It sends 64 byte array with first byte set to $80, i watched with USB Monitor. Actually 1 byte is enough.<br /><br />Here are my write procedures:<br /><br />procedure TForm1.btnOutReportClick(Sender: TObject);<br />var<br />  Err: integer;<br />begin<br />  if Assigned(CurrentDevice) then<br />  begin<br />    Buf[0] := $80;<br />    if not CurrentDevice.SetOutputReport(Buf[0], 1) then<br />    begin<br />      Err := GetLastError;<br />      ListBox1.Items.Add(Format('SET REPORT ERROR: %s (%x)', [SysErrorMessage(Err), Err]));<br />    end<br />    else<br />      ListBox1.Items.Add(IntToHex(Buf[0], 2));<br />  end;<br />end;<br /><br />procedure TForm1.btnWriteClick(Sender: TObject);<br />var<br />  Towrite, Written: Cardinal;<br />  Err: integer;<br />begin<br />  if Assigned(CurrentDevice) then<br />  begin<br />    Buf[0] := $80;<br />    Towrite := 64;<br />//    HidCheck(CurrentDevice.WriteFile(Buf, Towrite, Written));<br />    if not CurrentDevice.WriteFile(Buf, Towrite, Written) then<br />      ListBox1.Items.Add(Format('%s (%x)',  [SysErrorMessage(Err), Err]))<br />    else<br />      ListBox1.Items.Add(IntToStr(Written));<br />  end;<br />end;<br /><br />Other stuff is same as yours.<br />What do you think could be wrong?<br /><br />Best regards,<br />dts<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=2256">dts</a> — Fri May 15, 2009 2:01 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[mschumann]]></name></author>
		<updated>2009-06-05T00:01:56+02:00 </updated>

		<published>2009-02-03T16:51:01+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=2190&amp;p=7807#p7807</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=2190&amp;p=7807#p7807"/>
		<title type="html"><![CDATA[[UPDATED] Using AVRUSB with Delphi TJvHidDevice]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=2190&amp;p=7807#p7807"><![CDATA[
[UPDATE]<br />I now found a better solution using the way shown by example HID_DATA from VUSB. It also works well with TJvHidDevice but one has to use the getFeature/setFeature methods for data transfer instead of reports. This doesnt trigger the events of the component so you have to poll it with a timer. In my current development (HTPC) this works absolutely fine.<br />[/UPDATE]<br /><br />Getting the ingenious USBDRV up and running on the ATMEGA was a snap. Since I am bound to Delphi 7 on the host side I had quite a few frustrating nights trying to get things up and running with LibUSB. It crashed often when disconnecting the device and so on. Then I discovered TJvHidDevice and tried this one since it does not need any additional drivers on the PC. It connected to my device but It took me some time to figure out how to communicate,. Maybe it saves time and frustration for someone out there so heres my solution:<br /><br />This device descriptor made it possible to communicate in 8 byte packtets which seems to be the upper limit for low speed devices.<br /><br /><div class="codebox"><p>Code: </p><pre><code>#define USB_BUFFER_SIZE 8<br />PROGMEM char usbHidReportDescriptor&#91;29&#93; = {<br />    0x06, 0xA0, 0xFF,   // USAGE_PAGE (Vendor Defined page 0xA1)<br />    0x09, 0x01,         // USAGE (Vendor Usage 0x01)<br />    0xA1, 0x01,         // COLLECTION (Application)<br />                        // Global items<br />    0x15, 0x00,         //   LOGICAL_MINIMUM(0)<br />    0x26, 0xFF, 0x00,   //   LOGICAL_MAXIMUM(255)<br />    0x75, 0x08,         //   REPORT_SIZE (8 Bits)<br />    0x95, USB_BUFFER_SIZE,    //   REPORT_COUNT (8  8 Bits, 8 Bytes)<br />                        // INPUT<br />    0x09, 0x03,         //   USAGE (Vendor Usage 0x03)<br />    0x81, 0x02,         //   INPUT (Data,Variable,Abs)<br />                        // OUTPUT<br />    0x09, 0x04,         //   USAGE (Vendor Usage 0x04)<br />    0x91, 0x02,         //   OUTPUT(Data, Variable,Abs<br />                        // Feature<br />    0x09, 0x05,         //   USAGE (Vendor Usage 0x05)<br />    0xB1, 0x02,         //   Feature (Data, Variable,Abs)<br />    0xC0                // END_COLLECTION<br />};<br /></code></pre></div><br /><br />On the AVR I Implemented only these functions<br /><br /><div class="codebox"><p>Code: </p><pre><code>static uchar rest, curpos, currep;<br />usbMsgLen_t usbFunctionSetup(uchar data&#91;8&#93;) {<br />usbRequest_t    *rq = (void *)data;<br />    // HID-Class Request<br />    if ((rq-&gt;bmRequestType &amp; USBRQ_TYPE_MASK) == USBRQ_TYPE_CLASS) {  <br />   if(rq-&gt;bRequest == USBRQ_HID_SET_REPORT) {<br /><br />    // Receiving more thana single byte needs usbFunctionWrite() <br />      curpos = 0;                <br />        rest = rq-&gt;wLength.word;  <br />        // Limit size<br />        if(rest &gt; sizeof(usbrec)) rest = sizeof(usbrec);<br />        // flag usage of usbFunctionWrite() <br />      return USB_NO_MSG;                   <br />      }<br />   }<br />    return 0;<br />}<br /><br />uchar usbFunctionWrite(uchar *data, uchar len)<br />{<br />   uchar i;<br />    if(len &gt; rest) len = rest;               <br />    rest -= len;<br />    for(i = 0; i &lt; len; i++)<br />        usbrec&#91;curpos++&#93; = data&#91;i&#93;;<br />    if (rest == 0) {<br />   <br />       // Process results<br />       <br />       // Write the buffer to my lcd display<br />        write(0,0,0,usbrec);<br />        <br />     return 1;<br />   }  <br />   else<br />      return 0;  <br />}<br /></code></pre></div><br /><br />Transferring data to the host is done this way<br /><br /><div class="codebox"><p>Code: </p><pre><code>usbSetInterrupt(usbcmd, sizeof(usbcmd));  // usbcmd is char&#91;8&#93;<br /></code></pre></div><br /><br />This works well and even triggers the onData Event of the delphi component! Here are the important parts of the delphi side:<br /><br /><div class="codebox"><p>Code: </p><pre><code>...<br />  private<br />    { Private-Deklarationen }<br />    dev: TJvHidDevice;<br />...<br />const<br />    USB_BUFFER_SIZE = 8;<br />...<br />type<br />  TLCD = packed record<br />    ID: byte;<br />    text: array&#91;0..USB_BUFFER_SIZE-1&#93; of char;<br />  end;<br />...<br />procedure TForm1.log(s: string);<br />begin<br />  ListBox1.ItemIndex := ListBox1.Items.Add(s);<br />end;<br />...<br />procedure TForm1.HIDCtlDeviceChange(Sender: TObject);<br />var<br />  x: integer;<br />  s: string;<br />begin<br />  with hidCtl do begin<br />    // check if owned device was plugged out<br />    if Assigned(Dev) and not Dev.IsPluggedIn then begin<br />      // give back device<br />      s := dev.ProductName;<br />      CheckIn(Dev);<br />      log(s + ' disconnected');<br />      dev := nil;<br />    end;<br />    // no device connected<br />    if not Assigned(Dev) then<br />      // take over device<br />      if CheckOutByID(Dev, $16C0, $05DF) then begin<br />        log(dev.ProductName + ' connected');<br />      end;<br />  end;<br />end;<br />...<br />procedure TForm1.Button1Click(Sender: TObject);<br />var<br /> rep:TLCD;<br /><br />begin<br />  if assigned(dev) then begin<br />    rep.id:=0;<br />    strpcopy(rep.text,'Hallo');<br />    dev.setOutputReport(rep,sizeOf(rep));<br />  end;<br />end;<br />...<br />procedure TForm1.HIDCtlDeviceData(HidDev: TJvHidDevice; ReportID: Byte;<br />  const Data: Pointer; Size: Word);<br />var<br />  buffer: array&#91;0..100&#93; of char;<br />  I: integer;<br />  s:string;<br />begin<br />     Move(Data^, buffer&#91;0&#93;, Size);<br />     s:='';<br />     for i:=0 to size-1 do s:=s+', '+intToStr(ord(buffer&#91;i&#93;));<br />     log(s); <br />end;<br /></code></pre></div><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=1744">mschumann</a> — Tue Feb 03, 2009 4:51 pm</p><hr />
]]></content>
	</entry>
	</feed>
