Hallo!
Ich bin kompletter Neuling, und habe bisher Nichts mit der
Programmierung von Microcontrollern zu schaffen gehabt. Nun habe ich
einen "ps3ukey" hier liegen, der eigentlich mal angeschafft wurde, um
ein XUM1541 zu werden, was aber nicht ging, nachdem ich feststellte,
dass auf diesem Board die meisten Pins des ICs nicht verlötet waren.
Die XUM1541 habe ich dann mit einem anderen Board gebaut, der ps3ukey
liegt nun hier vor mir, und ich möchte daraus gerne ein Gerätchen bauen,
welches als Signal-Beeper für ein beliebiges Embedded-Gerät dienen soll.
Das heißt ich möchte einen Piezo-Piepser darauf stecken, und den Stick
dann als /dev/ttyUSB0 sehen, und später einfach z.B. mit einem String
wie "beep <F> <L>" (Frequenz, Länge), den ich an /dev/ttyUSB0 sende zum
fiepen bringen, um damit dann z.B. die erfolgreiche Abarbeitung von
Skripten auf einem Headless-Embedded Gerät zu bestätigen. Die
USB-Verbindung möchte ich z.B. mit V-USB lösen.
Ich bin ja schon ganz stolz, weil ich es tatsächlich geschafft habe, ein
kleines Testprogrämmchen (rote und blaue LEDs blinken abwechselnd) per
avr-gcc zu compilen und per dfu-programmer darauf zu flashen:
// blaue LED ist PB2!
// rote LED ist PD3!
#define F_CPU 1000000
#include <avr/io.h>
#include <util/delay.h>
int main (void) {
DDRB |= (1 << PB2);
DDRD |= (1 << PD3);
PORTB ^= ( 1 << PB2 );
while(1) {
/* mainloop */
PORTB ^= ( 1 << PB2 );
PORTD ^= ( 1 << PD3 );
_delay_ms(10000);
}
return 0;
}
Jetzt kommen wir aber zum eigentlichen Problem:
Das Timing der LEDs stimmte nicht. Auf dem Board befindet sich ein Quarz
mit der Aufschrift "K8.000", also 8MHz vermute ich?. Aber damit die Zeit
zwischen den Flashes der LEDs mit dem bei _delay_ms(n) angegebenen
Intervall übereinstimmt, musste ich
F_CPU auf 1000000 stellen.
Heiß das, dass der uC wirklich nur mit 1MHz läuft?
Oder kann das einfach eine Konfigurationssache sein?
Kann ich die echte Taktfrequenz über diese Clocksource-Dinge irgendwie
beeinflussen, ohne großen Umbauten an der Hardware?
Da ich wie oben angegeben ja gerne später über USB-Kommandos empfangen
möchte, bräuchte ich für die Verwendung von V-USB ja wie
hier(https://www.heise.de/select/make/2017/1/1488551128750727) bei heise
beschrieben eine der Freuqnzen von 2, 12,8, 15, 16, 16,5, 18 und 20 MHz.
Diabetos schrieb:> Heiß das, dass der uC wirklich nur mit 1MHz läuft?
Das könnte bedeuten, daß die sogenannten "Fuses" nicht so gesetzt sind,
daß der Quarz überhaupt angesteuert wird. Es könnte aber auch die
CKDIV8-Fuse gesetzt sein, die den Takt durch 8 teilt.
> Die USB-Verbindung möchte ich z.B. mit V-USB lösen.
Das ist beim at90usb162 grober Unfug, das Ding kann USB in Hardware. Du
solltest Dir statt V-USB besser LUFA ansehen.
Rufus Τ. F. schrieb:> Diabetos schrieb:>> Heiß das, dass der uC wirklich nur mit 1MHz läuft?>> Das könnte bedeuten, daß die sogenannten "Fuses" nicht so gesetzt sind,> daß der Quarz überhaupt angesteuert wird. Es könnte aber auch die> CKDIV8-Fuse gesetzt sein, die den Takt durch 8 teilt.>>> Die USB-Verbindung möchte ich z.B. mit V-USB lösen.>> Das ist beim at90usb162 grober Unfug, das Ding kann USB in Hardware. Du> solltest Dir statt V-USB besser LUFA ansehen.
Danke schon mal. Ich hatte mich nach erstem Sondieren eher mit V-USB
angefreundet, weil LUFA so überkomplex wirkte, und die Website etwas
eigenartig ist... schon den Download konnte ich dort nicht finden (habe
es inzwischen aber von Github).
Ich fürchte die Fuses kann ich mit dieser Verlötung des Chips gar nicht
setzen(z.B MISO fehlt, der wäre ja auf 17), oder? Ich habe mir an Hand
der Atmel-Dokumentation eine Grafik angefertig, wo zu sehen ist, welche
Pins überhaupt zur Verfügung stehen. Ich habe die Grafik mal angehängt.
Also müsste ich wohl sowieso auf LUFA setzen..?
LUFA ist sogar in der Arduino-Umgebung integriert, wenn man z.B. einen
Arduino Leonardo damit programmiert (der verwendet einen Atmega32u4, der
ebenso einen echten USB-Device-Controller enthält).
Und LUFA ist V-USB gegenüber eindeutig im Vorteil, wenn man eine andere
USB-Geräteklasse als HID umsetzen möchte; zwar gibt es eine
CDC-Implementierung mit V-USB, die aber funktioniert nur mit sehr
toleranten Betriebssystemen, da sie eine Verletzung der
USB-Spezifikation darstellt.
Daß Du allerdings bei Deinem Controller die Fuses nicht setzen kannst,
dürfte mehr als eklig sein.
Die Kontakte des QFN-Gehäuses sind auch mit feinen Nadeln nicht
erreichbar?
Zeig doch bitte mal ein (scharfes, anständig ausgeleuchtetes) Bild von
Deinem "ps3ukey".
Hallo!
Ich habe den Stick mal in der Totalen und im Detail fotografiert.
(Besser konnte ich die Makroaufnahme nach ca 30 Versuchen nicht
hinbekommen).
Die Lötflächen um das IC herum sind leider bei den meisten Pins nicht
mit dem IC verlötet. Von der MISO-Seite aus, also Pin 17-24, ist gar nur
ein Pin verlötet, nämlich der Reset (24, ganz rechts).
Die dünnste meiner Lötspitzen, mit der ich einigermaßen umgehen kann,
ist etwa so breit, wie der gesamte IC dick ist.
Die 2x3 Pinleiste links ist unbeschaltet; die habe ich selbst mit Epoxyd
angeklebt, weil ich mir daraus ursprünglich mit etwas Lackdraht einen
ISP-Header machen wollte...
PS: Habe noch ein Detailbild angehängt, es wurde vorher wohl beim
Transfer vom Smartphone durch die App komprimiert, jetzt ist es wohl
minimal besser. Ich kann aber leider dennoch nicht sagen, ob unter den
unverlöteten Füßen des ICs überhaupt Lötaugen auf dem Board sind.
Diabetos schrieb:> Oder kann das einfach eine Konfigurationssache sein?
Kapitel 6.8.1 Clock Prescale Register – CLKPR im Manual gelesen?
Dafür gibt es IIRC sogar ein Macro, was die 4 Takte beim Schreibzugriff
einhält.
Jim M. schrieb:> Diabetos schrieb:>> Oder kann das einfach eine Konfigurationssache sein?>> Kapitel 6.8.1 Clock Prescale Register – CLKPR im Manual gelesen?>> Dafür gibt es IIRC sogar ein Macro, was die 4 Takte beim Schreibzugriff> einhält.
Danke! Das hat funktioniert.
Habe das gefunden um die Clockbits zu resetten:
CLKPR = _BV(CLKPCE);
CLKPR = 0;
Und vor mein Progrämmchen gesetzt. Das Timing stimmt jetzt mit #define
F_CPU 8000000
Hätte nicht gedacht, dass man die Werte die von den Fuses presettet
werden auch von einem Userprogramm aus overriden kann. Das geht aber
sicher nicht mit Allem, was die Fuses so setzen, sonst bräuchte ich ja
kein ISP mehr?
Die nun anstehenden Fragen sind ja, ob LUFA überhaupt funktionieren
kann, ohne Zugriff auf die Fuses, oder ob Rufus evtl. noch einen Trick
auf Lager hat, wie ich das "MISO-Problem" mechanisch lösen könnte. Ich
habe ja im Github Download schon gesehen, dass LUFA seine eigenen
Bootloader mitbringt, aber weiß nicht wofür die eigentlich nötig sind.
Normalerweise bietet so eine Library ja ein paar Includes, über die ich
dann die gebotene Funktionalität bekommen, aber bei einem uC ist das
wohl anders. Bisher dachte ich der Bootloader sei nur dafür da, ein
Ansprechpartner zum Programmieren ohne ISP-Hardware zu sein...
LUFA ist zunächst nur eine Library, die Du zu Deinem Programm
dazulinkst. Der Bootloader ist dafür da, über die USB-Schnittstelle
Programme in das den Controller hineinzubekommen, den brauchst Du
offensichtlich nicht, denn Du bekommst ja Programme übertragen.
Ich habe keine Ahnung, ob man, um LUFA nutzen zu können, irgendwelche
speziellen Fuses o.ä. setzen muss.
Googelt man nach "LUFA at90usb162", findet man aber etliche Hinweise.
Also: Viel Erfolg!
OK, danke dir. Also ist es doch so, wie ich es bisher (von
Desktopentwicklung) kannte. Die Bootloader scheinen nur ein "Bonus" zu
sein, falls man auf seinem uC nocht keinen geeigneten drauf hat.
Dann versuche ich jetzt mal LUFA zu überschauen. Die für meinen Zweck
interessanteste mitgelieferte Demos (DualVirtualSerial) ist laut txt
leider nicht für den at90usb162 geeignet und liefert
Kompilierungsfehler, wenn ich diesen uC als Target setze.
Ich wollte hier noch kurz anfügen, dass das Miniprojekt (und mein
Erstling) soweit gelungen ist.
Ich habe in den mitgelieferten LUFA-Projekten nur den Source-Code von
"USBToSerial" ein wenig geändert, einen 12mm-Piezo-Beeper an den selben
Ausgang wie die blaue LED gelötetn, und es funktioniert. Unter Linux
sind keine Treiber nötig, man muss nur eine Ausgabe auf das Devcie
senden (z.B: echo > /dev/ttyACM0) und schon ertönt ein kleines Signal.
Ich wollte noch eigentlich noch die übergebenen Daten parsen, um daraus
Tonfolge, Laustärke und Dauern zu interpretieren, aber um mit
"&USBtoUSART_Buffer" etwas anzufangen reichen meinhe C-Kenntnisse nicht
aus. (Ich vermute es läuft darauf hinaus, die Länge das Buffers zu
ermitteln, und den gesamten String im Buffer in ein Array zu lesen, aber
das ist auch egal, es funktioniert ja auch so). Als Signalgeber für
Embedded-Geräte, ohne Treiberabhängigkeit.
Falls sich jemand dafür interessiert, der noch weniger, oder ähnlich
viel wie ich darüber weiß, habe ich den geänderten Code angehängt.