Forum: Mikrocontroller und Digitale Elektronik Studio 6 und Dragon


von berniebaer (Gast)


Lesenswert?

Hallo zusammen,

ich versuche gerade die Core-Lib's vom XMEGA Arduino unter Atmel Studio 
6 zu compilieren. Soweit so gut, Blink läuft.
Nun habe ich den Code für die interne 32Mhz Clock
durch folgenden
1
// config external crystal, frequency between 12 and 16 Mhz
2
    OSC.XOSCCTRL |= ( OSC_FRQRANGE_12TO16_gc | OSC_XOSCSEL_XTAL_256CLK_gc ) ;
3
    // Enable external Crystal
4
    OSC.CTRL |= OSC_XOSCEN_bm;
5
    // Wait for it to stabilize
6
    while ( !(OSC.STATUS & OSC_XOSCRDY_bm) ) ;
7
    // Set external Clock activ
8
    CCP = CCP_IOREG_gc; // Secret handshake so we can change clock
9
    //CLK.CTRL = (CLK.CTRL & ~CLK_SCLKSEL_gm ) | CLK_SCLKSEL_XOSC_gc;
10
    // Config PLL external osc. 16MHz and set PLL factor 8 to get 128MHz
11
    OSC.PLLCTRL |= ( OSC_PLLSRC_XOSC_gc |  OSC_PLLFAC3_bm );
12
    // enable PLL
13
    OSC.CTRL |= OSC_PLLEN_bm;
14
    // Set prescaler, div 1-2-2 -> 32MHz
15
    CCP = CCP_IOREG_gc; // Secret handshake so we can change clock
16
    CLK.PSCTRL = CLK.PSCTRL & (CLK_PSADIV_1_gc| CLK_PSBCDIV_2_2_gc);
17
    // Wait for it to stabilize
18
    while ( !(OSC.STATUS & OSC_PLLEN_bm) ) ;
19
    // Set main system clock to 32Mhz external clock
20
    CCP = CCP_IOREG_gc; // Secret handshake so we can change clock
21
->  CLK.CTRL = (CLK.CTRL & ~CLK_SCLKSEL_gm ) | CLK_SCLKSEL_PLL_gc;
22
    // Disable unused osc
23
    // OSC.CTRL&= ~(OSC_RC2MEN_bm | OSC_RC32MEN_bm );
ersetzt.Zum testen habe ich noch folgendes Schnippsel eingebaut
1
    PORTK.DIR = 0xff;  // all OUTPUT
2
    for(;;) {
3
      PORTK.OUTSET = PIN7_bm;
4
       _delay_ms(10);
5
       PORTK.OUTCLR = PIN7_bm;
6
       _delay_ms(10);
7
    }

Seitdem läuft die CPU völlig unrund. Ich hab mal mit Dragon nachgesehen 
was sich da so tut. Der letzte Befehl der noch "richtig" ausgeführt wird 
ist der mit Pfeil markierte. Danach PORTK.DIR... steht im Disass-code 
ein SER R24. Register wird aber nicht mehr verändert. Der nächste Befehl 
ist STS 0x0720, R24. Nach diesem Befehle verändert sich das Listing.

vorher:
  PORTK.DIR = 0xff;  // all OUTPUT
1
->000006E5  SER R24    Set Register 
2
  000006E6  STS 0x0720,R24    Store direct to data space 
3
      PORTK.OUTSET = PIN7_bm;
4
  000006E8  LDI R30,0x20    Load immediate 
5
  000006E9  LDI R31,0x07    Load immediate 
6
  000006EA  LDI R24,0x80    Load immediate

nachher:
  PORTK.DIR = 0xff;  // all OUTPUT
1
  000006E5  SER R24    Set Register 
2
  000006E6  ???     Could not decode instruction  
3
->000006E7  CPC R18,R16    Compare with carry 
4
      PORTK.OUTSET = PIN7_bm;
5
  000006E8  LDI R30,0x20    Load immediate 
6
  000006E9  LDI R31,0x07    Load immediate 
7
  000006EA  LDI R24,0x80    Load immediate

Mittlerweile bin ich scheinbar voll betriebsblind. Ich find
den Fehler einfach nicht.
Wenn jemande ne gute Idee hat???!!! Ich bin für jeden Vorschlag
offen.

Grüße
   Bernie

von Stefan (Gast)


Lesenswert?

Verändert sich der Programmspeicher wirklich? Das kannst DU ja prüfen, 
indem Du den Speicher vorher und anchher ausliest und die beiden Dateien 
vergleichst. Ich bezweifle, dass er sich verändert.

Könnter mir eher vorstellen, dass der Debugger nicht korrekt 
funktioniert. Ist Dein Programm größer als 32kb? Dann ist klar, dass es 
nicht gehen kann.

Hast Du alle Compiler Optimierungen deaktiviert (-O0)? Nur wenn der Code 
nicht optimiert wurde, funktioniert der Debugger anständig in der C 
Ansicht anständig.

von Markus M. (adrock)


Lesenswert?

Hi,

also ich verwende diesen Code um die Clock beim Xmega 192A3 auf 32 MHz 
zu setzen. Am Controller hängt ein Quarz mit 16MHz, der Takt wird dann 
per PLL auf 32 MHz verdoppelt:

1
void CCPWrite( volatile uint8_t * address, uint8_t value )
2
{
3
    uint8_t volatile saved_sreg = SREG;
4
5
    cli();
6
7
    volatile uint8_t * tmpAddr = address;
8
    #ifdef RAMPZ
9
    RAMPZ = 0;
10
    #endif
11
    asm volatile(
12
    "movw r30,  %0"        "\n\t"
13
    "ldi  r16,  %2"        "\n\t"
14
    "out   %3, r16"        "\n\t"
15
    "st     Z,  %1"       "\n\t"
16
    :
17
    : "r" (tmpAddr), "r" (value), "M" (CCP_IOREG_gc), "i" (&CCP)
18
    : "r16", "r30", "r31"
19
    );
20
21
    SREG = saved_sreg;
22
}
23
24
int main(void) {
25
26
    // On XMega setup clock to 32MHz (16 MHz osc. x2 PLL)
27
28
    OSC.CTRL |= OSC_XOSCEN_bm;
29
    
30
    // Wait for it to become stable
31
    
32
    while(! (OSC.STATUS&OSC_XOSCRDY_bm));
33
    
34
    // Enable PLL
35
    
36
    OSC.PLLCTRL = OSC_PLLSRC_XOSC_gc|(2<<OSC_PLLFAC_gp);
37
    OSC.CTRL |= OSC_PLLEN_bm;
38
    
39
    // Wait for it to become stable
40
    
41
    while(! (OSC.STATUS&OSC_PLLRDY_bm));
42
    
43
    // Use it as new CPU clock
44
    
45
    CCPWrite( &CLK.CTRL, CLK_SCLKSEL_PLL_gc );

Grüße
Markus

von berniebaer (Gast)


Lesenswert?

Hi Markus,

ich hab in der Zwischenzeit noch rumgebastelt und mich mit dem ATMEL 
SYSCLOCK_Driver beschäftigt. Jetzt habe ich auch das CCPWrite drin und
es scheint zu laufen. Der Code sieht jetzt nicht viel anders aus als 
deiner.
Mit dem Dragon habe ich noch nicht nachgesehen was sich da tut. Aber ich 
vermute das es sich um ein Timingproblem beim bescheiben des CLK.CTRL 
und CCP handelt. Interessant ist das er Effekt reproduzierbar
ist, sowohl als Einzelprogramm als auch in der Arduino CORE LIB 
(wireing.c).

@ Stefan
Jo, Optimierung raus und Debug alles.
Wieso funktioniert das den nicht mit > 32K Programmen?

Grüße
   Berniebaer

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.