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

	<title>Objective Development Forums</title>
	
	<link href="https://forums.obdev.at/index.php" />
	<updated>2013-12-24T22:04:47+02:00</updated>

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

		<entry>
		<author><name><![CDATA[xiangrui]]></name></author>
		<updated>2013-12-24T22:04:47+02:00</updated>

		<published>2013-12-24T22:04:47+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26378#p26378</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26378#p26378"/>
		<title type="html"><![CDATA[Re: hidtool works on Linux, does not work on Windows 7]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26378#p26378"><![CDATA[
I also started with this tool. It seems to me that Windows system is more strict on following the descriptor. The data sent and received must have the length defined in the descriptor, otherwise it will report error. Under unix, you can read and write less data than defined. You may get a warning at some level of the driver.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=6201">xiangrui</a> — Tue Dec 24, 2013 10:04 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[filo]]></name></author>
		<updated>2013-12-19T19:53:45+02:00</updated>

		<published>2013-12-19T19:53:45+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26364#p26364</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26364#p26364"/>
		<title type="html"><![CDATA[Re: hidtool works on Linux, does not work on Windows 7]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26364#p26364"><![CDATA[
I figured out that the only change in hidtool.c I made is at line 94 - I decreased buffer size to print just 8 bytes (they wrap around at the device anyway). I reverted back to 129 bytes as in the stock demo and now it works on Windows. I still don't get why it worked modified on Unixes.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20128">filo</a> — Thu Dec 19, 2013 7:53 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[filo]]></name></author>
		<updated>2013-12-18T15:55:59+02:00</updated>

		<published>2013-12-18T15:55:59+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26359#p26359</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26359#p26359"/>
		<title type="html"><![CDATA[Re: hidtool works on Linux, does not work on Windows 7]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26359#p26359"><![CDATA[
Everything also works perfectly under OS X Maverics.<p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20128">filo</a> — Wed Dec 18, 2013 3:55 pm</p><hr />
]]></content>
	</entry>
		<entry>
		<author><name><![CDATA[filo]]></name></author>
		<updated>2013-12-18T12:57:16+02:00</updated>

		<published>2013-12-18T12:57:16+02:00</published>
		<id>https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26357#p26357</id>
		<link href="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26357#p26357"/>
		<title type="html"><![CDATA[hidtool works on Linux, does not work on Windows 7]]></title>

		
		<content type="html" xml:base="https://forums.obdev.at/viewtopic.php?t=8774&amp;p=26357#p26357"><![CDATA[
Hello,<br />I made a device based on the hid-data demo. It works great on Linux (tested on two machines), but <strong class="text-strong">hidtool read fails on Windows 7 64-bit</strong> (also tested on two different machines other then the Linux ones):<br /><div class="codebox"><p>Code: </p><pre><code>error reading data: Communication error with device<br /></code></pre></div><br />When I unplug it hidtool returns device not found.<br />The device is correctly enumerated and shown in device manager without warnings.<br />Hardware itself is not faulty, as <strong class="text-strong">I successfully used bootloadHID to upload new firmware in Windows 7.</strong><br /><br />The main.c:<br /><div class="codebox"><p>Code: </p><pre><code>/* Name: main.c<br /> * Project: hid-data, example how to use HID for data transfer<br /> * Author: Christian Starkjohann<br /> * Creation Date: 2008-04-11<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 /> */<br /><br />//demo modified by SP2AGX for yaesu antenna switch<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 />*/<br /><br />#include &lt;stdlib.h&gt;<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 />#include &lt;avr/eeprom.h&gt;<br />#include &lt;avr/pgmspace.h&gt;   /* required by usbdrv.h */<br />#include &quot;usbdrv.h&quot;<br /><br />/* ----------- application specific defines --------- */<br />#define LED_PTT_ON()   PORTD&amp;=~_BV(PD4)<br />#define LED_PTT_OFF()  PORTD|=_BV(PD4)<br />#define LED_MODE_ON()  PORTB&amp;=~_BV(PB5)<br />#define LED_MODE_OFF() PORTB|=_BV(PB5)<br />#define NO_PTT PINC&amp;_BV(PC1)<br />#define MODE_BUTTON_UP PINB&amp;_BV(PB4)<br />#define MODE_BUTTON_DOWN !(PINB&amp;_BV(PB4))<br />#define MODE_AUTO 1<br />#define MODE_MANUAL 0<br />/* ----------- runtime variables -------------------- */<br />//number of samples to average<br />#define ADC_SAMPLES_MAX 16<br />//there are 7 buttons, button 0 means none pressed (8 possible input states)<br />#define BUTTONS_N 8<br />unsigned char volatile adc_values&#91;ADC_SAMPLES_MAX&#93;;<br />unsigned char volatile adc_index=0;<br />unsigned char volatile process_keys=0;<br />unsigned char volatile demanded_antenna=1;<br />unsigned char volatile selected_antenna=0;<br />unsigned char volatile operation_mode=MODE_AUTO;<br />/* ----------- EEPROM variables --------------------- */<br />#define BAND_COUNT 17<br />unsigned char ee_band_antenna&#91;BAND_COUNT&#93; EEMEM;<br /><br />//done: ports initialization<br />//done: driver control<br />//done: radio interfacing + PTT lock<br />//done: key sampling<br />//done: memory reset<br />//done: EEPROM programming<br />//done: USB routines<br /><br />//prototypes<br />void switch_antenna(unsigned char n);<br />inline unsigned char get_band_input();<br />unsigned char get_button_pressed();<br /><br />/* ------------------------------------------------------------------------- */<br />/* ----------------------------- USB interface ----------------------------- */<br />/* ------------------------------------------------------------------------- */<br /><br />PROGMEM const 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, 0x10,                    //   REPORT_COUNT (16) changed!!!!!!!<br />    0x09, 0x00,                    //   USAGE (Undefined)<br />    0xb2, 0x02, 0x01,              //   FEATURE (Data,Var,Abs,Buf)<br />    0xc0                           // END_COLLECTION<br />};<br />/* Since we define only one feature report, we don't use report-IDs (which<br /> * would be the first byte of the report). The entire report consists of 128<br /> * opaque data bytes.<br /> */<br /><br />/* The following variables store the status of the current data transfer */<br />//static uchar    currentAddress;<br />//static uchar    bytesRemaining;<br />//static uchar    page_flag=0;<br /><br />/* ------------------------------------------------------------------------- */<br /><br /><br />/* usbFunctionRead() is called when the host requests a chunk of data from<br /> * the device. For more information see the documentation in usbdrv/usbdrv.h.<br /> */<br />uchar   usbFunctionRead(uchar *data, uchar len)<br />{<br /><br />  data&#91;0&#93;=operation_mode;<br />  data&#91;1&#93;=selected_antenna;<br />  data&#91;2&#93;=demanded_antenna;<br />  data&#91;3&#93;=get_band_input();<br />  data&#91;4&#93;=get_button_pressed();<br />  data&#91;5&#93;=ADCH;<br />  data&#91;6&#93;=NO_PTT;<br />  data&#91;7&#93;=0;<br />  return 8;<br />}<br /><br />/* usbFunctionWrite() is called when the host sends a chunk of data to the<br /> * device. For more information see the documentation in usbdrv/usbdrv.h.<br /> */<br />uchar   usbFunctionWrite(uchar *data, uchar len)<br />{<br />  if (data&#91;0&#93;=='M'){ // 0x4D<br />    if (data&#91;1&#93;==1){ //switch to manual mode<br />      operation_mode=MODE_MANUAL;<br />      demanded_antenna=data&#91;2&#93;;<br />      switch_antenna(demanded_antenna);<br />    }<br />  } else if (data&#91;0&#93;=='A'){// 0x41<br />    operation_mode=MODE_AUTO;//return to auto mode<br />  }<br />    return 1;<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_CLASS){    /* HID class request */<br />        if(rq-&gt;bRequest == USBRQ_HID_GET_REPORT){  /* wValue: ReportType (highbyte), ReportID (lowbyte) */<br />            /* since we have only one report type, we can ignore the report-ID */<br />       //page_flag=0;<br />            return USB_NO_MSG;  /* use usbFunctionRead() to obtain data */<br />        }else if(rq-&gt;bRequest == USBRQ_HID_SET_REPORT){<br />       //page_flag=0;<br />            /* since we have only one report type, we can ignore the report-ID */<br />            return USB_NO_MSG;  /* use usbFunctionWrite() to receive data from host */<br />        }<br />    }else{<br />        /* ignore vendor type requests, we don't use any */<br />    }<br />    return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br />//switches the selected antenna relay if not blocked by PTT<br />void switch_antenna(unsigned char n){<br />  if (NO_PTT){ // PTT not active<br />    if (selected_antenna!=n){ //if there is any need to change<br />      PORTD&amp;=~(_BV(PD5)|_BV(PD6)|_BV(PD7));          //all antennas<br />      PORTB&amp;=~(_BV(PB0)|_BV(PB1)|_BV(PB2)|_BV(PB3)); //    off<br />      switch(n){<br />        case 1:PORTB|=_BV(PB1);break; //PB1<br />        case 2:PORTB|=_BV(PB2);break; //PB2<br />        case 3:PORTB|=_BV(PB3);break; //PB3<br />        case 4:PORTB|=_BV(PB0);break; //PB0<br />        case 5:PORTD|=_BV(PD7);break; //PD7<br />        case 6:PORTD|=_BV(PD6);break; //PD6<br />        case 7:PORTD|=_BV(PD5);break; //PD5<br />      }<br />    selected_antenna=n;<br />    }<br />  }<br />}<br />/* ------------------------------------------------------------------------- */<br />//returns the selected band from transceiver output<br />inline unsigned char get_band_input(){<br />  return (PINC&gt;&gt;2)&amp;0xF; //read the inputs, shift to lower the value and mask high bits<br />}<br /><br />/* ------------------------------------------------------------------------- */<br />//averages ADC samples and picks the most likely pressed button<br />unsigned char get_button_pressed(){<br /> uint16_t error_table&#91;BUTTONS_N&#93;;<br /> unsigned char max_adc=0,min_adc=255;<br /> unsigned char i;<br /> unsigned char adc_value_avg;<br /> static const unsigned char perfect_value&#91;&#93;={0, 0xFF, 0xDB, 0xB6, 0x91, 0x6D, 0x48, 0x24 };//zero is simply lack of keys, constant pulldown resistor<br /> unsigned min_err=0xFFFF,min_err_i=0; //by default assume no key pressed<br /> <br />  for (i=0;i&lt;ADC_SAMPLES_MAX;i++){<br />    if (adc_values&#91;i&#93;&gt;max_adc){ max_adc=adc_values&#91;i&#93;; }<br />    if (adc_values&#91;i&#93;&lt;min_adc){ min_adc=adc_values&#91;i&#93;; }<br />  }<br /> <br />  if (max_adc-min_adc &lt; 10 ){ //all ADC values look stable, 10 is just a magic number<br />    adc_value_avg=((uint16_t)max_adc+min_adc)/2;<br /> <br />    for (i=0;i&lt;BUTTONS_N;i++){ //compute differences between ADC and perfect key values for each key<br />      if (adc_value_avg&gt;perfect_value&#91;i&#93;){ //prevents underflow at zero<br />   error_table&#91;i&#93; =  adc_value_avg - perfect_value&#91;i&#93;;<br />      } else {<br />   error_table&#91;i&#93; =  perfect_value&#91;i&#93; - adc_value_avg;<br />      }<br />    }<br />    <br />    for (i=0;i&lt;BUTTONS_N;i++){ //pick the smallest error<br />      if (error_table&#91;i&#93;&lt;min_err) {<br />   min_err=error_table&#91;i&#93;;<br />   min_err_i=i;<br />      }<br />    }<br />  }<br />  return min_err_i;<br />}<br />/* ------------------------------------------------------------------------- */<br />//reset to defaults, then halt<br />void memory_reset(){<br />   unsigned char i=0;<br />   for (i=0;i&lt;BAND_COUNT ;i++){<br />     eeprom_busy_wait();<br />     eeprom_write_byte(&amp;ee_band_antenna&#91;i&#93;,1);<br />   }<br />   LED_MODE_ON();<br />   LED_PTT_ON();<br />   PORTD|=_BV(PD6);//some extra leds<br />   PORTD|=_BV(PD5);<br />   while (1){<br />      cli();<br />      wdt_reset(); //endless loop, wait for power cycle<br />   }<br />  <br />}<br />/* ------------------------------------------------------------------------- */<br />int main(void)<br />{<br /><br />  wdt_reset();<br />  wdt_enable(WDTO_1S);<br /><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 /><br />    usbInit();<br />    usbDeviceDisconnect();  /* enforce re-enumeration, do this while interrupts are disabled! */<br /><br />    /* ----- ADC configuration ----- */<br />    ADMUX = _BV(REFS0)|_BV(ADLAR);//multiplexed button input ADC0, Aref=AVCC+cap, 8-bit left adjust<br />    ADCSRA = _BV(ADEN) | _BV(ADPS2) |  _BV(ADPS1) | _BV(ADPS0) | _BV(ADSC); //93kHz ADC clock, interrupt enable, start conversion<br /><br />    /* ----- pins configuration ----- */<br />    PORTC|=_BV(PC1)|_BV(PC2)|_BV(PC3)|_BV(PC4)|_BV(PC5); //PTT and band input pullup<br />    DDRD|= _BV(PD4)|_BV(PD5)|_BV(PD6)|_BV(PD7); //PTT_LED and relay driver output<br />    DDRB|= _BV(PB0)|_BV(PB1)|_BV(PB2)|_BV(PB3)|_BV(PB5); //MODE_LED and relay driver output<br />    LED_MODE_OFF();<br />    LED_PTT_OFF();<br />    PORTB|=_BV(PB4); //mode button input pullup<br /><br />    /* ---timer configuration for key sampling --- */<br />    TCCR0 = _BV(CS02); // 256 prescaling, ~180Hz interrupt rate<br />    TIMSK = _BV(TOIE0);<br />    <br />    loop_until_bit_is_set(ADCSRA,ADIF);//wait for the first ADC conversion<br />    if (ADCH&gt;200){<br />      memory_reset();<br />    }<br />    ADCSRA |= _BV(ADIE); //enable ADC interrupt<br />    <br />    unsigned char i = 0;<br />    while(--i){             /* fake USB disconnect for &gt; 250 ms */<br />        wdt_reset();<br />        _delay_ms(1);<br />    }<br />    usbDeviceConnect();<br />    sei();<br />    <br />    for(;;){                /* main event loop */<br />        wdt_reset();<br />        usbPoll();<br /><br />   if (process_keys){ //slow processing loop, ~180Hz rate<br />     process_keys=0;<br />     unsigned char button=get_button_pressed();<br />     <br />     if (button){ //any button pressed<br />       if (MODE_BUTTON_DOWN){ //memory programming<br />         eeprom_busy_wait();<br />         eeprom_write_byte(&amp;ee_band_antenna&#91;get_band_input()&#93;,button);<br />         eeprom_busy_wait();<br />         operation_mode=MODE_AUTO;<br />       } else {      //regular manual switch<br />         operation_mode=MODE_MANUAL;<br />         demanded_antenna=button;<br />       }<br />     }<br />     <br />     if (operation_mode==MODE_AUTO){<br />       demanded_antenna=eeprom_read_byte(&amp;ee_band_antenna&#91;get_band_input()&#93;); //retrive the programmed antenna from eeprom<br />       LED_MODE_ON();<br />     } else {<br />       LED_MODE_OFF();<br />     }<br />     <br />     if (MODE_BUTTON_DOWN){<br />       operation_mode=MODE_AUTO;<br />     }<br />   }<br /><br />   if (NO_PTT){<br />     LED_PTT_OFF();<br />   } else {<br />     LED_PTT_ON();<br />   }<br />   <br />   switch_antenna(demanded_antenna);<br />    }<br />    return 0;<br />}<br /><br />/* ------------------------------------------------------------------------- */<br />//key sampling interrupt<br /><br />ISR (TIMER0_OVF_vect, ISR_NOBLOCK){ //interrupt should be interruptable<br />  TIMSK &amp;= ~_BV(TOIE0);//disable timer interrupt<br />  ADCSRA |= _BV(ADSC); //start next conversion<br />}<br /><br />ISR (ADC_vect, ISR_NOBLOCK){ //interrupt should be interruptable<br />        adc_values&#91;adc_index&#93;=ADCH; //store current value<br />   adc_index++;<br />   if (adc_index==ADC_SAMPLES_MAX){<br />     adc_index=0;<br />     process_keys=1;<br />   }<br />   TCNT0 = 0; //reset delay timer<br />   TIMSK |= _BV(TOIE0);//enable timer interrupt<br />}<br /><br /></code></pre></div><br />I also tried changing REPORT_COUNT (16) back to defaults, though I've built a different device using an identical descriptor that actually works under Windows.<br /><br />I did a communication dump using Wireshark:<br /><a href="http://sp2put.utp.edu.pl/~filo/yas/yas_usbdump.pcapng" class="postlink">http://sp2put.utp.edu.pl/~filo/yas/yas_usbdump.pcapng</a><br />The device is probably connected after packet 53.<br />I try to execute hidtool read at packet 77 and then again at packet 83.<br /><br />The device itself is a little more described at <a href="http://sp2put.utp.edu.pl/index.php/2761,automatyczny-przelacznik-anten-do-yaesu-ft-950-z-usb?lang=en" class="postlink">http://sp2put.utp.edu.pl/index.php/2761,automatyczny-przelacznik-anten-do-yaesu-ft-950-z-usb?lang=en</a><p>Statistics: Posted by <a href="https://forums.obdev.at/memberlist.php?mode=viewprofile&amp;u=20128">filo</a> — Wed Dec 18, 2013 12:57 pm</p><hr />
]]></content>
	</entry>
	</feed>
