ATmega4809 TCA Input Event Counter

OP #7157463
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
}
OP #7157523
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?
Gast #7157525
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.

Antwort schreiben

Bitte melde dich an, um einen Beitrag zu schreiben.

oder

Mit Google-Account einloggen

Die Registrierung ist kostenlos und dauert nur eine Minute.

Jetzt registrieren