Hallo Leute.
Ich möchte gerne Daten über USB vom PC zu einem Atmega32 senden. Ich
habe dafür auf dem PC die LibUSBDotNet Bibliothek installiert und nutze
VB.net für das PC Programm. Auf dem Atmel verwende ich V-USB. Als Anfang
will ich erst einmal 6 Byte Daten senden mit den Zahlen 1 bis 6. Die
Setup Daten kommen auf dem µC in der usbFunctionSetup Funktion auch
korrekt an. Danach wird dann die usbFunctionWrite Funktion aufgerufen,
dessen übergebene Datenlänge ebenfalls 6 Byte beträgt.
Die 6 Byte Daten sind allerdings fehlerhaft. Ich bekomme da immer die
Zahlen 0,0,1,0,2,0 egal welche anderen Zahlen ich sende.
Den V-SUB Code habe ich von der Wiki Seite kopiert und nur die Request
Nummer angepasst.
VB.Net Code zum Senden der Daten:
1
Dim UsbCtrl As Byte = (UsbCtrlFlags.Direction_Out Or UsbCtrlFlags.RequestType_Class Or UsbCtrlFlags.Recipient_Endpoint)
2
Dim Packet As UsbSetupPacket
3
Dim buffer(100) As Short
4
Dim transferred As Integer = 0
5
6
For i As Integer = 1 To 7
7
buffer(i) = i
8
Next
9
10
11
Packet = New UsbSetupPacket(UsbCtrl, 1, 1, 0, 6)
12
13
If MyUsbDevice.ControlTransfer(Packet, buffer, 6, transferred) = True Then
usbRequest_t *rq = (void *)setupData; // cast to structured data for parsing
7
switch(rq->bRequest){
8
case 1:
9
currentPosition = 0; // initialize position index
10
bytesRemaining = rq->wLength.word; // store the amount of data requested
11
if(bytesRemaining > sizeof(buffer)) // limit to buffer size
12
bytesRemaining = sizeof(buffer);
13
return USB_NO_MSG; // tell driver to use usbFunctionWrite()
14
}
15
return 0; // ignore all unknown requests
16
}
17
18
uchar usbFunctionWrite(uchar *data, uchar len)
19
{
20
uchar i;
21
New_Data = len;
22
23
if(len > bytesRemaining) // if this is the last incomplete chunk
24
len = bytesRemaining; // limit to the amount we can store
25
bytesRemaining -= len;
26
for(i = 0; i < len; i++)
27
{
28
buffer[currentPosition++] = data[i];
29
UART_Putc(data[i]);
30
}
31
return bytesRemaining == 0; // return 1 if we have all data
32
}
Jetzt ist die Frage, wo der Fehler liegen könnte, dass ich immer falsche
Daten empfange. Ich hoffe einer von euch kann mir da weiter helfen.
Killerawft
1. Nutze einfach das Testprogramm von V-USB mit dem du die LED (HID-USB)
an und aus schaltest.
2. Stecke den AVR-USB-Anschluss nicht direkt an den USB-Port vom PC,
sondern übereinen Hub, am besten über einen alten USB-1.1 Hub.
1. Ich weiß nicht genau welches Projekt du meinst, unter den HID
Projekten gibt es keines, das eine LED ein und Ausschaltet.
Ich habe mir andere Projekte mit LED Matritzen angeschaut und in denen
wurde auch nur der Code Schnipsel von dem V-USB Wiki genutzt.
2. Ich habe keinen USB Hub, ich habe aber einfach mal den USB Port
gewechselt. Geholfen hat das nicht.
Stimmt es denn, dass das Datenarray von der usbFunctionWrite die
gesendeten Daten als Bytes übergibt? oder werden die Daten wie bei der
usbRequest_t in 2 byte längen übertragen also als Word und muss ich die
Daten dann auch als Word abschicken?
Killerawft schrieb:> 1. Ich weiß nicht genau welches Projekt du meinst, unter den HID> Projekten gibt es keines, das eine LED ein und Ausschaltet.
Es gibt HID Keyboards, die bekanntlich 3 LED haben.
Ausser Keyboards und Forcefeedback bei Joysticks gibt es m.W. kein HID
Device, das Ausgänge unterstützt.
Ich habe inzwischen festgestellt, dass die Daten tatsächlich als Word,
also 2 Byte pro Element, verschickt und empfangen werden. Es war also
kein Übertragungsproblem, sondern Unwissenheit :)
Killerawft schrieb:> Ich weiß nicht genau welbufferches Projekt du meinst
Im vusb-Archiv:
/examples/hid-custom-rq/commandline/set-led.c
Zum testen ob die Verbindung überhaupt steht ist das super.
Killerawft schrieb:> Ich habe inzwischen festgestellt, dass die Daten tatsächlich als Word,> also 2 Byte pro Element, verschickt und empfangen werden.
Bei mir war das eigentlich einfach ein byte-Buffer der übertragen wurde.
Besorge dir einen alten Hub, es geht vielleicht auch ein USB 2.0 Hub.
Die Timing sind für den AVR einfach etwas unpassend und deshalb wird er
nicht erkannt wenn er direkt an den USB-Port der Southbridge vom
PC/Laptop angeschlossen wird.
Inzwischen habe ich meinen konkreten Fehler entdeckt.
Die Daten wurden wie zuvor geschrieben als 2 byte lange variable
verschickt, also als short. In der Datei usbconfig.h vom V-USB treiber
gibt es ganz unten den Eintrag #define usbMsgPtr_t unsigned short. Damit
wird das Übertragungsformat bestimmt bzw. was der Treiber als Variablen
länge erwarten soll.
Ändert man den Eintrag zu #define usbMsgPtr_t unsigned char* werden die
Daten als einzelne Bytes empfangen und verarbeitet und nicht als short.
Mike J. schrieb:> Besorge dir einen alten Hub, es geht vielleicht auch ein USB 2.0 Hub.> Die Timing sind für den AVR einfach etwas unpassend und deshalb wird er> nicht erkannt wenn er direkt an den USB-Port der Southbridge vom> PC/Laptop angeschlossen wird.
Schon wieder dieser Unsinn. Hast du den Thread überhaupt gelesen?
Es gibt überhaupt kein Problem mit der Erkennung des USB-Geräts.
Matthias S. schrieb:> Killerawft schrieb:>> 1. Ich weiß nicht genau welches Projekt du meinst, unter den HID>> Projekten gibt es keines, das eine LED ein und Ausschaltet.>> Es gibt HID Keyboards, die bekanntlich 3 LED haben.> Ausser Keyboards und Forcefeedback bei Joysticks gibt es m.W. kein HID> Device, das Ausgänge unterstützt.
Falsch. HID Devices sind nicht nur Joystick, Keyboard oder Mäuse. Man
kann natürlich auch Daten (Rechner -> µC) an ein HID Device schicken -
jeglicher Art. Man setzt sich in der HID EP Descriptor einfach die
bEndpointAddress zu DataIn. Schau mal bei USB.org um. Du wirst erstaunt
sein, was alles über das HID Protocoll läuft.
Mike J. schrieb:> Besorge dir einen alten Hub, es geht vielleicht auch ein USB 2.0 Hub.> Die Timing sind für den AVR einfach etwas unpassend und deshalb wird er> nicht erkannt wenn er direkt an den USB-Port der Southbridge vom> PC/Laptop angeschlossen wird.
Ist übrigens totaler Schwachsinn. Womit V-USB besonders schlecht
zurecht kommt, sind alte USB 1.1 Hubs, die die Daten an alle Ports
weitersenden. Dann ist der Kontroller nämlich nur mit der Analyse von
Daten für andere Functions beschäftigt.
Das Timing ist am Computer das gleiche.
Also: Direkt an den Computer anschließen.
Draco schrieb:> Falsch. HID Devices sind nicht nur Joystick, Keyboard oder Mäuse. Man> kann natürlich auch Daten (Rechner -> µC) an ein HID Device schicken -> jeglicher Art.
Dann nenne mir ein einziges, für welches bereits HID Treiber auf den
Zielplatformen vorhanden sind - denn darum gehts hier.
Matthias S. schrieb:> Dann nenne mir ein einziges, für welches bereits HID Treiber auf den> Zielplatformen vorhanden sind - denn darum gehts hier.
Bluetooth Headsets... um mal eins in die Runde zu werfen.