Forum: Mikrocontroller und Digitale Elektronik ATmega4809 TCA Input Event Counter


von Veit D. (devil-elec)


Lesenswert?

Hallo,

ich muss euch mal fragen ob das Verhalten von TCA normal ist oder nicht. 
Im Manual lese ich nichts von der Notwendigkeit das TCA CNT Register auf 
1 setzen zu müssen statt auf 0 nach Reset zu belassen. Den Testcode habe 
ich für die Gemeinde in Barmetall umgeschrieben damit es jeder 
ausprobieren kann wer möchte.

Der Code soll die Overflows der RTC zählen. Alles im Sekundentakt. Das 
wird über das Eventsystem angebunden. Alles wie gehabt. TCA wurde wegen 
Arduinovoreinstellungen komplett resetet und dann neu konfiguriert. Wer 
die Arduino IDE verwendet muss allerdings den MegaCoreX von MCUdude 
verwenden. Er hat TCA komplett freigeschaufelt. Ohne dessen CorePackage 
funktioniert millis nicht, da hängt der TCA noch mit drin.

Ich musste jedenfalls feststellen das TCA nur beginnt zu zählen wenn ich 
CNT auf 1 nach Reset setze und nicht auf 0. Ich kann mir nicht erklären 
warum man das machen muss. Ist das bei euch auch so? Mit einem AVRxDB 
gibt es keine solchen Probleme. Im Errata lese ich davon auch nichts. 
Mach ich was falsch oder ist das so?

Was ich auch soeben getestet habe ist, wenn ich den nächsten TCA 
Überlauf provoziere mit Einstellung 65530 nach Reset, dann zählt er bis 
65535, geht auf 0 und bleibt auf 0. Man müßte hier auch wieder 
nachhelfen und auf 1 setzen.
1
/* 
2
  IDE 1.8.19
3
  Arduino Nano Every
4
  MegaCoreX erforderlich
5
  TCA0 zählt über den Event Eingang die Überläufe der RTC
6
*/
7
8
#include <avr/io.h>
9
#include <avr/interrupt.h>
10
#include <util/atomic.h>
11
12
void setup (void)
13
{                     
14
  Serial.begin(9600);             
15
  Serial.println("\nuReset ### ###");
16
  initRTC();
17
  initTCA0();
18
  initEventSystem();
19
}
20
21
void loop (void)
22
{  
23
  readCounter(Serial, 1000);
24
}
25
26
void readCounter(Stream &cout, const uint32_t interval)
27
{
28
  static unsigned long lastMillis {0};
29
  
30
  if (millis() - lastMillis >= interval) {
31
    lastMillis += interval;
32
    cout.print("count ");
33
    cout.println(TCA0.SINGLE.CNT);
34
  } 
35
}
36
37
void initEventSystem (void)
38
{
39
  EVSYS.CHANNEL7 = EVSYS_GENERATOR_RTC_OVF_gc;    // Generator 'RTC OVF' mit Channel 7 verbinden
40
  EVSYS.USERTCA0 = EVSYS_CHANNEL_CHANNEL7_gc;     // Channel 7 mit User 'TCA0' verbinden, damit reagiert TCA0 auf RTC OVF
41
}
42
43
void initTCA0 (void)
44
{
45
  // alles reseten wegen Arduino Voreinstellungen
46
  TCA0.SINGLE.CTRLA    = 0;
47
  TCA0.SINGLE.CTRLB    = 0;
48
  TCA0.SINGLE.CTRLC    = 0;
49
  TCA0.SINGLE.CTRLD    = 0; 
50
  TCA0.SINGLE.CTRLESET = TCA_SINGLE_CMD_RESET_gc;
51
  TCA0.SINGLE.EVCTRL   = 0;
52
  TCA0.SINGLE.INTCTRL  = 0;
53
  TCA0.SINGLE.INTFLAGS = 0xFF;
54
  TCA0.SINGLE.DBGCTRL  = 0;
55
  TCA0.SINGLE.CNT      = 1; // größer 0 erforderlich
56
  TCA0.SINGLE.PERBUF   = 0;
57
  TCA0.SINGLE.PER      = 0;
58
  TCA0.SINGLE.CMP0     = 0;
59
  TCA0.SINGLE.CMP1     = 0;
60
  TCA0.SINGLE.CMP2     = 0;
61
      
62
  TCA0.SINGLE.CTRLA = TCA_SINGLE_CLKSEL_DIV1_gc;
63
  TCA0.SINGLE.EVCTRL = TCA_SINGLE_EVACT_POSEDGE_gc;
64
  // TCA0.SINGLE.EVCTRL = TCA_SINGLE_EVACT_ANYEDGE_gc;
65
  TCA0.SINGLE.EVCTRL = TCA0.SINGLE.EVCTRL | TCA_SINGLE_CNTEI_bm;  
66
  TCA0.SINGLE.CTRLA = TCA0.SINGLE.CTRLA | TCA_SINGLE_ENABLE_bm; 
67
}
68
69
void initRTC (void)
70
{
71
  while (RTC.STATUS > 0) { ; }          // warten auf Register Syncronisierung
72
  RTC.CLKSEL = RTC_CLKSEL_INT32K_gc;    // Periodendauer 30,518µs
73
  RTC.PER = 64;                         // = 1000ms / 15,625ms
74
  // RTC.CTRLA Bug, see Errata
75
  byte temp {0};
76
  temp |= RTC_PRESCALER_DIV512_gc;      // Prescaler 512 -->> 30,518µs * 512 = 15,625ms
77
  temp |= RTC_RTCEN_bm;                 // RTC aktivieren  
78
  RTC.CTRLA = temp;
79
}

: Bearbeitet durch User
von S. Landolt (Gast)


Lesenswert?

> TCA wurde ... komplett resetet

Das stimmt nun nicht, der Reset-Wert von TCA0_PER ist nicht 0, sondern 
0xFFFF.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

hmmm, dass hatte ich übersehen. Habe nun PER und PERBUF mit 0xFFFF 
initialisiert und jetzt funktioniert es auch mit CNT Startwert 0 und er 
zählt nach Überlauf weiter. Danke. Das heißt selbst wenn PER nicht 
benötigt wird wird damit verglichen und ein CNT "Reset" ausgeführt?

von S. Landolt (Gast)


Lesenswert?

During normal operation, the counter value is continuously compared to 
zero and the period (PER) value to determine whether the counter has 
reached TOP or BOTTOM. The counter value can also be compared to the 
TCAn.CMPn registers.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

das erklärt Einiges, habe ich nicht beachtet.
Vielen Dank. Wünsche schattiges WE.

von S. Landolt (Gast)


Lesenswert?

Danke, Ihnen auch.
  Und vielleicht gibt es ja am Sonntag endlich etwas Regen hier im 
Südwesten.

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.