PDA

Archiv verlassen und diese Seite im Standarddesign anzeigen : AVR Hardware USB



MisterMou
19.08.2014, 00:13
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.

Beispiel:
http://www.atmel.com/images/AVR270_USB_mouse.zip

Die ganze Schedulergeschichte habe ich erstmal weggelassen. Erstmal 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.

Das sieht dann so aus:
http://abload.de/thumb/1kojyq.png (http://abload.de/image.php?img=1kojyq.png)

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:

int main(void)
{
usb_start();

while(1)
{
if(Is_usb_receive_setup())
{
Led_on(); //for debugging
Led_off();
}
}
}

void usb_start(void)
{
Usb_enable_regulator();
Usb_disable_interface();
Usb_enable_interface();
Usb_select_low_speed();
Usb_enable_vbus_pad();

Usb_disable_clock();
usb_start_PLL();
Usb_enable_clock();
Usb_attach();

usb_config_ep(0, USB_CONF1_EP0_0, USB_CONF1_EP0_1); //config control EP
}

void usb_start_PLL(void)
{
PLLFRQ &= ~(1<<PINMUX); //use CPU clock
PLLFRQ |= 0x04|(1<<PLLUSB); //96MHz / 2
PLLCSR |= (1<<PINDIV); //PLL clock prescaler = 2
PLLCSR |= (1<<PLLE); //PLL enable

while(!(PLLCSR & (1<<PLOCK))); //wait for PLL is locked
}

U8 usb_config_ep(U8 epNum,U8 config0, U8 config1)
{
Usb_select_endpoint(epNum);
Usb_enable_endpoint();
UECFG0X = config0;
UECFG1X = config1;
Usb_allocate_memory();
return (Is_endpoint_configured());
}

Defines:


#define USB_CONF1_EP0_0 0x00 //control EP
#define USB_CONF1_EP0_1 0x00 //one bank, 8Byte buffer

#define Usb_enable_interface() (USBCON |= (1<<USBE)) //enable USB interface
#define Usb_disable_interface() (USBCON &= ~(1<<USBE)) //disable USB interface
#define Usb_enable_regulator() (UHWCON |= (1<<UVREGE)) //enable internal USB pads regulator
#define Usb_enable_vbus_pad() (USBCON |= (1<<OTGPADE)) //enable VBUS pad
#define Usb_disable_clock() (USBCON |= (1<<FRZCLK)) //disable clock
#define Usb_enable_clock() (USBCON &= ~(1<<FRZCLK)) //enable clock
#define Usb_enable_vbus_pad() (USBCON |= (1<<OTGPADE)) //enable VBUS pad

#define Usb_select_low_speed() (UDCON |= (1<<LSM)) //select Low-Speed Mode
#define Usb_attach() (UDCON &= ~(1<<DETACH)) //attach pullup resistor for speed selection

#define Usb_select_endpoint(ep) (UENUM = (U8)ep) //selects the endpoint number to interface with the CPU
#define Usb_enable_endpoint() (UECONX|=(1<<EPEN)) //enables the current endpoint
#define Usb_allocate_memory() (UECFG1X |= (1<<ALLOC)) //allocates the current configuration in DPRAM memory
#define Is_endpoint_configured() ((UESTA0X & (1<<CFGOK))?1:0)//tests if current endpoint is configured

#define Is_usb_receive_setup() (UEINTX&(1<<RXSTPI)) //tests if SETUP received

schorsch_76
20.08.2014, 07:48
Wiso glaubst du ist der Scheduler im Beispiel? Ist der im Beispiel nur zur Verwirrung oder ist ist das Beispiel da um dir den Weg zu zeigen?

MisterMou
20.08.2014, 09:39
Wozu der Scheduler da ist, ist mir durchaus bewusst.
Für den aktuellen Stand des Programms tut er aber in keinster Weise Not.
Generell braucht man für eine lumpige Maus keinen Scheduler, aber man kann ;)

Mir geht es nicht darum, den Code von Atmel zum laufen zu bringen, sondern ihn komplett zu verstehen. Dementsprechend wurde der relevante Code durchgearbeitet und in meinen Stil übernommen.

Ich finde die Codes von Atmel immer sehr universell und dementsprechend umfangreich. Sie sind auch gerne mal: "Guck mal was alles mit unseren Controllern geht", vorallem aus Sicht eines Einsteigers.