Halli Hallo,
zur Zeit bastel ich daran, mit einem mega16U4 eine USB Maus zum Laufen
zu bekommen. Als Taktquelle dient ein 16MHz Quarz.
Ich bin einfach ratlos warum das Ding zickt. Nachdem ich mir schon ein
paar Nächte um die Ohren geschlagen habe, hoffe ich auf Eure Hilfe.
Zum Hintergrund, ich habe das Beispiel von Atmel durchgearbeitet und
meiner Meinung nach auch verstanden. So wie es aussieht, aber wohl doch
nicht.
Beispiel:
http://www.atmel.com/images/AVR270_USB_mouse.zip
Die ganze Schedulergeschichte habe ich erstmal weggelassen. Zunächst
soll der Spaß laufen.
Das Problem ist, dass das RXSTPI Flag nicht gesetzt wird.
Zum Überprüfen lass ich mir einen kurzen Peak ausgeben, der mit einem
Logicanalyzer überwacht wird. Parallel dazu wird die USB Übertragung
erfasst.
Im Moment wird gepollt. Also erstmal ganz dumpf mit dem Knüppel auf den
Kopf.
Natürlich kommt es momentan erstmal zu einem Fehler im Rechner, weil der
Controller noch nicht antwortet, das ist mir bewusst.
Zuletzt gibt es noch den Code, den ich auf das Wesentlichste reduziert
habe.
Die Reihenfolge der Initialisierung habe ich aus dem Beispiel
übernommen.
Es wäre echt der Knaller, wenn sich jemand meldet, der die eine geniale
Idee hat.
Code:
1
intmain(void)
2
{
3
usb_start();
4
5
while(1)
6
{
7
if(Is_usb_receive_setup())
8
{
9
Led_on();//for debugging
10
Led_off();
11
}
12
}
13
}
14
15
voidusb_start(void)
16
{
17
Usb_enable_regulator();
18
Usb_disable_interface();
19
Usb_enable_interface();
20
Usb_select_low_speed();
21
Usb_enable_vbus_pad();
22
23
Usb_disable_clock();
24
usb_start_PLL();
25
Usb_enable_clock();
26
Usb_attach();
27
28
usb_config_ep(0,USB_CONF1_EP0_0,USB_CONF1_EP0_1);//config control EP
29
}
30
31
voidusb_start_PLL(void)
32
{
33
PLLFRQ&=~(1<<PINMUX);//use CPU clock
34
PLLFRQ|=0x04|(1<<PLLUSB);//96MHz / 2
35
PLLCSR|=(1<<PINDIV);//PLL clock prescaler = 2
36
PLLCSR|=(1<<PLLE);//PLL enable
37
38
while(!(PLLCSR&(1<<PLOCK)));//wait for PLL is locked
39
}
40
41
U8usb_config_ep(U8epNum,U8config0,U8config1)
42
{
43
Usb_select_endpoint(epNum);
44
Usb_enable_endpoint();
45
UECFG0X=config0;
46
UECFG1X=config1;
47
Usb_allocate_memory();
48
return(Is_endpoint_configured());
49
}
Defines:
1
#define USB_CONF1_EP0_0 0x00 //control EP
2
#define USB_CONF1_EP0_1 0x00 //one bank, 8Byte buffer
3
4
#define Usb_enable_interface() (USBCON |= (1<<USBE)) //enable USB interface
5
#define Usb_disable_interface() (USBCON &= ~(1<<USBE)) //disable USB interface
6
#define Usb_enable_regulator() (UHWCON |= (1<<UVREGE)) //enable internal USB pads regulator
7
#define Usb_enable_vbus_pad() (USBCON |= (1<<OTGPADE)) //enable VBUS pad
Im Endeffekt geht es um eine normales HID Gerät, in dem Fall eine Maus.
Im Moment erwarte ich den Puls, das ein Setup Paket empfangen wurde.
Da wird noch nichts verarbeitet, das ist auch so gewollt.
Ich habe den Code extra angepasst, damit er mein Problem repräsentiert
und leicht zu verstehen ist. Das ist lange nicht der komplette Code.
Allein zum Verarbeiten der Setup Pakete gibt es noch 1000 Zeilen Code.
Die wollte ich jetzt aber hier nicht auftischen. Das trägt ja nicht zur
Lösung des Problems bei.
Ich hoffe, ich habe damit deine Frage beantwortet.
Hallo,
ich glaube du hast da noch ein paar Knoten in deiner Denke!
Da kommt kein "Setup-Paket", woher sollte der Host auch wissen wer da
dran ist?
Der Host (meist PC) pollt nur ständig und falls da ein neues Gerät
angeschlossen ist dann hat sich das gefälligst bei einer ganz
allgemeinen Aufforderung zu melden und zu sagen wer es ist und was es
kann.
Genau das ist der Beginn der sogenannten "Enumeration" die du nicht
einfach kappen oder weglassen kannst !!!
Mach dich erst im (Selbst-)Studium schlau wie das alles geht! Das Forum
hier kann das nicht ersetzen!
Gruss
Danke für deinen Link, dort steht aber leider das Gleiche.
"Once the USB host has established a USB device is connected, and at
what speed it should communicate,then the host will reset the USB device
and attempt to read the descriptors to identify the USB device
using a default address."
Das Lesen des Descriptors läuft über den GET_DESCRIPTOR Request, dies
ist ein Standardrequest.
Zuerst wird mit einem Setup Paket begonnen, welches an Adresse 0,
Endpoint 0 gesendet wird. Danach folgt ein Data Paket, welches die
Anfrage für den Device Descriptor enthält. Erst danach muss das Device
das erste mal reagieren. Indem es ein ACK sendet.
Genau das ist in dem Bild zu sehen, was ich am Anfang gepostet habe.
Es ist dort auch der zweite Versuch des Hosts zu sehen, das Device zu
enumerieren.
Ich habe mir das nicht aus den Fingern gesaugt.
Inzwischen arbeite ich über zwei Wochen daran und habe das zweite Buch
durchgekaut. Mehr vernünftige haben wir nicht in der FH. Dazu so
ziemlich alles, was ich im Netz gefunden habe.
Auch der LUFA Treiber wurde im Teil der Device Initialisierung
durchgearbeitet.
An der Stelle kann ich noch zwei gute Seiten für den Einstieg empfehlen.
http://www.usbmadesimple.co.uk/ums_5.htmhttp://www.beyondlogic.org/usbnutshell/usb6.shtml#StandardDeviceRequests
Als Buch hat sich "USB 1.1 Professional Series" vom Franzis Verlag
bewährt, aber nur zum Grundwissen. Der Teil der Requests ist recht kanpp
gehalten.
Ich möchte dir nicht zu nah treten Stefan, aber ich würde mich freuen,
wenn ich ernst genommen werde. Und nicht wie ein Kiddy behandelt werde,
das nicht weiß, wovon es redet. Inzwischen arbeite ich 4 Jahre mit
Mikrocontrollern und habe 3 Jahre studiert und bin auf den Weg zum
Master in Elektrotechnik. Da ich erst 23 bin, kann ich noch nicht viel
mehr Erfahrung haben.
Hallo
Robert schrieb:> ich würde mich freuen,> wenn ich ernst genommen werde. Und nicht wie ein Kiddy behandelt werde,> das nicht weiß, wovon es redet
dann lese Dir deine 1. Anfrage noch mal durch und überlege genau wie du
da dein Problem schilderst und wie du jemanden begegnen würdest der das
so macht?
Nicht umsonst bin ich der einzige der überhaupt darauf geantwortet hat.
Robert schrieb:> zur Zeit bastel ich daran, mit einem mega16U4 eine USB Maus zum Laufen> zu bekommen. Als Taktquelle dient ein 16MHz Quarz.> Ich bin einfach ratlos warum das Ding zickt. Nachdem ich mir schon ein> paar Nächte um die Ohren geschlagen habe, hoffe ich auf Eure Hilfe.
hier fehlt jetzt nur noch der Satz: "Kann mir jemand sagen was ich
falsch mache."
"was, wieso, wobei ????"
Du schilderst dein Problem nicht ausreichend! Es ist offensichtlich
niemandem klar wo du bei der schrittweisen Enumerierung eines HID-Device
hängen bleibst. Das ist alles.
Warum sagst du nicht dass du Probleme hast bei der Enumerierung eines
HID-Device und beschreibst die Schritte die gehen und letztlich den
Schritt wo du hängen bleibst.
Das Ganze in der Terminologie der einschlägigen Fachliteratur.
Gruss
Hallo nochmal,
hier ein Link auf ein HID-Mouse Beispiel für den ATmega32u4 (müsste auch
für 16u4 gehen) das in der Kürze nicht zu unterbieten ist. (gerade mal
etwa 350 Zeilen)
Vergleiche mal die Initialisierung dort mit deiner.
Da gibt es ein paar bedenkliche Unterschiede soweit ich das auf die
Schnelle sehen konnte.
https://www.pjrc.com/teensy/usb_mouse.html
das Beispiel "USB Mouse, Version 1.1." besteht nur aus 3 Files !!!
Robert schrieb:> Das Lesen des Descriptors läuft über den GET_DESCRIPTOR Request, dies> ist ein Standardrequest.> Zuerst wird mit einem Setup Paket begonnen, welches an Adresse 0,> Endpoint 0 gesendet wird. Danach folgt ein Data Paket, welches die> Anfrage für den Device Descriptor enthält. Erst danach muss das Device> das erste mal reagieren. Indem es ein ACK sendet.
Das stimmt eben nicht! Du musst schon den Device-Descriptor schicken
(und nicht nur ein ACK), auch wenn die Daten dann verworfen werden und
mit einer neuen Adresse erneut angefragt werden.
Robert schrieb:> Genau das ist in dem Bild zu sehen, was ich am Anfang gepostet habe.> Es ist dort auch der zweite Versuch des Hosts zu sehen, das Device zu> enumerieren.
An welche Adresse geht dieser Versuch? Immer noch Null? Falls ja, da
hast Du den Fehler.
Kannst Du mal Deinen Mitschnitt dekodieren. Das NRZI Zeug ist schlecht
lesbar. Oder sollen wir das selber machen?