Forum: Mikrocontroller und Digitale Elektronik ATxmega32A4U Internal 32.768kHz Oscillator und USB


von Simon K. (simon) Benutzerseite


Lesenswert?

Hallo Leute,
Ich habe gerade ein Projekt mit einem ATmega32A4U, der das interne USB 
benutzt (Mittels 32MHz internal oscillator und USBSOF-DFLL).
Der Systemtakt läuft im Moment mit einem Quarz+PLL auf 27.12MHz.

Versuche ich den 32.768kHz internal oscillator anzuschalten mittels
OSC.CTRL |= OSC_RC32KEN_bm;
und zwar egal an welcher Stelle im Code, erkennt der USB Host den 
Mikrocontroller nicht mehr. Windows sagt dann sowas wie "Gerät konnte 
nicht erkannt werden".

Auf den DM/DP Leitungen scheint noch was zu passieren, wenn ich dem 
Oszilloskop glauben schenken darf. Einen Hardware USB Analyzer habe ich 
leider nicht zur Hand.

Ich halte das für höchst merkwürdig! Hat jemand anders sowas schon mal 
erlebt oder kann das ausprobieren? Im Errata vom ATxmega32A4U steht 
davon jedenfalls nichts drin.

Gruß und Danke schon mal!

von Basti M. (counterfeiter)


Lesenswert?

Der DFLL hängt doch irgendwie an dem 32.768 Hz internem Clock?!

Ansonsten wirklich komisch... und was passiert, wenn der Clock schon vor 
USB aktiviert wird?

von holger (Gast)


Lesenswert?

>Versuche ich den 32.768kHz internal oscillator anzuschalten mittels
>OSC.CTRL |= OSC_RC32KEN_bm;
>und zwar egal an welcher Stelle im Code, erkennt der USB Host den
>Mikrocontroller nicht mehr. Windows sagt dann sowas wie "Gerät konnte
>nicht erkannt werden".

USB läuft halt nicht mit 32.768kHz.

von Simon K. (simon) Benutzerseite


Lesenswert?

Basti M. schrieb:
> Der DFLL hängt doch irgendwie an dem 32.768 Hz internem Clock?!
>
> Ansonsten wirklich komisch... und was passiert, wenn der Clock schon vor
> USB aktiviert wird?

Nein, die USB DFLL läuft mit dem USB SOF (Start of Frame) als 
Taktquelle.

holger schrieb:
>>Versuche ich den 32.768kHz internal oscillator anzuschalten mittels
>>OSC.CTRL |= OSC_RC32KEN_bm;
>>und zwar egal an welcher Stelle im Code, erkennt der USB Host den
>>Mikrocontroller nicht mehr. Windows sagt dann sowas wie "Gerät konnte
>>nicht erkannt werden".
>
> USB läuft halt nicht mit 32.768kHz.

Ich hab ja auch bloß den internen Oszillator aktiviert . Der Prozessor 
läuft natürlich weiterhin auf 27.12MHz.

von Simon K. (simon) Benutzerseite


Lesenswert?

Habe das Problem auch noch mal bei avrfreaks geschildert.
http://www.avrfreaks.net/index.php?name=PNphpBB2&file=viewtopic&p=1049473#1049473

von Simon K. (simon) Benutzerseite


Angehängte Dateien:

Lesenswert?

Gibts denn hier Leute, die etwas mehr über USB Internas wissen als ich?
Ich habe weiter rumexperimentiert und kann einfach nicht herausfinden, 
wo das Problem sein soll.

Ich habe mal USBTrace zum Loggen benutzt. Im Anhang zwei Screenshots, 
die ein Log von USBTrace von beiden Fällen zeigt.

Auf meinem RIGOL DSO lässt sich leider nichts wesentliches erkennen, 
sonst hätte ich davon auch noch einen Screenshot angehängt.

Um die beiden Logs zu capturen, habe ich in folgendem Initcode die 
markierte Stelle auskommentiert (funktioniert), bzw. einkommentiert 
(funktioniert nicht).
1
void SystemInit(void)
2
{
3
  /* Disable JTAG */
4
  CCP = CCP_IOREG_gc;
5
  MCU.MCUCR = MCU_JTAGD_bm;
6
  MCU.MCUCR = MCU_JTAGD_bm;
7
8
  /* TODO: Why does USB fail when enabling RC32K? */
9
  /* Enable all used clocks */
10
#if 1
11
  OSC.XOSCCTRL = OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_16KCLK_gc;
12
  OSC.CTRL |= OSC_XOSCEN_bm;
13
  while(!(OSC.STATUS & OSC_XOSCRDY_bm))
14
    ;
15
#endif
16
17
#if 0 // <- HERE
18
  /* Activate 2MHz and 32.768kHz oscillators */
19
  OSC.CTRL |= OSC_RC2MEN_bm | OSC_RC32KEN_bm;
20
  while(!(OSC.STATUS & OSC_RC2MRDY_bm))
21
    ;
22
  while(!(OSC.STATUS & OSC_RC32KRDY_bm))
23
    ;
24
25
  /* Tune 2MHz Oscillator to 27.12MHz/14 */
26
  OSC.DFLLCTRL |= OSC_RC2MCREF_RC32K_gc;
27
  DFLLRC2M.COMP2 = 0x07;
28
  DFLLRC2M.COMP1 = 0x64;
29
  DFLLRC2M.CTRL = DFLL_ENABLE_bm;
30
#endif // <- HERE
31
32
#if 0
33
  OSC.PLLCTRL = OSC_PLLSRC_RC2M_gc | (14 << OSC_PLLFAC_gp);
34
#else
35
  OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc | (2 << OSC_PLLFAC_gp);
36
#endif
37
  OSC.CTRL |= OSC_PLLEN_bm;
38
  while(!(OSC.STATUS & OSC_PLLRDY_bm))
39
    ;
40
41
  /* Set PLL as main clock */
42
  CCP = CCP_IOREG_gc;
43
  CLK.CTRL = CLK_SCLKSEL_PLL_gc;
44
45
  /* Use TCE0 as system tick */
46
  TCE0.PER = F_CPU / 256 / 10 - 1;
47
  TCE0.CTRLA = TC_CLKSEL_DIV256_gc;
48
49
#if 1
50
  /* Enable RTC with roughly 1kHz clock */
51
  CLK.RTCCTRL = CLK_RTCSRC_ULP_gc | CLK_RTCEN_bm;
52
  RTC.CTRL = RTC_PRESCALER_DIV1_gc;
53
#endif
54
55
}

Vielleicht kann da ja jemand weitere Vermutungen anstellen, was los ist?
:-)

von Simon K. (simon) Benutzerseite


Lesenswert?

Kleiner Nachtrag. Den Unterschied zwischen Funktion und Nichtfunktion 
macht sogar das Hinzufügen/Wegnehmen dieser einzigen Zeile Programmcode 
aus:
1
OSC.CTRL |= OSC_RC32KEN_bm;

Das gibts doch nicht!

von Basti M. (counterfeiter)


Lesenswert?

Mal nachgeschaut ob beim OSC_RC32KEN_bm auch das richtige Bit gesetzt 
wird?

von Simon K. (simon) Benutzerseite


Lesenswert?

Basti M. schrieb:
> Mal nachgeschaut ob beim OSC_RC32KEN_bm auch das richtige Bit gesetzt
> wird?

Aus Verzweiflung habe ich alle defines mal mit dem Datenblatt überprüft 
und das passt soweit. Das wäre zu schon gewesen.

Ein Abgleich mit dem Atmel Software Framework ergibt auch keine 
Abweichungen.. Die haben da aber auch in keinem Beispiel den 32.768kHz 
Oszillator und USB gleichzeitig laufen. Sonst hätte man auf jeden Fall 
einen Beweis gehabt, dass das funktionieren MUSS.

von Fabian O. (xfr)


Lesenswert?

Kann es sein, dass Du vergisst, den Schreibschutz für das 
OSC.CTRL-Register aufzuheben bzw. es danach zu viele Takte dauert? Schon 
das Vodern mit dem alten Wert könnte zu lang sein.

von Simon K. (simon) Benutzerseite


Lesenswert?

Du meinst die CCP? Das Register fällt nicht unter die durch die CCP 
geschützten Register. Auch mal testweise ein hinzufügen von CCP = 
CCP_IOREG_gc; direkt vor dem Zugriff bringt keinen Unterschied.

von Fabian O. (xfr)


Lesenswert?

Ja, meinte ich. Habs mit dem CLK.CTRL-Register verwechselt, Sorry.

von Fabian O. (xfr)


Lesenswert?

Falls es Dir moralisch hilft: Ich kann das Problem mit einem 
ATxmega128A4U reproduzieren. Wenn ich
1
OSC.CTRL |= OSC_RC32KEN_bm;
in das Programm einfüge, funktioniert die USB-Verbindung nicht mehr. 
Sehe im Datenblatt aber keine Erklärung, warum man das nicht machen 
dürfen sollte.

von Simon K. (simon) Benutzerseite


Lesenswert?

Fabian O. schrieb:
> Falls es Dir moralisch hilft: Ich kann das Problem mit einem
> ATxmega128A4U reproduzieren. Wenn ichOSC.CTRL |= OSC_RC32KEN_bm;in das Programm 
einfüge, funktioniert die USB-Verbindung nicht mehr.
> Sehe im Datenblatt aber keine Erklärung, warum man das nicht machen
> dürfen sollte.

Ja, das hilft mir :-) Vor allem jetzt vor dem Schlafengehen.

Riecht wohl ziemlich stark nach Silicon Bug, meiner Meinung nach.

von Master (Gast)


Lesenswert?

Oh man...

das hat mich auch ein paar Nächte schlaf gekostet... Sehr gut 
Erkenntnis, kein Plan wie du da vor 10 Jahren drauf gekommen bist, aber 
Danke! Ich habe das Problem nicht ohne eure Hilfe finden können!

Wenn das mal jemand liest der sich auskennt, das ist ein Bug der 
wirklich schwer zu finden ist und unglaublich relevant wenn man mit USB 
arbeitet. Vielleicht könnte der mal ins Wiki...

von Simon K. (simon) Benutzerseite


Lesenswert?

Lang ist es her! Interessant, dass der Bug auch immer noch nicht in 
einem Erratasheet zu finden ist :-)

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.