Elektrolurch schrieb:
> Evtl. könntest du - mit internem Takt - XOSC auf einen Zähler geben und
> so die ungefähre XOSC-Frequenz bestimmen. Wenn kein Quarz, dann keine
> oder völlig falsche Frequenz.
Herzlichen Dank für den Hinweis, vielleicht werde ich das so machen.
Ich habe es noch einmal probiert, leider wird das XOSCRDY-Bit immer
gesetzt.
Der externe Takt wird auch nur für die Timer etc. genutzt, der Kern
läuft weiter mit dem internen Takt.
Ich konnte die genutzten Timer trotz des fehlenden Quarzes mittels des
GCLK->GENCTRL[2] betreiben, die Frequenz scheint nur nicht zu stimmen.
folgendendes funktioniert jetzt, zumindest wenn kein Quarz bestückt ist.
1 | static void clock_init()
|
2 | {
|
3 | bool xosc_fail;
|
4 | OSCCTRL->XOSCCTRL.reg = OSCCTRL_XOSCCTRL_STARTUP(0xC) | OSCCTRL_XOSCCTRL_AMPGC | OSCCTRL_XOSCCTRL_GAIN(0x4) | OSCCTRL_XOSCCTRL_XTALEN | OSCCTRL_XOSCCTRL_ENABLE | OSCCTRL_XOSCCTRL_CFDEN;
|
5 | while (!(OSCCTRL->STATUS.reg & OSCCTRL_STATUS_XOSCRDY)){};
|
6 | if (OSCCTRL->STATUS.reg & OSCCTRL_STATUS_XOSCFAIL)
|
7 | {
|
8 | xosc_fail = true;
|
9 | }
|
10 | else
|
11 | {
|
12 | xosc_fail = false;
|
13 | }
|
14 |
|
15 | OSCCTRL->OSC48MDIV.reg = OSCCTRL_OSC48MDIV_DIV(0);
|
16 | MCLK->CPUDIV.reg = MCLK_CPUDIV_CPUDIV_DIV1;
|
17 |
|
18 | GCLK->GENCTRL[0].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC48M;
|
19 |
|
20 | if (xosc_fail == false)
|
21 | {
|
22 | GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(1) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_XOSC;
|
23 | }
|
24 | else
|
25 | {
|
26 | GCLK->GENCTRL[2].reg = GCLK_GENCTRL_DIV(2) | GCLK_GENCTRL_GENEN | GCLK_GENCTRL_SRC_OSC48M;
|
27 | }
|
28 | }
|
Ich hätte nur Bedenken, dass es vielleicht nicht immer richtig
funktioniert.