Hey, ich hab mal ne Frage zum Arduino M0 Pro, bzw. dem Atmel SAMD21. Ich habe den Arduino M0 Pro, bei welchem laut Specs der SAMD21 mit 48 MHz läuft. Allerdings benutze ich das Board mit Atmel Studio und ohne irgendwelche Arduino Libraries. Muss ich nun die Chipfrequenz in einem Register oder per Fuse einstellen, um den SAMD21 mit 48 MHz zu betreiben oder wie wird das geregelt? Mit freundlichen Grüßen
:
Bearbeitet durch User
Hey, nutzt du das ASF, oder möchtest du alles selbst programmieren?
Lukas V. schrieb: > Muss ich nun die Chipfrequenz in einem Register oder per Fuse einstellen Ja. Standardmäßig läuft er vom internen RC-Oszillator, wimre mit 2 MHz.
Möchte generell alles selber programmieren, aber für den Fall, wenns einfacher wäre, würd ich auch ASF nutzen. Das ist aber parallel möglich? Also dass man nur die ASF Module nutzt die man braucht und sonst alles selber macht?
Jörg W. schrieb: > Lukas V. schrieb: >> Muss ich nun die Chipfrequenz in einem Register oder per Fuse einstellen > > Ja. Standardmäßig läuft er vom internen RC-Oszillator, wimre mit 2 MHz. Okay, darf ich so dreist sein und fragen, wie ich das mache? Meine Google-Suchen waren bis jetzt sehr erfolglos.
Lukas V. schrieb: > Okay, darf ich so dreist sein und fragen, wie ich das mache? Du musst dir als erstes mal Gedanken um die komplette Taktversorgung deines Chips machen. Hier mal ein Ausschnitt aus einer Software, die den SAML21 benutzt:
1 | * frequency generator |
2 | * XOSC32K --> GCLK[1] ------o------------------------> 32768 Hz 1 |
3 | * | DIV[1]=1 | |
4 | * | o--- Periph. Chann. 2 --\ |
5 | * V | | |
6 | * /--------------------------------------------------/ |
7 | * | | FDPLL_Timing | |
8 | * | | | |
9 | * | | FDPLL_REF | |
10 | * | | \--- Periph. Chann. 0 --\ |
11 | * | | | |
12 | * | | /--------------------------------------------/ |
13 | * | | | DFLL_REF signal |
14 | * | | | /----------------> GKLK_MAIN |
15 | * | | | | |
16 | * | | \-----> DFLL48 --> GCLK[0] --o----------------> 48 MHz 0 |
17 | * | | | |
18 | * | | /--------/ |
19 | * | | | |
20 | * | | o--- Periph. Chann. ... Fast peripheral channels |
21 | * | | | |
22 | * | | ... |
23 | * | | |
24 | * | \-------> |
25 | * \----------> FDPLL96 --> GCLK[2] -o----------------> 16 MHz 2 |
26 | * | |
27 | * /--------/ |
28 | * | |
29 | * o--- Periph. Chann. ... Slow peripheral channels (timers) |
30 | * | |
31 | * ... |
32 | * |
33 | * DFLL_REF: CLKCTRL.GEN=1, CLKCTRL.ID=0, use GCLK[1] output as DFLL ref. freq. |
Nur, dass du erstmal eine Idee bekommst, worum man sich so Gedanken machen darf. ;-)
:
Bearbeitet durch Moderator
Starte im Atmel Studio einfach ein neues Projekt, und waehle deinen richtigen Chip aus. Dann sollte es in main() schon eine Funktion init_irgendwas() geben. Da drin passiert alles noetige. Da musst du eigentlich nichts mehr einstellen. Da findest du dann auch irgendwo die Settings fuer die PLL. Vielleicht fined ich dazu ja noch was, ich such mal. Das ASF kannst du benutzen, dann bist du aber auf C "festgenagelt". Beim erstellen eines ASF-Projektes kommt eine Warnung, dass das mit C++ moeglicherweise nicht mehr wie angedacht funktioniert. Ausserdem hast du beim ASF das Problem, das da teilweise globale Variablen drin sind, die aber nicht static sind. Preisfrage: Mal angenommen im ASF gibt es eine globale, nicht statische Struktur mit dem Namen "USB_Descriptor". Wie gross ist die Wahrscheinlichkeit, das ein Entwickler eine USB anwendung hat, und eine Struktur fuer den USB-Descriptor ebefalls "USB_Descriptor" nennt? Ja, ueber genau sowas sind wir bei meinem alten Arbeitgeber gestolpert. Und in C faellt das nicht unbedingt sofort auf, ausser das dein Programm nicht das macht, was du gerne haettest. Dazu hatte ich hier auch mal einen Thread aufgemacht, um das Verhalten zu verstehen: Beitrag "GCC: Welches (globale) Symbol nimmt der Compiler bei gleichem Namen und Typ?"
Die Funktion, die von Atmel zur verfuegung gestellt wird muesste system_init() heissen, und sollte bei einem neuen Projekt automatisch in der main() stehen.
@Jörg Ja, dass da noch einiges mit dranhängt, war mir bewusst. Ich hatte natürlich gehofft, dass es eine recht simple "Standardlösung" gibt. Aber dann heißt es wohl, tiefer in die Materie einzudringen :) @Kaj Hmm, im Atmel Studio ist in der main automatisch ein Funktionsaufruf "SystemInit();" Dort steht aber nichts von PLL, sondern es wird nur eine Variable uint32_t SystemCoreClock = __SYSTEM_CLOCK gesetzt, wobei __SYSTEM_CLOCK auf 1000000 defined ist.
Lukas V. schrieb: > @Kaj Hmm, im Atmel Studio ist in der main automatisch ein > Funktionsaufruf "SystemInit();" > Dort steht aber nichts von PLL, sondern es wird nur eine Variable > uint32_t SystemCoreClock = __SYSTEM_CLOCK gesetzt, wobei __SYSTEM_CLOCK > auf 1000000 defined ist. Ich kann dir leider nicht sagen, wie das aktuell in Atmel Studio aussieht :( Mein Wissen ist da auch schon wieder gut 1,5 Jahre alt. Bei mir sah das noch so aus:
1 | int main(void) |
2 | {
|
3 | system_init(); |
4 | ...
|
5 | }
|
6 | |
7 | /*==============================================*/
|
8 | |
9 | /**
|
10 | * \brief Initialize system
|
11 | *
|
12 | * This function will call the various initialization functions within the
|
13 | * system namespace. If a given optional system module is not available, the
|
14 | * associated call will effectively be a NOP (No Operation).
|
15 | *
|
16 | * Currently the following initialization functions are supported:
|
17 | * - System clock initialization (via the SYSTEM CLOCK sub-module)
|
18 | * - Board hardware initialization (via the Board module)
|
19 | * - Event system driver initialization (via the EVSYS module)
|
20 | * - External Interrupt driver initialization (via the EXTINT module)
|
21 | */
|
22 | |
23 | void system_init(void) |
24 | {
|
25 | /* Configure GCLK and clock sources according to conf_clocks.h */
|
26 | system_clock_init(); |
27 | ...
|
28 | }
|
29 | |
30 | |
31 | /*==============================================*/
|
32 | |
33 | /**
|
34 | * \brief Initialize clock system based on the configuration in conf_clocks.h.
|
35 | *
|
36 | * This function will apply the settings in conf_clocks.h when run from the user
|
37 | * application. All clock sources and GCLK generators are running when this function
|
38 | * returns.
|
39 | *
|
40 | * \note OSC8M is always enabled and if user selects other clocks for GCLK generators,
|
41 | * the OSC8M default enable can be disabled after system_clock_init. Make sure the
|
42 | * clock switch successfully before disabling OSC8M.
|
43 | */
|
44 | void system_clock_init(void) |
45 | {
|
46 | ...
|
47 | }
|
Und irgendwo da, in den Untiefen des ASF, passierte dann die ganze magic. Da gab es bei uns auch noch ein paar Probleme: Hat man bei der Config irgendwas versaut, ist man in einer endlosen Rekursion beim Clock-Init gelandet => Stack Overflow. Ja, das ASF ist schon toll... kann einem viel Arbeit abnehmen, kann einem aber auch den letzten Nerv rauben. :D
Konnte das ganze jetzt ganz leicht mit Atmel Start lösen. https://imgur.com/1t5c2V3 https://imgur.com/3twSQFi https://imgur.com/4vO7ngb https://imgur.com/5prHKMU Vielen Dank für die Antworten!
Wäre schön, die Bilder hier zu posten statt Links auf einen Imagehoster zu setzen. Wenn in einem oder zwei Jahren jemand diesen Thread findet, ob dann die Links noch passen? Die Bilder hier werden dann jedenfalls noch da sein. Freut mich, dass du dein Problem gelöst hast. Einen opensourcefähigen Startup-Code, der die DFLL bedient, hätte ich im Moment nicht parat gehabt.
Das stimmt natürlich, hier nochmal die Bilder.
Vorsicht mit dem NVM und dem Bootloader. Der muss vorher richtig konfiguriert werden. Sonst lässt sich der Clock nicht umstellen. Das Problem wurde hier schon Diskutiert.
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.