Forum: Mikrocontroller und Digitale Elektronik ATmega809 Timer CMP Interrupt funktioniert nicht


von Max M. (maxmicr)


Lesenswert?

Guten Abend,

ich versuche gerade, den Timer0 des ATmega809 dazu zu bekommen, dass er 
einen Interrupt erzeugt, wenn der Wert im CMP0-Register erreicht ist:
1
#define F_CPU           20000000UL
2
3
#define TIM0_PRESCALER  16
4
#define TIM0_MS         30
5
#define TIM0_MS_FACTOR  ( (F_CPU) / (1000 * TIM0_PRESCALER) )
6
#define TIM0_COMP_VAL   (TIM0_MS * TIM0_MS_FACTOR)
7
8
9
ISR(TCA0_CMP0_vect) {
10
  /* Clear interrupt flag */
11
  TCA0.SINGLE.INTFLAGS |= (1 << TCA_SINGLE_CMP0EN_bp);
12
13
  PORTF.OUT ^= (1 << PIN0_bp);
14
}
15
16
void initTimer0() {
17
  /* Set Prescaler */
18
  TCA0.SINGLE.CTRLA |= TCA_SINGLE_CLKSEL_DIV16_gc;
19
  /* Set CMP value */
20
  TCA0.SINGLE.CMP0 = TIM0_COMP_VAL;
21
  /* Enable Compare Channel 0 Interrupt */
22
  TCA0.SINGLE.INTCTRL |= (1 << TCA_SINGLE_CMP0EN_bp);
23
  /* Enable Timer */
24
  TCA0.SINGLE.CTRLA |= (1 << TCA_SINGLE_ENABLE_bp);
25
}
26
27
void initCPU() {
28
  /* Set Clock source to 20MHz internal oscillator */
29
  CLKCTRL.MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;
30
  /* Disable prescaler */
31
  CLKCTRL.MCLKCTRLB &= ~(1 << CLKCTRL_PEN_bp);
32
  
33
  /* Enable interrupts globally */
34
  sei();
35
  
36
  PORTF.DIR |= (1 << PIN0_bp);
37
}
38
39
int main(void)
40
{
41
  initCPU();
42
  initTimer0();
43
    while (1) 
44
    {
45
    
46
    }
47
}

Allerdings passiert beim debuggen gar nichts (d.h. die Interrupt-Routine 
wird nicht erreicht). Das CNT-Register erhöht sich aber ständig, d.h. 
laufen würde der Timer im Prinzip.

Hat da jemand eine Idee, was noch fehlt?

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Allerdings passiert beim debuggen gar nichts

Was ist darunter zu verstehen, Simulator oder reale Schaltung?

von Max M. (maxmicr)


Lesenswert?

S. Landolt schrieb:
> Simulator oder reale Schaltung?

Reale Schaltung mit nem Atmel-ICE.

Gemessen mit nem Oszi funktionierts allerdings auch nicht.

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wie sind denn die Einträge in der Vektortabelle? 2 Bytes oder 4 Bytes?

von S. Landolt (Gast)


Lesenswert?

Wie sieht das Assembler-Listing aus?
  Ich habe leider keine passende C-Umgebung (und auch nur einen 
ATmega4809).

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

S. Landolt schrieb:
> Wie sieht das Assembler-Listing aus?

Hab ich angehängt

Johann L. schrieb:
> Wie sind denn die Einträge in der Vektortabelle? 2 Bytes oder 4 Bytes?

Ich weiß mit der Frage nicht so recht was anzufangen. Hilft die 
angehängte Datei .map-Datei?

von S. Landolt (Gast)


Lesenswert?

Bitte nicht lachen, aber Vorschlag: versuchsweise ganz ans Ende der 
ISR(TCA0_CMP0_vect) ein 'sei();' setzen.

von Max M. (maxmicr)


Angehängte Dateien:

Lesenswert?

Funktioniert leider auch nicht :(

von S. Landolt (Gast)


Lesenswert?

Jetzt bin ich ratlos, ein entsprechendes Assembler-Programm auf einem 
ATmega4809 läuft hier.

von S. Landolt (Gast)


Lesenswert?

Ich stelle das Programm mal vor, auch wenn es vermutlich nicht viel 
nützt:
1
.org    $2000
2
    rjmp        reset
3
4
.org    $2000 + TCA0_CMP0_vect
5
    push    tmp0
6
    lds     tmp0,TCA0_SINGLE_INTFLAGS   ; The OVF flag is not cleared automatically
7
    sts     TCA0_SINGLE_INTFLAGS,tmp0
8
9
    ldi     tmp0,1
10
    sts     PORTF_OUTTGL,tmp0
11
    pop     tmp0
12
    reti
13
;******************************************************
14
15
reset:
16
;                       Clock Controller (CLKCTRL)
17
;                       20 MHz/1:
18
    puti    CPU_CCP,$D8
19
    puti    CLKCTRL_MCLKCTRLB,0
20
21
    puti    PORTF_DIR,1
22
23
    puti    TCA0_SINGLE_CTRLA,TCA_SINGLE_CLKSEL_DIV16_gc | (1<<TCA_SINGLE_ENABLE_bp)
24
    puti    TCA0_SINGLE_INTCTRL,(1<<TCA_SINGLE_CMP0_bp)
25
    putiw   TCA0_SINGLE_PER,30000
26
    putiw   TCA0_SINGLE_CMP0,$12340
27
28
    sei
29
main_loop:
30
  rjmp      main_loop

von Max M. (maxmicr)


Lesenswert?

Hab jetzt mal testweise an .asm Projekt erstellt und deinen Code 
reinkopiert:
1
puti: Unknown instruction or macro
2
CPU_CCP: Unknown instruction or macro
3
syntax error, unexpected ";" (Zeile "20 MHz/1:")

Braucht man da vielleicht ein Headerfile?

Edit: Hab mal im Instruction Set Summary nachgeschaut und da steht kein 
"PUTI" als Instruktion bzw. Suche über das gesamte Dokumente liefert 
keine Ergebnisse. Bist du dir sicher, dass das der Code ist den du bei 
dir ausgeführt hast?

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Das sind macros, ich versuche mal, ein vollständiges Programm zu 
liefern, Moment.

von S. Landolt (Gast)


Angehängte Dateien:

Lesenswert?

Bitte beachten: ATmega4809!
Das Setzen von TCA0_SINGLE_PER sowie TCA0_SINGLE_CMP0 habe ich jetzt 
gelöscht, ist hier eigentlich nicht nötig.

von Max M. (maxmicr)


Lesenswert?

Krieg da jetzt ein paar "beyond end of memory" Fehler. Ich hab leider 
überhaupt keine Ahnung von ASM.

Trotzdem danke für deine Hilfe und Mühe

von S. Landolt (Gast)


Lesenswert?

Nur am Rande: fehlt da im 'void initCPU()' nicht die Freigabe per 
CPU.CCP?

von S. Landolt (Gast)


Lesenswert?

> Krieg da jetzt ein paar "beyond end of memory" Fehler.

Wurden alle 'ATmega4809' durch 'ATmega809' sowie das 'm4809.def' durch 
'm809.def' ersetzt?

von Max M. (maxmicr)


Lesenswert?

1
.include  "m809def.inc"
2
3
.macro  put
4
#if  defined (__ATmega809__)
5
.if  @0 < $40
6
  out    @0,@1
7
.else
8
  sts    @0,@1
9
.endif
10
#else
11
.if  @0 < $60
12
  out    @0,@1
13
.else
14
  sts    @0,@1
15
.endif
16
#endif
17
.endmacro
18
;----------------------
19
20
.macro  puti
21
  ldi    tmp0,@1
22
  put    @0,tmp0
23
.endmacro
24
;----------------------
25
26
.macro  putiw
27
#if  defined (__ATmega809__)
28
.ifdef  @0H
29
  ldi    tmp0,low (@1)
30
  put    @0L,tmp0
31
  ldi    tmp0,high(@1)
32
  put    @0H,tmp0
33
.else
34
  ldi    tmp0,low (@1)
35
  put    @0+0,tmp0
36
  ldi    tmp0,high(@1)
37
  put    @0+1,tmp0
38
.endif
39
#else
40
.ifdef  @0H
41
  ldi    tmp0,high(@1)
42
  put    @0H,tmp0
43
  ldi    tmp0,low (@1)
44
  put    @0L,tmp0
45
.else
46
  ldi    tmp0,high(@1)
47
  put    @0+1,tmp0
48
  ldi    tmp0,low (@1)
49
  put    @0+0,tmp0
50
.endif
51
#endif
52
.endmacro
53
;----------------------
54
55
.def  tmp0  = r16
56
57
.org  $2000
58
  rjmp    reset
59
60
.org  $2000 + TCA0_CMP0_vect
61
  push  tmp0
62
  lds    tmp0,TCA0_SINGLE_INTFLAGS  ; The OVF flag is not cleared automatically
63
  sts    TCA0_SINGLE_INTFLAGS,tmp0
64
65
  ldi    tmp0,1
66
  sts    PORTF_OUTTGL,tmp0
67
  pop    tmp0
68
  reti
69
;******************************************************
70
71
reset:
72
;            Clock Controller (CLKCTRL)
73
;            20 MHz/1:
74
  puti  CPU_CCP,$D8
75
  puti  CLKCTRL_MCLKCTRLB,0
76
77
  puti  PORTF_DIR,1
78
79
  puti  TCA0_SINGLE_CTRLA,TCA_SINGLE_CLKSEL_DIV16_gc | (1<<TCA_SINGLE_ENABLE_bp)
80
  puti  TCA0_SINGLE_INTCTRL,(1<<TCA_SINGLE_CMP0_bp)
81
82
  sei
83
main_loop:
84
  rjmp    main_loop
1
Severity  Code  Description  Project  File  Line
2
Warning    offset 0x4000 in .cseg is beyond end of memory at 0x1fff  TestASM  main.asm  57
3
Error    Relative branch out of reach  TestASM  main.asm  58
4
Warning    offset 0x4002 in .cseg is beyond end of memory at 0x1fff  TestASM  main.asm  60
5
Warning    offset 0x4012 in .cseg is beyond end of memory at 0x1fff  TestASM  main.asm  60
6
Warning    end of .cseg at 0x4046 is beyond end of memory at 0x1fff  TestASM  main.asm  84
7
Error    Relative branch out of reach  TestASM  main.asm  84

S. Landolt schrieb:
> fehlt da im 'void initCPU()' nicht die Freigabe per
> CPU.CCP?

Das stimmt - vielen Dank! Hab ich nachgetragen, funktioniert aber 
trotzdem nicht:
1
CCP = 0xD8;

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

Tja, da steht im Datenblatt für alle 4 Flash-Größen "Start address in
Data Space 0x4000", aber entweder stimmt das nicht oder ich verstehe es 
falsch.

von S. Landolt (Gast)


Lesenswert?

Also gut, einfach mal die beiden "$2000" durch "0" ersetzen und schauen, 
was passiert.

von Max M. (maxmicr)


Lesenswert?

S. Landolt schrieb:
> Also gut, einfach mal die beiden "$2000" durch "0" ersetzen und schauen,
> was passiert.

Dann kompiliert es zwar aber funktioniert trotzdem nicht (durch den Code 
steppen im Debug-Modus funktioniert aber also scheinbar denkt der 
Assembler schon mit und mapped den gesamten Code an die passende 
Stelle?).

Kann das auch an meiner Schaltung liegen? Aber eigentlich nicht, der Pin 
wackelt einwandfrei wenn ich das Togglen in die while-Schleife 
verschiebe.

Ansonsten frage ich mich noch ob ich vielleicht irgendwie ausversehen 
eine Fuse gesetzt hab die einen Timer deaktiviert?

Oder muss man erst die Peripherie mit dem Clock versorgen so wie bei den 
STM32ern? Irgendwas aktivieren?

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Dann kompiliert es zwar aber funktioniert trotzdem nicht.

Auch nach Aus-Ein-Schalten nicht?

> ... Fuse ...

Nicht, dass ich wüsste; bin aber kein Spezialist für die megaAVR® 
0-series.

Und da mir sonst nichts mehr einfällt, darf ich mich verabschieden. 
Wünsche einen frohen 4. Advent.

von Max M. (maxmicr)


Lesenswert?

1
reset:
2
;            Clock Controller (CLKCTRL)
3
;            20 MHz/1:
4
  puti  CPU_CCP,$D8
5
  puti  CLKCTRL_MCLKCTRLB,0
6
7
  puti  PORTF_DIR,1
8
9
  puti  TCA0_SINGLE_CTRLA,TCA_SINGLE_CLKSEL_DIV16_gc | (1<<TCA_SINGLE_ENABLE_bp)
10
  puti  TCA0_SINGLE_INTCTRL,(1<<TCA_SINGLE_CMP0_bp)
11
12
  sei
13
main_loop:
14
  ldi    tmp0,1
15
  sts    PORTF_OUTTGL,tmp0
16
  ldi    tmp0,0
17
  nop
18
  sts    PORTF_OUTTGL,tmp0
19
  rjmp    main_loop

So toggled der Pin, also Code funktioniert.

Edit: Die Lösung: 
https://www.avrfreaks.net/forum/atmega809-wont-generate-tca0-cmp-interrupt

Sachen gibts Kopf auf Tisch

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

habe mal ein Bsp. erstellt. Beide Pins takten mit 5Hz.
1
/*
2
 * Timer0_CMP_ISR.cpp
3
 *
4
 * Created: 22.12.2019 01:02:33
5
 * Author : Devil-Elec
6
 * Board  : ATmega4809 Curiosity Nano
7
 */ 
8
9
#include <avr/io.h>
10
#include <avr/interrupt.h>
11
12
13
void TCA0_FREQ_init(void);
14
15
16
int main(void)
17
{
18
    // init Main Clock 20MHz   
19
    CPU_CCP = CCP_IOREG_gc;              // write access for four CPU instructions
20
    CLKCTRL_MCLKCTRLA = CLKCTRL_CLKSEL_OSC20M_gc;  // select Source before prescaler set
21
    CPU_CCP = CCP_IOREG_gc;              // write access for four CPU instructions
22
    CLKCTRL_MCLKCTRLB = 0;              // no prescaler, default nach Reset ist prescaler 6
23
       
24
   TCA0_FREQ_init();
25
   
26
   PORTA.DIR = PIN0_bm;     // TCA0 Pin
27
   PORTF.DIR = PIN5_bm;
28
   
29
   sei();
30
       
31
   while (1)
32
   {
33
       ;
34
   }
35
}
36
37
38
39
void TCA0_FREQ_init(void)
40
{
41
    TCA0.SINGLE.CMP0BUF = 31249;                        // TOP - Compare Register - Frequenz bestimmend
42
   
43
    TCA0.SINGLE.CNT = 0;
44
45
    TCA0.SINGLE.CTRLB  = TCA_SINGLE_ALUPD_bm;           // enabled Auto Lock Update
46
    TCA0.SINGLE.CTRLB |= TCA_SINGLE_CMP0EN_bm;          // enable Compare 0, WOn toogle
47
    TCA0.SINGLE.CTRLB |= TCA_SINGLE_WGMODE_FRQ_gc;      // Frequency Mode
48
    
49
    TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP0_bm;           // enable Compare 0 Interrupt
50
    
51
    TCA0.SINGLE.CTRLA  = TCA_SINGLE_CLKSEL_DIV64_gc;    // Prescaler
52
    TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;          // enable TCA module
53
}
54
55
56
57
ISR(TCA0_CMP0_vect)
58
{
59
    PORTF.OUTTGL = PIN5_bm;
60
        
61
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;          
62
}

von S. Landolt (Gast)


Lesenswert?

Wobei ich mich frage, weshalb in der ATmega-Großfamilie überhaupt noch 
Controller mit 8 KiB Flash entwickelt, produziert und gekauft werden - 
und der verantwortliche Ingenieur ist ja auch prompt darauf 
reingefallen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

naja, Druckfehler in Datenblättern können immer wieder passieren, falls 
da überhaupt ein Fehler ist, weil die ja kompatibel zueinander sind und 
alle Register in der neuen Serie grundlegend aufgeräumt bzw. 
vernünftig(er) strukturiert wurden.

Wegen 8KiB. Meinste nicht das es immer kleine und große µC geben wird?

Habe nochmal in die iomX809.h geschaut, 4809 mit 809 verglichen.
Für beide gilt:
define MAPPED_PROGMEM_START     (0x4000)

Würde sagen wollen, dass haut schon alles hin.


Fröhliche Weihnachten und frohes Programmieren ...  :-)

von S. Landolt (Gast)


Lesenswert?

Ich bezog mich auf die Vektortabelle des ATmega809, s. Zitat im Link von 
Max M.:

"This chip has a silicon bug, incorrect size of interrupt vectors. See 
discussion here: https://www.avrfreaks.net/forum/...";

Zugegeben, könnte man vielleicht entfernt auch als "Druckfehler im 
Datenblatt" interpretieren, aber ich weiß nicht ...

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

S. Landolt schrieb:
> Ich bezog mich auf die Vektortabelle des ATmega809, s. Zitat im Link von
> Max M.:
>
> "This chip has a silicon bug, incorrect size of interrupt vectors. See
> discussion here: https://www.avrfreaks.net/forum/...";
>
> Zugegeben, könnte man vielleicht entfernt auch als "Druckfehler im
> Datenblatt" interpretieren, aber ich weiß nicht ...

avr-gcc behandelt ATmega808/809 wie andere 8KiB-Devices auch, d.h. nimmt 
an, dass es kein CALL/JMP gibt.  Laut Datenblatt gibt es diese 
Instruktionen zwar, aber sie sind 1) Resourcenverschwendung und 2) 
bestimmt die avr-libc daraus die Größe der Einträge in .vectors.

Was aber etwas irritiert ist, dass die eingesetzte Toolchain mit 100% 
Wahrscheinlichkeit ohne nativen ATmega808/809-Support kommt, und der 
Support stattdessen per Device-Packs vom Hersteller erfolgt.  Und wenn 
der noch nichtmal weiß, wie seine Devices eigenen funktionieren, und 
noch nicht 1× ein Programm für diese Devices übersetzt und hat laufen 
lassen, dann spricht das nicht wirklich für Qualität.

Und wie sieht's für ATtiny807/806/804? Haben die auch 4-Byte Vektoren?

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Hallo,

ist das ein Doppelposting vom TO? Hier und dort im Forum?
Bei genauer Betrachtung wurde das mit dem vermuteten Siliziumbug demnach 
widerlegt. Hätte ich mir auch nicht vorstellen können, jedenfalls nicht 
im fertig entwickelten Produkt.

Der TO hat den Timer einfach falsch programmiert.
Sein Mainclock hätte so auch nicht funktioniert.
Im Normalmode muss das PER/PERBUF Register als TOP verwendet werden.
Im Frequencymode muss das CMPn/CMPnBUF Register als TOP verwendet 
werden.
Dann funktioniert die CMP ISR.

Die Serie ist noch neu, muss man sich sachte vortasten. Der Schreibstil 
im Manual ist auch anders was man bis jetzt gewohnt war. :-)

von Max M. (maxmicr)


Lesenswert?

Vielen dank für eure Antworten.

Ich habe mich ursprünglich für den ATmega809 entschieden (bzw. allgemein 
für die neue AVR-Reihe), weil ich auf einfacher zu bedienende Hardware 
gehofft hatte.

Nachdem ich ursprünglich die IAR Kickstart-Version verwenden wollte 
(Code-größenbeschränkt auf 4Kbyte), aber IAR so derbe Bugs in der 7.20.1 
drinn hat, dass der Atmel-ICE nicht funktioniert (Bugfixes gibts 
natürlich nur für zahlende Kunden), bin ich nun doch auf Atmel Studio 
umgeschwenkt.

Hab dann aber einen ganzen Tag gebraucht um einen Timer zum laufen zu 
bekommen nur um herauszufinden, dass der Hersteller keinen Peil von 
seinen eigenen Produkten hat.
Im Nachhinein kann ich mir aus dem Datenblatt auch nicht wirklich 
herleiten, dass ich den Timer im Frequenzmodus laufen lassen muss.

Für dieses sehr simple Programm belegt der avr-gcc nun fast unverschämte 
300byte Flash (das Assembler-Programm von Landolt braucht knapp 60byte). 
So schnell fass ich keinen AVR / Microchip mehr an, das gibts doch 
nicht.

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> Der TO hat den Timer einfach falsch programmiert.

Das verstehe ich nicht: für PER gilt doch "Reset: 0xFFFF" laut 
Datenblatt, und im vorliegenden Programm ist der Wert von CMP0 
unerheblich, er wird auf jeden Fall durchlaufen und damit sollte die LED 
blinken.

von S. Landolt (Gast)


Lesenswert?

> Bei genauer Betrachtung wurde das mit dem vermuteten
> Siliziumbug demnach widerlegt.

Ich muss zugeben, dass ich nicht alles auf avrfreaks gelesen habe, 
aber:

in einem alten ATmega_DPF steht in iom809.h:
#define _VECTOR_SIZE 2 /* Size of individual vector. */
wie es sich für einen 8 KiB-Controller gehören würde, jetzt lese ich 
dort:
#define _VECTOR_SIZE 4 /* Size of individual vector. */

von Veit D. (devil-elec)


Lesenswert?

Hallo,

@ Landolt:
geht ja auch, wenn man es richtig programmiert. Beim TO gehts ja 
mittlerweile auch. Womit ich weniger klar komme ist wenn der TO die 
Schuld jetzt auf den Hersteller schiebt. Man muss sich in jeden neuen µC 
einarbeiten. Dabei ist jeder 8Bitter noch leicht(er) überschaubar. Die 
neue AVR Serie hat neue Timer mit mehr Möglichkeiten und aufgeräumten 
Registern. Das man das nicht alles gleich aus dem ff beherrscht ist 
klar.
C++ und Assembler kann man nun auch nicht direkt vergleichen.
Das unten reduzierte benötigt bei mir 268Byte Flash und 0 Byte RAM.
1
void TCA0_init(void)
2
{
3
    // TCA0.SINGLE.PERBUF default 0xFFFF ... 2,38Hz
4
    TCA0.SINGLE.CNT = 0;
5
6
    TCA0.SINGLE.CTRLB = TCA_SINGLE_WGMODE_NORMAL_gc;   // Normal Mode
7
    
8
    TCA0.SINGLE.INTCTRL = TCA_SINGLE_CMP0_bm;           // enable Compare 0 Interrupt
9
    
10
    TCA0.SINGLE.CTRLA  = TCA_SINGLE_CLKSEL_DIV64_gc;    // Prescaler
11
    TCA0.SINGLE.CTRLA |= TCA_SINGLE_ENABLE_bm;          // enable TCA module
12
}
13
14
ISR(TCA0_CMP0_vect)
15
{
16
    PORTF.OUTTGL = PIN5_bm;
17
    TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;          
18
}

@ Johann:
Hab in die Header geschaut.
Bei den ATtinys (804) beginnt der Flash ab 0x4000
und
#define _VECTOR_SIZE 2 /* Size of individual vector. */
#define _VECTORS_SIZE (31 * _VECTOR_SIZE)

bei den ATmegas (4809) beginnt der Flash ab 0x8000
und
#define _VECTOR_SIZE 4 /* Size of individual vector. */
#define _VECTORS_SIZE (40 * _VECTOR_SIZE)


Wenn es beim TO jetzt funktioniert, bedeutet das für mich das alles 
andere auch i.O. ist.


... ich muss erstmal Geschenke verpacken ...

von S. Landolt (Gast)


Lesenswert?

> Womit ich weniger klar komme ist wenn der TO die
> Schuld jetzt auf den Hersteller schiebt.

Tja, Veit D., da sind wir nun mal unterschiedlicher Meinung. Die 
Vektorgröße des ATmega809 passt nicht zu allem Bisherigen - entweder ein 
Fehler im Chip oder in der alten iom809.h, so oder so: Schuld von 
Microchip/Atmel.

Soll uns beiden aber die Vorfreude auf geruhsame Feier- und Ferientage 
in keiner Weise vermiesen!

von Max M. (maxmicr)


Lesenswert?

Veit D. schrieb:
> C++ und Assembler kann man nun auch nicht direkt vergleichen.

Ist ja auch C und kein C++. Und ein 6x so großes Binary - da muss 
irgendwas schief laufen. Vor allem, da das alles nur Befehle sind, die 
Werte in ein Register schreiben.

Veit D. schrieb:
> Womit ich weniger klar komme ist wenn der TO die
> Schuld jetzt auf den Hersteller schiebt.

Wenn die Lösung ist, dass ich die Definitionsdateien der Controller neu 
herunterladen muss (obwohl ich mein Atmel-Studio vor 5 Tagen neu 
installiert habe), dann schiebe ich schon die Schuld auf den Hersteller 
(wie gesagt, ich hab keine Zeile Code geändert, nur heruntergeladen -> 
installiert -> Laptop neu gestartet -> neu kompiliert -> funktioniert).

Bevor ich die neue Definitionsdateien nicht heruntergeladen und 
installiert hatte, war das Programm seltsamerweise "nur" 200Byte groß.

S. Landolt schrieb:
> Soll uns beiden aber die Vorfreude auf geruhsame Feier- und Ferientage
> in keiner Weise vermiesen!

+1

: Bearbeitet durch User
von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Veit D. schrieb:
> @ Johann:
> Hab in die Header geschaut.
> Bei den ATtinys (804) beginnt der Flash ab 0x4000
> und
> #define _VECTOR_SIZE 2 /* Size of individual vector. */
> #define _VECTORS_SIZE (31 * _VECTOR_SIZE)

Dateien sind geduldig.  Was zählt ist, was die Hardware macht.  Gibt's 
dazu belastbare aussagen?

> bei den ATmegas (4809) beginnt der Flash ab 0x8000
> und
> #define _VECTOR_SIZE 4 /* Size of individual vector. */

Wie zu erwarten bei > 8KiB Flash.

von neuer PIC Freund (Gast)


Angehängte Dateien:

Lesenswert?

>Ist ja auch C und kein C++. Und ein 6x so großes Binary - da muss
>irgendwas schief laufen. Vor allem, da das alles nur Befehle sind, die
>Werte in ein Register schreiben.

Weil der gcc nicht smart genug ist, es bei kurzen snippets mit einem 
Assemblerprogrammierer aufzunehmen? Wie soll er auch. Für diese ISR 
braucht er Register (hat so eine RISC-Architektur an sich). Nun hat der 
gcc dummerweise als Altlast R0+R1 verwendet. Wohl erst später kam der 
mul-Befehl, welcher R0+R1 als output hat. Schade, so müssen R0+R1 
jedesmal gesichert werden; in der ISR könnte ja ein mul-Befehl 
auftauchen. Dummerweise ist R1 zum  NULL-Register gemacht worden. 
Deswegen das XOR. R2 als tmp und R3 als NULL und R0+R1 einfach nicht 
betrachtet, könnte der Interrupt unter avr-gcc schneller laufen. Habe 
schon gcc-Programme für den AVR gesehen, wo z.B. R7 überhaupt nicht 
verwendet wurde.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

@ Max:
Deinen aktuellen Frust kann ich jetzt nachvollziehen. In paar Wochen 
siehst du das bestimmt anders. Die IDE etc. ist auch nur Software die 
gepflegt werden muss. Fehler wurden korrigiert. Microchip hat seinen Job 
gemacht. Ich sehe das eher positiv.


@ Johann:
ich habe keinen ATtiny der neuen Serie zur Verfügung. Ich möchte mich 
ganz auf die ATmegas konzentrieren, sonst liegt bei mir zu viel µC Müll 
rum.  :-)


@ S. Landolt:
> Soll uns beiden aber die Vorfreude auf geruhsame Feier- und Ferientage
> in keiner Weise vermiesen!

Volle Zustimmung!   +1   :-)

Wir lassen uns von alledem nicht unterkriegen.

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

neuer PIC Freund schrieb im Beitrag #6082716:
> Für diese ISR braucht er Register (hat so eine RISC-Architektur an
> sich). Nun hat der gcc dummerweise als Altlast R0+R1 verwendet.
> Wohl erst später kam der mul-Befehl, welcher R0+R1 als output hat.
> Schade, so müssen R0+R1 jedesmal gesichert werden;

Das ist bei allen unterstützten GCC-Versionen nicht mehr der Fall.  Für 
den Code von

Veit D. schrieb:
1
> ISR(TCA0_CMP0_vect)
2
> {
3
>     PORTF.OUTTGL = PIN5_bm;
4
>     TCA0.SINGLE.INTFLAGS = TCA_SINGLE_CMP0_bm;
5
> }

erzeugen alle aktuellen Versionen, wenn Optimierung aktiviert ist (außer 
mit -Og):
1
00000102 <__vector_9>:
2
 102:  8f 93         push  r24
3
 104:  80 e2         ldi  r24, 0x20  ; 32
4
 106:  80 93 a7 04   sts  0x04A7, r24  ; 0x8004a7
5
 10a:  80 e1         ldi  r24, 0x10  ; 16
6
 10c:  80 93 0b 0a   sts  0x0A0B, r24  ; 0x800a0b
7
 110:  8f 91         pop  r24
8
 112:  18 95         reti

Warum der Hardwarehersteller keinen aktuellen Compiler verteilt, 
entzieht sich meiner Kenntnis.

Dass der Code so groß ist, liegt jedoch an der Vector-Tabelle des 
Startup-Codes:  allein die nimmt beim ATmega4809 160 Bytes ein.

: Bearbeitet durch User
von Veit D. (devil-elec)


Lesenswert?

Johann L. schrieb:

> Warum der Hardwarehersteller keinen aktuellen Compiler verteilt,
> entzieht sich meiner Kenntnis.

Ich habe nur eine Vermutung. Wenn sie nur Assembler und C Bsp. in ihre 
Manuals drucken, kommen sie mit ihrer 5.4.0 Toolchain noch lange hin. 
Wer nur in C++11 programmiert hat damit auch kein Problem. Wer neuer 
möchte muss sich leider kümmern. Du kennst ja den Aufwand am Besten der 
notwendig ist die Toolchain für aktuellen C++ Compiler auf dem laufenden 
zu halten. Das wollen die sich bestimmt sparen, obwohl das genau der 
Punkt wäre wo sie dich/euch unterstützen müßten. Ist das bei anderen 
Hersteller IDEs besser? Ich weiß nicht wie die zukünftige Pflege der 
Microship MPLAP X IDE aussehen wird. Irgendwann wird AS7 bestimmt nicht 
mehr supportet. Zwei IDEs pflegen ist derzeit wohl deren Luxus.

von Np R. (samweis)


Lesenswert?

Veit D. schrieb:
> Irgendwann wird AS7 bestimmt nicht
> mehr supportet.

Das hat aber mit der Version des avr-gcc nichts zu tun.
MPLABX benutzt ja (für AVR) denselben Compiler.

Ich denke eher, das sind die Nachwehen des Kulturkampfes nach der 
Übernahme.
Wenn man den ganzen Tag herumläuft mit der Message "Now we'll do it the 
Microchip way", dann ist Input von außen und Zusammenarbeit mit Externen 
das letzte, was man sucht...

von Wilhelm M. (wimalopaan)


Lesenswert?

Johann L. schrieb:
> erzeugen alle aktuellen Versionen, wenn Optimierung aktiviert ist (außer
> mit -Og):

@Johann: Du hattest das doch gefixed:

https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81268

Dazu muss in den device-specs ja folgendes stehen:
1
*asm_gccisr:
2
    %{!mno-gas-isr-prologues: -mgcc-isr}

Wenn ich mich recht erinnere, ist das in den device-packs von MicroChip 
nicht drin.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

du meinst diese Dateien von Johann?
Beitrag "Re: cannot read spec file 'device-specs/specs-atmega4808'"
Damals ging es nur um die ATmegas.

von Wilhelm M. (wimalopaan)


Lesenswert?

Die device-specs sind in den Device-Packs von MicroChip enthalten. Diese 
enthalten aber die oben genannte Zeile nicht,

von Johann L. (gjlayde) Benutzerseite


Lesenswert?

Wilhelm M. schrieb:
> Johann L. schrieb:
>> erzeugen alle aktuellen Versionen, wenn Optimierung aktiviert ist (außer
>> mit -Og):
>
> @Johann: Du hattest das doch gefixed:
>
> https://gcc.gnu.org/bugzilla/show_bug.cgi?id=81268
>
> Dazu muss in den device-specs ja folgendes stehen:
>
>
1
> *asm_gccisr:
2
>     %{!mno-gas-isr-prologues: -mgcc-isr}
3
>

PR81268 ist der GCC-Teil des Optimierens von ISR Pro- und Epilogen; die 
Änderung beinhaltet auch eine Anpassung der specs-Generierung so dass 
obige Spec enthalten ist.

Problem gibt es dann, wenn man einen neuen Compiler mit einem alten, 
inkompatiblen Spec-File ohne obige Spec verwendet.

Idealerweiese sind die Specs-Dateien unabhängig von der Compilerversion, 
aber die Tools entwickeln sich eben weiter. Und die Specs, die der 
Compiler mitbringt, sind so gestaltet, dass sie kompatibel zu älteren 
Versionen sind.

> Wenn ich mich recht erinnere, ist das in den device-packs von MicroChip
> nicht drin.

von BlaBla (Gast)


Angehängte Dateien:

Lesenswert?

Für das Atmel Studio 7 gibt es ein Update über den Device Pack Manager.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

Danke für die Info.
Dein Weihnachtsmann wird nachher gewiss fleißig sein.

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.