Hallo; Ich habe folgendes Problem... Ich will Daten via Bulk transfer vom PC zum µC schicken, dann auf ein E² schreiben und lesen mit SPI, und die Daten zurück an den PC mit USB Bulk transfer... Bei Windows XP klappt es perfekt, aber nicht unter Linux Suse10.1 mit libusb 0.1.12. Es scheint ein Problem mit dem dataToggle bit unter linux zu sein??? Das erste mal nach der enumeration klappt es, danach nie wieder... Was kann ich machen ? bitte schaut euch meine sourcen an ...speziell usb_device_task.c Bitte helft mir, ich versteh es nicht, warum es unter Linux nicht klappt Vielen Dank an alle die helfen wollen...
Du mußt wahrscheinlich das Data-Toggle-Bit zurücksetzen. Wenn Du das Linux-Programm neu startest, beginnt der Datentransfer jeweils mit Data0-Paketen. wenn Du zuvor eine ungerade Anzahl von Paketen übertragen hast, sendet die Firmware aber nun ein Data1-Paket -- und das verträgt sich nicht.
Aber ich weiß nicht wo och das DataToggle Bit zurücksetzen muss, bzw. wann im Code... Immer darf ich es nicht zurücksetzen, da ja auch Data1 Pakete kommen können...also wo und wie mach in ein Reset am besten... Vielen vielen Dank
>Immer darf ich es nicht zurücksetzen, da ja auch Data1 Pakete kommen >können...also wo und wie mach in ein Reset am besten... Ja, das ist eine gute Frage! Ich gehe mal davon aus, dass Du nicht meinen Code, sondern den von Atmel für Deine Experimente verwendest. Dann musst Du da mal etwas suchen, grep -r oggle * im Quelltextverzeichis beipielsweise. Ich mache den Reset der Toggle-Bits in der Funktion UsbDevSetInterface() die Teil der Enumeration ist und beim Start des Linux-Programms aufgerufen wird. Ich werde mal versuchen die Funktion hier als Anhang anzuhängen, aber das nützt Dir nicht viel, denn beim Atmel-Code kann das alles anders sein. Das Makro zum Rücksetzen der Toggle-Bits ist #define UsbDevResetDataToggleBit() SetBit(UECONX, RSTDT) // next packet is data0 das sollte im Atmel-Code ähnlich sein, zumindest Register UECONX und Bit RSTDT. Du kannst dieses Problem aber auch vorläufig umgehen, wenn Du immer eine gerade Anzahl von Datenpaketen überträgst -- dann sollte das Toggle-Bit stimmen.
Also das resetten der dataToggle bits bekomme ich hin, habe die Funktion gefunden...nun ist nur die Frage wann ich resette... Rufen Sie vor jedem usb_bulk_read(...) und vor jedem usb_bulk_write(...) dieses set_interface auf ? Auf der PC seite sieht mein Programm so aus: der Hauptteil...: iError = usb_claim_interface(dev_hnd,0); printf(" iError bei claim = %d\n",iError); iError = usb_bulk_write(dev_hnd,0x03/*int ep*/,(char*)Prot/*char* bytes*/, 5/*int size*/,1000 /*int timeout*/); iError = usb_bulk_read(dev_hnd,0x82/*int ep*/,(char*)RecProt/*char* bytes*/, 4096/*int size*/,1000 /*int timeout*/); usb_release_interface(dev_hnd,0) /**********************************************************************/ bitte Sie sind meine letzte Hoffnung...vielen Dank für Ihre Hilfe
In meinem Testprogramm sieht das so aus: dev = UsbFindDevice(); if (dev == NULL) { puts("USB device not found!"); exit(EXIT_FAILURE); } handle = usb_open(dev); if (handle == NULL) { puts("USB device handle not found!"); exit(EXIT_FAILURE); } if (usb_claim_interface(handle, 0) < 0) { puts("Can not claim interface!"); usb_close(handle); exit(EXIT_FAILURE); } Dann kommt eine Anzahl Bulk-Transfers, und am Programmende usb_release_interface(handle, 0); usb_close(handle); exit(EXIT_SUCCESS); Hast Du probiert, jeweils eine gerade Anzahl von Transfers zu machen, also statt einem Bulk-Read gleich zwei, ebenso für Bulk-Write. Wenn dann alles ok ist, wissen wir, dass es sicher am Toggle-Bit liegt. Wo jetzt im Atmel-Code die Toggle-Bits (jeder Enpoint hat ein eigenes!) zurückgesetzt werden, weiss ich nicht. Ich bin mir auch nicht sicher, welche Funktion der LibUSB meine Funktion UsbDevSetInterface() meiner Firmware aufruft -- aber wenn ich LibUSB nach deren (spärlicher) Dokumentation verwende, wird bei mir die Funktion UsbDevSetInterface() meiner Firmware aufgerufen, und damit werden die Toggle-Bits bei jeden Neustart meines Linux-Programms zurückgesetzt und es funktioniert.
Ok, ich hatte noch den Atmel-Code des mouse-examples auf der Festplatte: grep -r oggle * liefert at90usb128/modules/usb/usb_standard_request.c: Usb_reset_data_toggle(); Und in usb_standard_request.c findet man, dass Usb_reset_data_toggle(); in Funktion void usb_clear_feature(void) aufgerufen wird. Wie ich das sehe, wird der StandardDeviceRequest ClearFeature von LibUSB nicht aufgerufen! Sieh mal in der Dokumentation von LibUSB nach, ob es eine Funktion ResetEndpoint oder ähnliches gibt. Die Funktion müsstest Du dann an geeigneter Stelle in dein Linux-Programm einbauen -- vor den Bulk-Read. Alternativ: In der Atmel-Datei usb_standard_request.c sehe ich eine Funktion void usb_set_configuration( void ) und darin enthalten ist usb_user_endpoint_init(usb_configuration_nb); Da könntest Du die Toggle Bits zurücksetzen. Gruß Stefan Salewski
Erst einmal vielen vielen Dank für Ihre Hilfe... In der libUSB Dokumentation habe ich folgendes gefunden: /*********************************************************************** ***/ usb_resetep Name usb_resetep -- Resets state for an endpoint Description int usb_resetep(usb_dev_handle *dev, unsigned int ep); usb_resetep resets all state (like toggles) for the specified endpoint. The ep parameter is the value specified in the descriptor field bEndpointAddress. Returns 0 on success or < 0 on error. Deprecated: usb_resetep is deprecated. You probably want to use usb_clear_halt. /*********************************************************************** ****/ Wenn ich Sie richtig verstanden habe, müsste diese Funktion beim starten meines Programmes aufgerufen werden...richtig ??? also prinzipiell so: ?? /*ProgrammStart*/ openDevice claim_interface resetEndpoint(EP2) resetEndpoint(EP3) usb_bulk_write() usb_bulk_read() release_interface /*ProgrammEnde*/ Nochmals vielen vielen Dank
Ja, würde ich so in der Art probieren. Oder eben usb_clear_halt(). Ich erwarte, dass usb_clear_halt() von LibUSB void usb_clear_feature(void) der Atmel-Firmware aufruft -- genau was Du brauchst. Probier also am besten zuerst usb_clear_halt(). Gruß Stefan Salewski
SUPER!!! Vielen vielen Dank der Clear Feature Befehl wird duch die libusb Funktion usb_clear_halt() ausgeführt und führ ein Reset der ToggleBits durch... Vielen Dank für Ihre Hilfe... Nun bin ich am Interrupt dran...wenn ich einen Interrupt einem Endpoint zuweisen will, muss ich dann diesen zuerst selektieren ? Beispiel: usb_select_endpoint(ENDPOINTNUMMER); usb_receive_out_interrupt_enable(); so dass ich einen Interrupt bekomme sobald ich auf der jeweiligen Nummer ein OUT empfange, oder gilt das interrupt enable allgemein für alle endpoints ? Vielen Dank Mit freundlcihen Grüßen Manuel Sahm
>Nun bin ich am Interrupt dran...wenn ich einen Interrupt einem Endpoint >zuweisen will, muss ich dann diesen zuerst selektieren ? >Beispiel: >usb_select_endpoint(ENDPOINTNUMMER); >usb_receive_out_interrupt_enable(); >so dass ich einen Interrupt bekomme sobald ich auf der jeweiligen Nummer >ein OUT empfange, oder gilt das interrupt enable allgemein für alle >endpoints ? Nach Figure 22-5, Seite 280 im Datenblatt sind die verschiedenen Interruptquellen jeweils auf einen speziellen Endpoint bezogen. Deine Vermutung ist daher richtig, Du musst den Endpoint zunächst selektieren um danach die Interruptquelle für diesen Endpoint freizugeben. Du musst, wenn ein Interrupt eingetreten ist, in der Regel auch überprüfen, auf welchen Endpoint er sich bezieht. Das geschieht über das Register UEINT, ein gesetztes Bit bedeutet, dass der zugehörige Endpoint den Interrupt ausgelöst hat. Eventuell ist diese Auswertung aber bereits im Atmel-Code enthalten, so dass man eventuell nur noch festlegen muss, welche Funktion für einen bestimmten Endpoint aufgerufen werden soll. Gruß Stefan Salewski
Ah OK, alles klar, habe ich auch so verstanden... Ich habe bis jetzt das USBKEY128 DevBoard, da ist ja leider nur ein 8 MHz Quartz drauf; ich würde aber gerne mal einen 16MHz Quartz benutzen, dafür müsste ich mir aber dann wahrscheinlich das STK500 + STK525 zulegen oder ? Und weiterhin wollte ich die TimerInterrupts mal testen...wie könnte ich denn jede Sekunde die LED namchen bzw. wieder ausmachen... Braucht man da nicht ne Formel, falls man das über COMPARE Mode machen will ? Vielen Dank Mfg M. Sahm
>Und weiterhin wollte ich die TimerInterrupts mal testen...wie könnte ich >denn jede Sekunde die LED namchen bzw. wieder ausmachen... >Braucht man da nicht ne Formel, falls man das über COMPARE Mode machen >will ? Die Timer sind bei allen AVRs ähnlich -- falls Du die Beschreibung im Datenblatt nicht sofort verstehst, musst Du mal nach Beispielen oder Tutorials im Internet suchen. >Ich habe bis jetzt das USBKEY128 DevBoard, da ist ja leider nur ein 8 >MHz Quartz drauf; ich würde aber gerne mal einen 16MHz Quartz benutzen, >dafür müsste ich mir aber dann wahrscheinlich das STK500 + STK525 >zulegen oder ? Du hast den USB-KEY -- dieses winzige Ding? Das liegt bei mir seit letztem Sommer unbenutzt in der Schublade, weil ich nicht so recht weiss was man damit sinnvolles machen soll. Debugging ist damit kaum möglich, da man kein UART hat. Quarz könnte man ja eventuell wechseln, aber 16 MHz sind nicht mehr ganz so problemlos wie 8 MHz. STK525: Wenn man nur Software entwickeln will und einem der Preis nicht abschreckt wohl ganz ok. Wenn man aber später eh eigene Platinen aufbauen will, kann man sich auch gleich eine Platine selber machen, wie etwa meine von http://www.ssalewski.de/AVR_USB_gEDA.html.de Natürlich sollte man elekrische Grundkenntnisse haben und etwas löten können. Die Bauteile kosten ca. 25 Euro, und die Platine pro Stück rund 15 Euro, wenn man sich mindestens 4 machen lässt (Bilex). Gruß Stefan Salewski
Ich benutze zum Debuggen den JTAGICE mkII; habe mir das SPI (PORTB) und zwei Pins von PORTA geholt un ein E² anzuschließen. Hatte eigentlich bisher keine schlechten Erfahrungen mit dem USB-KEY... Jetzt will ich halt versuchen Geschwindigkeit rauszukriegen, indem ich die frequenz verdopple...haben Sie vergleiche von 8 MHz zu 16 MHz...? Erreicht man bei manchen Funktionen den Faktor 2 in der Geschwindigkeit (z. B. kopieren von Daten in den USB Fifo)? Mein Projekt ist ein LOW COST RFID reader: PC -----via USB BULK Transfer --> µC ----via SPI----> ReaderIC ----via SPI---> µC -------via USB BULK Transfer -> PC Dieser Bulk transfer ist schon verdammt schnell,...aber beim kopieren der Daten kann man noch was rausholen denke ich... Viele Grüße M. Sahm
Fast alle Operationen des Controllers skalieren selbstverständlich mit der Taktfrequenz -- bei 16MHz hat man entsprechend die doppelte Geschwindigkeit wie bei 8 MHz. Die Datenübertragung zwischen Host und Device ist aber nicht von der Taktfrequenz des uC abhängig, da der USB-Teil eine feste Taktfrequenz hat (intern bis zu 48 MHz). Mit Fullspeed sollte eine Übertragung vom bis zu ca. 1MByte/s möglich sein -- aber soweit ich weiss ist der Atmel-USB-Code doch für die HID Klasse ausgelegt und dann hat man nur Low-Speed. Mit Fullspeed sollte man ohne Probleme bis zu 1MByte/s übertragen können, wenn man den FIFO kontinuierlich auslesen bzw. beschreiben kann, etwa wenn man die Daten aus einem großen Puffer liest oder hineinschreibt. Wenn die Daten aber in sehr kleinen Portionen eintrudeln, etwas immer ein oder zwei Byte vom ADC, ist die Situation ungünstiger. In meiner Beispielanwendung, wo ich per Timerinterrupt Daten vom internen ADC auslese (jeweils 2 Byte), erreiche ich mit C bei 16MHz und Fullspeed bis zu 100kByte/s. Aber das ist nur eine Beispielanwendung -- Timergesteuert einzelne Bytes in den FIFO zu schreiben macht viel Overhead, insbesondere da ich die Daten noch durch einen separaten Ringpuffer schiebe, um USB-Latenzzeiten zu überbrücken und Datenaufzeichnung in Echtzeit zu garantieren (alle 20us). Gruß Stefan Salewski
Super; danke für die Info; habe heute alles hibekommen mit Timer usw... Jetzt habe ich eventuell ein Hardwareproblem. Was ich will: Den AT90USB1287 mit 16 MHz betreiben, dies ist von der Spannung her kein Problem, da die USB Schnittstelle ja 5V bereitstellt. An den µC will ich ein RFID reader IC anschließen, diese läuft aber mit 3,3V. Von 5V auf 3,3V ist ja kein Problem, aber: Ich schließe dieses ReaderIc via SPI an, und da, wenn ich richtig liege sind bei 16 MHz die IO Pins mit einem Pegel von 5V am laufen, müsste es doch Probleme geben. Ich kann doch nicht 5V Pegel von der SPI auf eine 3,3V System jagen, oder doch ? Weiterhin habe ich nichts gefunden uber die Detektierung der HIGH und LOW Pegel vom AT90USB. Von dem IC komman ja dann auch nur 3,3V Pegel via SPI zurück...kann der AT90USB diese im 16MHz Betrieb (also 5V) überhaupt als High und Low identifiezieren ? Ich hoffe es war einigermaßen verständlich... Danke im vorraus Mit freundlichen Grüßen Manuel Sahm
Der AT90USB wird die Pegel schon als Low oder High erkennen, nur musst du schauen, ob der RFID-IC mit den 5V-Pegeln klarkommt. Entweder hat der IC 5V-tolerante Eingänge oder du musst die Pegel anpassen. Was für einen RFID-Reader willst du denn einsetzen? Gruß, Peter
Ich will das MFRC522 von NXP (Philips) ansteuern...zum Testen, später soll da glaube ich das MFRC530 dran... Tja und das läuft nunmal nur mit 3,3V und die maximalen Spannungen sind laut Datenblatt 4V (so wie ich das erkennen kann). Also müsste man sämtliche Signale die vom AT90USB1287 kommen von 5V auf 3,3V runterschrauben...????, oder ??? Sind Sie sicher, dass der Atmel die Pegel sicher detektieren kann (bei 5V) ? ich habe dazu im Datenblatt auch nichts gefunden... viele grüße Manuel
>Also müsste man sämtliche Signale die vom AT90USB1287 kommen von 5V auf >3,3V runterschrauben...????, oder ??? >Sind Sie sicher, dass der Atmel die Pegel sicher detektieren kann (bei >5V) ? ich habe dazu im Datenblatt auch nichts gefunden... Datenblatt AT90USB Seite 400: Input High Voltage Min: 0.6 VCC Gute 3 V sollte er noch als High erkennen. >Von 5V auf 3,3V ist ja kein Problem, aber: Naja, zumindest auch etwas Aufwand. Aber frag Dich mal, warum Atmel den USB-KEY mit 8MHz ausliefert. 16 MHz braucht zumindest stabile 4,5 V -- ob das am USB immer garantiert ist? Ich will dir keine Angst machen, bei mir geht es auch, aber wenn man unter allen Umständen die Funktion garantieren will? Ich würde mal drüber nachdenken ob nicht doch 8 MHz ausreichen -- dann kann eventuell der AT90USB auch mit gut 3V laufen. Gruß Stefan Salewski
Hallo; habe jetzt ein anderes Problem... ich muss Variablen bzw. ganze Tabellen im Flash ablegen... In der mir vorliegenden Firmware macht man das mit __tiny Jetzt bringt mir der Compiler immer fehlermeldungen von wegen TINY_Z zu klein oder so...? Data:100-100 Irgendwie muss das mit dem XLC - File zu tun haben...? Könnte mir das mal jemand erklären...? Vielen Dank Viele Grüße Manuel Sahm
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
Mit Google-Account einloggen
Noch kein Account? Hier anmelden.