Is iemand bekend met de USB-firmware GENHID (voor de 18F-serie) en het VB6-hostprogramma USBHDIO?

Het werkt bij mij deels (op een 18F2450, 8MHz kristal), maar geeft zowel in WIN98SE als in WINXP hetzelfde foute gedrag te zien: aanmelden lukt, de eerste keer zenden van data door de host geeft geen foutmelding maar er volgt geen ontvangst door de host van het identieke data-report van de PIC. Hierna herhalen van de procedure(zonder opnieuw aanmelden) gaat verder (meestal) goed. Soms zie ik mijn controle-ledjes flikkeren en stokt weer (1X) de ontvangst.

USBHDIO heb ik ook gebruikt, werkte hier prima... (W2K). Krijg steeds netjes data terug als ik op send/receive data knoppen druk...
Op de LVR site kun testprogramma's als HIDTEST.EXE downloaden om HID devices te testen...

Ja, met HIDtest krijg ik een configuratiefout. En nu verder zoeken.......
Arco, welke firmware gebruik jij, met welk configuratie-report?

Ik gebruik de assembler versie van de GenHid firmware:
http://pe.ece.olin.edu/ece/projects.html
Vogens mij gebruik ik de configuratie die er bij zit...

Arco,
Dezelfde als de mijne. Ik heb kleine veranderingen aangebracht voor gebruik op de PIC18F2450, maar misschien niet genoeg.
Merkwaardig: als ik USBHIDIO voorzie van 2X SetupDIGetDeviceInterfaceDetail loopt ie als een trein (met de bekende foutboodschap "gegevensgebied te klein", die je mag negeren). HIDtest geeft een configuratiefout zonder nadere verklaring, dus zoeken maar.

De eerste keer verzenden error is een fout in de firmware (was dat al weer vergeten)
Staat in deze thread beschreven hoe de firmware aan te passen...
Probleem was bij mij daarna verdwenen...

Arco, je thread geeft mij geen specifieke ingang op het PICforum. Een zoekterm als GENHID levert ook niets op. Omdat het waarschijnlijk al een oud onderwerp is, zou je me iets naders kunnen geven?
Tot zover al veel dank!

Benz,
Link werkt wel, maar niet altijd en soms wat langzaam. (Ik denk dat er wat mis is daar...)

Hier de betreffende tekst:


1) The data toggle bit should be cleared during the declaration of the EP1 Out endpoint. 
In >StandardRequests> case setConfiguration, the movlw 0xC8 should be 0x88 

    movlw   high (USB_Buffer+MAX_PACKET_SIZE+MAX_PACKET_SIZE) 
    movwf   BD1OAH, BANKED ; ...set its address 
    movlw   0x88 ; was 0xC8 --- ! BAD ! 
    movwf   BD1OST, BANKED ; set UOWN bit (USB can write EP1 OUT buffer) 

2) In the MAIN code, the BD1OBC register is being loaded incorrectly two ways: it is being loaded with a 
byte count of 8 instead of 2 as defined in the escriptors, and it is being loaded AFTER returning the 
control of EP1 registers to the USB SIE. The byte counter should be loaded BEFORE returning control to 
the SIE. So, in the MAIN application code, the original 

code: 

    banksel BD1OST 
    movf    BD1OST, W, BANKED ; get the EP1 OUT status register 
    andlw   0x40 ; extract the DATA01 bit 
    xorlw   0x40 ; toggle the DATA01 bit 
    iorlw   0x88 ; set UOWN and DTS bits 
    movwf   BD1OST, BANKED ; turn the buffer back over to USB 
    movlw   0x08 
    movwf   BD1OBC ; reset the EP1 OUT byte count 
repeat 

needs to be reordered / fixed with: 

    banksel BD1OST 
    movlw   0x02 
    movwf   BD1OBC ; reset the EP1 OUT byte count 
    movf    BD1OST, W, BANKED ; get the EP1 OUT status register 
    andlw   0x40 ; extract the DATA01 bit 
    xorlw   0x40 ; toggle the DATA01 bit 
    iorlw   0x88 ; set UOWN and DTS bits 
    movwf BD1OST, BANKED ; turn the buffer back over to USB 
    repeat 

[Bericht gewijzigd door Arco op (27%)]

Veel dank, Arco. Vandaag werkte je link naar behoren. Zoals je schrijft: waarschijnlijk problemen op de site, waardoor ik een time-out ondervind.
Ik ga aan de slag.

De genoemde wijzigingen heb ik doorgevoerd en mijn eerste probleem (1e keer fout bij write naar host) is opgelost. USBHIDIO loopt als een trein.
De merkwaardige foutboodschap van USBHIDIO, dat het gegevensgebied te klein is, blijft.
TESTHID geeft nog steeds een configuratiefout. Tenzij TESTHID doelt op de fout van het gegevensgebied werkt TESTHID anders dan USBHIDIO, want die laatste werkt gewoon.

De errormelding 'data area too small' na de eerste SetupDIGetDeviceInterfaceDetail call is normaal. De eerste keer wordt die functie aangeroepen met size 0 en een null pointer. Hierop geeft Windows de gewenste grootte van het datagebied door. Bij de tweede aanroep wordt dit gebruikt, en gaat alles goed...
Da's allemaal zoals het hoort...

Ik krijg geen configuratiefout met HidTest... Wanneer zie je die? Er zit wel een fout in als je bij Basic test -> Hid Strings indrukt. Dan blijft 'ie hangen. Zelfde als je Device Info drukt. (Want die test ook op HID strings)
Waarschijnlijk klopt de GetDescriptor -> String -> Default code niet in de Firmware.

[Bericht gewijzigd door Arco op (31%)]

Arco,
Voor alle zekerheid ook maar getest met een PIC18F4550-systeem met de compleet originele GENHID (met de PICForum-correcties), maar het gedrag is krek gelijk.
HIDTEST geeft bij beide systemen:
-HidDGetConfiguration: failed of no configuration
-HidDGetPhysicalDescriptor: failed
-HIDStrings loopt vast
-rest werkt.

[Bericht gewijzigd door BenZ op (13%)]

Hallo BenZ,

Getconfiguration faalt ook op 'originele' HID devices zoals de PicKit2, dus dat is niet zo erg. Het uitlezen van de strings is wel hinderlijk. Heb ik als volgt opgelost:

Heb 3 strings, naam, device, en serial no. Voor de rest retourneer ik dezelfde tekst. (in dit geval "-")
HID strings zegt dan altijd dat er 255 strings zijn en loopt niet meer vast.


Descriptor_begin
Device	
                db      0x12, DEVICE              ; bLength, bDescriptorType
                dw      0x0200                    ; USB Version
                db      0x00, 0x00                ; bDeviceClass, bDeviceSubClass
                db      0x00, DREC_SIZE           ; bDeviceProtocl, bMaxPacketSize
                dw      0x0925                    ; Vendor  ID
                dw      0x1299                    ; Product ID 
                dw      0x4321                    ; Device version 
                db      0x01, 0x02                ; iManufacturer, iProduct
                db      0x03, NUM_CONFIGURATIONS  ; iSerialNumber (none), bNumConfigurations

Configuration1
                db      0x09, CONFIGURATION       ; bLength, bDescriptorType
                db      0x29, 0x00                ; wTotalLength (low byte), wTotalLength (high byte)
                db      NUM_INTERFACES, 0x01      ; bNumInterfaces, bConfigurationValue
                db      0x00, 0xA0                ; iConfiguration (none), bmAttributes
                db      0x32, 0x09                ; bMaxPower (100 mA), bLength (Interface1 descriptor starts here)
                db      INTERFACE, 0x00           ; bDescriptorType, bInterfaceNumber
                db      0x00, 0x02                ; bAlternateSetting, bNumEndpoints (excluding EP0)
                db      0x03, 0x00                ; bInterfaceClass (HID code), bInterfaceSubClass
                db      0x00, 0x00                ; bInterfaceProtocol, iInterface (none)
HID1
                db      0x09, HID                 ; bLength, bDescriptorType
                db      0x01, 0x01                ; bcdHID (low byte), bcdHID (high byte)
                db      0x00, 0x01                ; bCountryCode (none), bNumDescriptors
                db      REPORT, 0x2F              ; bDescriptorType, wDescriptorLength (low byte)
                db      0x00, 0x07                ; wDescriptorLength (high byte), bLength (Endpoint1 descritor starts here)
                db      ENDPOINT, 0x81            ; bDescriptorType, bEndpointAddress (EP1 IN)
                db      0x03, 0x08                ; bmAttributes (Interrupt), wMaxPacketSize (low byte)
                db      0x00, 0x0A                ; wMaxPacketSize (high byte), bInterval (10 ms)
Endpoint2
                db      0x07, ENDPOINT            ; bLength, bDescriptorType
                db      0x01, 0x03                ; bEndpointAddress (EP1 OUT), bmAttributes (Interrupt)
                db      0x08, 0x00                ; wMaxPacketSize(low byte), wMaxPacketSize(high byte)  
                db      0x0A                      ; bInterval
Report1
                db      0x06, 0xA0                ; Usage Page (Vendor Defined),
                db      0xFF, 0x09                ; ..., Usage ID (Vendor Defined)
                db      0x01, 0xA1                ; ..., Collection (Application)
                db      0x01,0x09                 ; ...,     Usage ID (Vendor Defined)
                db      0x03, 0x15                ; ...,     Logical Minimum (0)
                db      0x00, 0x26                ; ...,     Logical Maximum (255)
                db      0x00, 0xFF                ; ...,
                db      0x75, 0x08                ;     Report Size (8 bits),
                db      0x95, 0x02                ;     Report Count (2 fields),
                db      0x81, 0x02                ;     Input (Data, Variable, Absolute),
                db      0x09, 0x04                ;     Usage ID (Vendor Defined),          
                db      0x15, 0x00                ;     Logical Minimum (0),
                db      0x26, 0x00                ;     Logical Maximum (255)
                db      0xFF, 0x75                ; ...,     Report Size (8 bits)
                db      0x08, 0x95                ; ...,     Report Count (2 fields)
                db      0x02, 0x91                ; ...,     Output (Data, Variable, Absolute)
                db      0x02, 0x09                ; ...,     Usage ID (Vendor Defined)      ; The Feature Report
                db      0x05, 0x15                ; ...,     Logical Minimum (0)
                db      0x00, 0x26                ; ...,     Logical Maximum (255)
                db      0x00, 0xFF                ; ...,
                db      0x75, 0x08                ;     Report Size (8 bits),
                db      0x95, 0x02                ;     Report Count (2 fields), 
                db      0xB1, 0x02                ;     Feature (Data, Variable, Absolute),
                db      0xC0                      ; End Collection

String0		
                db      String1-String0, STRING	; bLength, bDescriptorType
                db      0x09, 0x04			; wLANGID[0] (low byte), wLANGID[0] (high byte)
String1
                db      String2-String1, STRING	; bLength, bDescriptorType
                dw      'C','o','m','p','a','n','y',' ','n','a','m','e'
String2
                db      String3-String2, STRING	; bLength, bDescriptorType
                dw      'D','e','v','i','c','e',' ','t','y','p','e'
String3
                db      String255-String3, STRING	 ; bLength, bDescriptorType
                dw      'S','e','r','i','a','l','n','o',':'
String255
                db      Descriptor_end-String255, STRING	 ; bLength, bDescriptorType
                dw      '-'
Descriptor_end

                case STRING
                  bcf     USB_error_flags, 0, BANKED
                  movf    USB_buffer_data+wValue, W, BANKED
                    select
                      case 0
                        movlw   low (String0-Descriptor_begin)
                        break
                      case 1
                        movlw   low (String1-Descriptor_begin)
                        break
                      case 2
                        movlw   low (String2-Descriptor_begin)
                        break
                      case 3
                        movlw   low (String3-Descriptor_begin)
                        break
                      default
                        movlw   low (String255-Descriptor_begin)
                        break
                    ends

Dank Arco. Ik kan weer verder.

Ik ben inmiddels achter dat ik een verouderde versie van ENGR2210.INC gebruikte. Ook blijkt de db-assemblerdirective bij de PIC18-serie een veranderde werking te hebben gekregen, zodat mijn pogingen om de descriptors te ordenen verkeerd uitpakten.
Nu werkt alles naar behoren, zij het op lage snelheid.
Arco, werkt het bij jou (na aanpassingen van FSEN en descriptor) op full speed?

Ja full speed werkt prima. Het 'db' directive wordt inderdaad helaas om zeep geholpen door de compiler. Als de compiler een regel met een enkele 'db' tegenkomt vindt 'ie het nodig om er ongevraagd een 'dw' van te maken. Erg storend. :( (Tenslotte, als ik een 'dw' wil kan ik dat zelf wel maken...)

Ik kan er geen hoogte van krijgen ...

Met een gemodificeerd USBHIDIO-programma zend ik 250X een pakketje van 8 Bytes naar mijn PIC2450 die ingesteld is op een reportcount van 8. Evenzo zendt de PIC dat pakketje telkens retour. Bij een lowspeed-instelling en 24 MHz CPU-osc kost dat 4,6 s en bij fullspeed en 48 MHz osc precies 4 s.
Dat levert me een framerate op van 2X250 per 4 s = 125 per s, terwijl die in beide gevallen 1000 moet zijn (USBspecs hfst. 5).

Het resultaat is onafhankelijk van de PC, de USB-bus en aantal USB-apparaten aan de HUB.

De firmware is gebaseerd op GENHID met de correcties die op het PICforum zijn aangedragen.

Het lijkt sterk op 1 byte per frame, maar zowel de firmware als USBHIDIO werken volgens 8 bytes/report.
Iemand een idee?

PS. Wat is het voordeel van fullspeed boven lowspeed als je kleine pakketten (8 bytes) per keer verzendt?

Je moet dan wel de bInterval parameter in de descriptor aanpassen, anders lukt dat niet. Die staat nu op 10mS (0x0A), dus er kunnen nooit meer als 100 paketten per seconde worden verzonden. bInterval zit in ENDPOINT2 en HID1 (laatste parameter...). Ik heb hem op 1 staan...
Verder is het ook aan te raden grotere packetsize van 64 te kiezen, omdat dat veel efficienter is als 8x zoveel kleine pakketjes...

Arco, die laatste parameter van HID1 is het bInterval van endpoint1 (maar dat wist je natuurlijk al). Ik weet dat het efficienter is grotere pakketten te verzenden (en dat je dan naar fullspeed moet overstappen), maar momenteel wil ik doorgronden hoe het principieel zit.
Ik heb de beide intervallen al eens op 1 gezet, in lowspeed-mode, en dat leverde een snelheidsverschil op van 4,6 naar 2,8 s (ook voor 250 pakketjes van 8 bytes), mijns inziens geen erg grote snelheidswinst. In de verhalen van Brad Minch over lowspeed vs fullspeed op het PICforum noemt hij dit bInterval niet en ook in hfdst. 5 van de USBspecs wordt de framerate aangegeven zonder te vermelden dat die afhankelijk zou zijn van bInterval. Heb jij tijden gemeten en vergeleken (en met welke firmware/hostprogramma)?

Ik lees zojuist een regeltje in hfdst. 5 dat de minimale acces-periode van lowspeed 10 ms is en van fullspeed 1 ms. De host (in mijn geval: de HIDprocedures?) kan aanpassingen uitvoeren, zodat een meting nog tot andere uitkomsten kan leiden.
In ieder geval: eerst maar eens de intervallen op 1 ms zetten in mijn fullspeed firmware.

[Bericht gewijzigd door BenZ op (18%)]

Met de beide bIntervals op 1 ms, 48 MHz cpu-klok, T0CON-prescaler op 2, fullspeed USB kom ik op 250X zenden en ontvangen van 8 bytes op 0,5 s, zowel op USB1 als USB2-aansluitingen.

"fullspeed USB kom ik op 250X zenden en ontvangen van 8 bytes op 0,5 s"

Dat lijkt er meer op... In de lange thread van Brad Minch staat ergens dat de minimum response tijd van Windows (2000) 2 mS is met HID devices, zelfs als je hem op '1' zet.
Dat is dus 500*8=4000 bytes per seconde. Maximaal zou je dan 32.000 bytes kunnen versturen in 64 byte packets. (Kan zelfs nog meer als je meer als 1 endpoint gebruikt)

Arco, als ik het goed zie dient de timer om een voldoende lange wachttijd te hebben, waarmee het bInterval wordt overbrugd (om zeker te zijn van een service_usb die de ontvangst van een datapakket aangeeft). De instelling van de prescaler moet dan bij 48 MHz (=12 MHz instructiefrekw.) 64 zijn (levert 1,3 ms timer-periode op).
Mijn gemeten totaaltijd wordt dan door die toevoeging van wachttijd 0,7 s.
Tenzij je hierop nog commentaar hebt, wil ik het onderwerp sluiten, met dank voor de bijdragen.