Forum: Mikrocontroller und Digitale Elektronik AVR Hardware USB, Setup Paket wird nicht empfangen


von Robert (Gast)


Angehängte Dateien:

Lesenswert?

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
int main(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
void usb_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
void usb_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
U8 usb_config_ep(U8 epNum,U8 config0, U8 config1)
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
8
#define Usb_disable_clock()            (USBCON |= (1<<FRZCLK))        //disable clock
9
#define Usb_enable_clock()            (USBCON &= ~(1<<FRZCLK))    //enable clock
10
#define Usb_enable_vbus_pad()        (USBCON |= (1<<OTGPADE))    //enable VBUS pad
11
12
#define Usb_select_low_speed()        (UDCON |= (1<<LSM))            //select Low-Speed Mode
13
#define Usb_attach()                (UDCON &= ~(1<<DETACH))        //attach pullup resistor for speed selection
14
15
#define Usb_select_endpoint(ep)        (UENUM = (U8)ep)            //selects the endpoint number to interface with the CPU
16
#define Usb_enable_endpoint()        (UECONX|=(1<<EPEN))            //enables the current endpoint
17
#define Usb_allocate_memory()        (UECFG1X |=  (1<<ALLOC))    //allocates the current configuration in DPRAM memory
18
#define Is_endpoint_configured()    ((UESTA0X & (1<<CFGOK))?1:0)//tests if current endpoint is configured
19
20
#define Is_usb_receive_setup()        (UEINTX&(1<<RXSTPI))        //tests if SETUP received

von Stefan (Gast)


Lesenswert?

Hallo,

was soll den deiner Meinung nach der "mega16u4" tun??? und was 
funktioniert daran nicht ???

Gruss

von Robert (Gast)


Lesenswert?

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.

von Stefan (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?


von Robert (Gast)


Lesenswert?

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.htm
http://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.

von Stefan (Gast)


Lesenswert?

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

von Stefan (Gast)


Lesenswert?

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 !!!

von potter (Gast)


Lesenswert?

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?

Bitte melde dich an um einen Beitrag zu schreiben. Anmeldung ist kostenlos und dauert nur eine Minute.
Bestehender Account
Schon ein Account bei Google/GoogleMail? Keine Anmeldung erforderlich!
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.