Forum: Mikrocontroller und Digitale Elektronik ARM SAMC20 externen Quarz erkennen


von Simon (Gast)


Lesenswert?

Hallo,
hat eventuell schon mal jemand bei dem SAMC20, oder natürlich auch gerne 
bei einem ähnlichen Derivat, wärend der Laufzeit versucht zu erkennen, 
ob ein externer Quarz vorhanden ist?

Ich stelle es mir wie folgt vor:
- Reset/Power on
- der interne Takt ist ausgewählt
- Konfiguration und Start des "External Multipurpose Crystal Oscillator"
- Warte darauf, dass der externe Takt fertig ist
- Wenn die "Clock Failure Detection" angesprochen hat, arbeite mit dem 
internen Takt, ansonsten mit dem externen

Könnte das so klappen?

Ich habe hauptsächlich probleme mit dem Warten; das XOSCRDY-Bit war 
trotz fehlendem Quarz gesetzt.

Über sachdienliche Hinweise würde ich mich sehr freuen.

Gruß
Simon

von Elektrolurch (Gast)


Lesenswert?

Simon schrieb:
> Ich habe hauptsächlich probleme mit dem Warten; das XOSCRDY-Bit war
> trotz fehlendem Quarz gesetzt.
???
Ich kenne nur den D21.
Aber dass das XOSCRDY-Bit gesetzt ist, ist sehr verwunderlich.
Funktioniert denn die Oszillator-Umschaltung auf XOSC?
Prüfe das mal nach.
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.

von Simon (Gast)


Lesenswert?

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.

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
Noch kein Account? Hier anmelden.