Forum: Mikrocontroller und Digitale Elektronik AVR ATtiny Serie 1: Input Capture TCD0


von Wulf D. (holler)


Lesenswert?

Hat mal jemand auf den AVR ATTiny der Serie 1 einen Input Capture auf 
Timer/Counter D, also TCD0 umgesetzt?

Man muss das im datasheet spärlich dokumentierte Event-System 
konfigurieren. Wollte ausgehend von einem Flankenwechsel eines Portpins 
auf dem TCD0 einen Capture auslösen und dabei einen synchronen 
Event-Channel nutzen. Da kann man noch ein Digitalfilter nutzen.

Den Portpin als Event-Generator zu definieren ist kein Problem.

Jetzt finde ich aber weder im Datenblatt noch in den Headerfiles 
Hinweise auf einen TCD0 als "Synchronous User".

Oder ist der "Synchronous Event Channel 0" per default immer mit dem 
"Input Event A" des TCD0 und der Channel 1 mit dem Event B Eingang 
verbunden?

Reine Spekulation, leider steht im DaBla nix darüber.

Eine asynchrone Lösung findet man, damit kann man aber kein Filter 
nutzen.

von Ob S. (Firma: 1984now) (observer)


Angehängte Dateien:

Lesenswert?

Wulf D. schrieb:

> Man muss das im datasheet spärlich dokumentierte Event-System
> konfigurieren. Wollte ausgehend von einem Flankenwechsel eines Portpins
> auf dem TCD0 einen Capture auslösen und dabei einen synchronen
> Event-Channel nutzen. Da kann man noch ein Digitalfilter nutzen.
>
> Den Portpin als Event-Generator zu definieren ist kein Problem.
>
> Jetzt finde ich aber weder im Datenblatt noch in den Headerfiles
> Hinweise auf einen TCD0 als "Synchronous User".

Der TCD ist ein exotisches Tier, denn er ist von Hause aus asynchron zum 
Rest. Er synchronisiert also immer selber auf seine Takt-Domain. Und an 
dieser Stelle hat er dann auch eigene Filter. Siehe Blockschaltbild.

Die wesentliche Ausnahme davon ist das direkte "Durchgreifen" auf die 
Ausgänge des TCD. Das kann wirklich asynchron erfolgen, dann aber eben 
auch nicht gefiltert werden. Das ist aber überhaupt nicht deine 
gegenwärtige Spielwiese. Wenn ich dich richtig verstanden habe, willst 
du ja nur Capturen.

> Oder ist der "Synchronous Event Channel 0" per default immer mit dem
> "Input Event A" des TCD0 und der Channel 1 mit dem Event B Eingang
> verbunden?

Nö, womit die beiden Input Events des TCD verbunden werden, ist über das 
Eventsystem konfigurierbar. Und es ist scheißegal, ob die Quelle in 
üblicher Lesart synchron oder asynchron ist, sie muß sowieso mit der 
Taktdomain des TCD synchronisiert werden. Ausnahme ist, wie gesagt, die 
direkte Steuerung der Ausgabe. Die kann auch wirklich asynchron 
erfolgen, wobei asynchron hier doppelt asynchron ist, erstens asynchron 
zum IO-Takt (also die übliche Lesart), aber auch asynchron zur 
TCD-Taktdomain.

> Reine Spekulation, leider steht im DaBla nix darüber.

Da steht alles darüber. Man muss nur verstehend lesen und nicht nur 
überfliegen.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

vielleicht hilft dir die App Note 3212 "Getting Started with TCD" 
weiter.
https://www.microchip.com/en-us/product/attiny3217#Tools%20And%20Software
Unterhalb bis auf "Seite" 10 vorklicken.

von Wulf D. (holler)


Lesenswert?

Ob S. schrieb:
> Da steht alles darüber. Man muss nur verstehend lesen und nicht nur
> überfliegen.

Danke für deine Hinweise. Das mit dem asynchronen Output hatte ich auch 
so verstanden, aber wie du schon sagtest, brauche ich nicht. Nur 
Capture.

Ich hatte das schon mehr als überflogen. Ich halte die Erklärungen noch 
immer für stark verbesserungswürdig. Der TCD0 ist wohl immer ein "async 
user" im Sinne des Event-Systems. Doof halt wenn da Sätze wie diese 
stehen:
1
It is not possible to use asynchronous event detection and digital filter at the same time.

Andere Beispiele:
- die beiden Event-Eingänge werden im TCD0-Kapitel mit "Input Event A" 
und "Input Event B" bezeichnet. Aber nur da.
Im EVSYS-Kapitel stehen die mit "Event 0" und "Event 1", ebenso wie in 
den Headerfiles.

- Mal heißt das unterste Bit im TCD-Eventregister (TCD0.EVCTRLA) CAPTEI, 
mal heisst es TRIGEI.

Ich finde solche Inkonsistenzen nervig, kosten Zeit die richtige 
Interpretation zu finden.

Veit D. schrieb:
> Hallo,
> vielleicht hilft dir die App Note 3212 "Getting Started with TCD"
> weiter.
> https://www.microchip.com/en-us/product/attiny3217#Tools%20And%20Software

Danke, das hilft. Die Sache funktioniert nun.

Das Event-System ist eigentlich eine tolle Sache. Man konfiguriert es in 
drei Schritten.
- Ein "Generator" auf einen Channel legen. Beispiel Portpin PB4
/* Asynchronous Channel 1 Generator Selection*/
1
EVSYS.ASYNCCH1 = EVSYS_ASYNCCH1_PORTB_PIN4_gc;
- Den Channel dem "User" zuweisen. Beispiel TCD0 Event 0 select
1
EVSYS.ASYNCUSER6 = EVSYS_ASYNCUSER6_ASYNCCH1_gc;
- Das Event-Register des Users für die gewünschte Reaktion 
konfigurieren.

Im Detail lassen sich nur bestimmte Kanäle von Generator zu User legen, 
aber wäre mit etwas genauerer Erklärung im DaBla nahezu trivial.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

schön das du es lösen konntest. Ich wusste nicht ob es mit dem 
Eventsystem oder TCD Probleme gibt. Egal welcher Art. Microchip hält 
viele App Notes bereit, leider teilweise über Controller Serien hinweg 
verteilt/verstreut. Es lohnt sich über alle neuen ATtiny und AVR Reihen 
mal reinzuschauen. Die Hardwareeinheiten sind ja immer ähnlich 
aufgebaut. Paar Bsp. hintereinander gibts hier.
https://forum.arduino.cc/t/nano-every-atmega4809-am-anfang-stand-der-anfang/701185
Viele Zusammenhänge was wie möglich ist mittels Eventsystem kann man 
übrigens im Headerfile rauslesen. Anhand der Bitkonfigurationen und 
Aufteilung der Abschnitte. Klar sollte das eigentlich besser aus dem 
Manual ersichtlich sein, naja, man muss sich irgendwie zu helfen wissen. 
;-)

: Bearbeitet durch User
von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Wulf D. schrieb:

> Ich hatte das schon mehr als überflogen. Ich halte die Erklärungen noch
> immer für stark verbesserungswürdig. Der TCD0 ist wohl immer ein "async
> user" im Sinne des Event-Systems.

Jepp, so könnte man das vielleicht zusammenfassen.

> Doof halt wenn da Sätze wie diese
> stehen:
>
1
> It is not possible to use asynchronous event detection and digital 
2
> filter at the same time.
3
>

Nein, das ist völlig korrekt, denn diese Aussage bezieht sich ja auf die 
allgemein verfügbaren Filter des Eventsystems und nicht auf die 
zusätzlich vorhandenen im Spezialfall des TCD. Also völlig korrekt.

> Andere Beispiele:
> - die beiden Event-Eingänge werden im TCD0-Kapitel mit "Input Event A"
> und "Input Event B" bezeichnet. Aber nur da.
> Im EVSYS-Kapitel stehen die mit "Event 0" und "Event 1", ebenso wie in
> den Headerfiles.

> - Mal heißt das unterste Bit im TCD-Eventregister (TCD0.EVCTRLA) CAPTEI,
> mal heisst es TRIGEI.
>

Naja, das ist tatsächlich alles etwas inkonsistent und das völlig ohne 
Not. Das hätte man sicher schöner machen können.

> Ich finde solche Inkonsistenzen nervig, kosten Zeit die richtige
> Interpretation zu finden.

Da bin ich voll bei dir.

von Veit D. (devil-elec)


Angehängte Dateien:

Lesenswert?

Hallo,

helfe mir einmal auf die Sprünge? Woher kommt das Bit "CAPTEI" in 
TCD0.EVCTRLA bei dir? Ich finde es nicht.

TRIGEI gibt es für TCD.
CAPTEI für TCB.

2 unterschiedliche Timer, 2 unterschiedliche Aufgaben.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Veit D. schrieb:
> Hallo,
>
> helfe mir einmal auf die Sprünge? Woher kommt das Bit "CAPTEI" in
> TCD0.EVCTRLA bei dir? Ich finde es nicht.
>
> TRIGEI gibt es für TCD.
> CAPTEI für TCB.
>
> 2 unterschiedliche Timer, 2 unterschiedliche Aufgaben.

Ahem, nö, da bin ich anderer Meinung. Die Aufgabe ist ja durchaus 
dieselbe. Da hätte man die Bits auch locker gleich benennen können, auch 
wenn sie zu unterschiedlichen Timern gehören. Wenn denn auch die Nummern 
der physischen Bits gleich sind, die sie repräsentieren, was hier ja der 
Fall ist.

Aber: Das ist Meckern auf hohem Niveau. Gegen teilweise obszönen 
Peripherie-Benennungs-Wallungen bei anderen Architekturen ist das bei 
den AVR8 doch immerhin noch wenigstens halbwegs konsistent und 
einheitlich. Gegenüber dem doch mitunter recht heftigen Wildwuchs bei 
den Classic-Teilen (vor allem bei den Tinys) ist es bei den modernen auf 
jeden Fall schon eindeutig besser geworden.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

gut, lassen wir so stehen.  :-)

von Wulf D. (holler)


Lesenswert?

Ja ok, sind wirklich zwei unterschiedliche Timer wo das untereste Bit 
mit CAPTEI bzw TRIGEI bezeichnet ist. Die Funktion ist gleich.
EDGE macht in beiden Timern auch das gleiche und ist gleich bennant: 
geht doch.

Die "Getting Started with ..." sind wirklich gut. Weiß auch nicht warum 
ich den zum TCD nicht fand.

Eine Sache klappt noch nicht: will dass der Timer nach dem Capture 
automatisch resettet und neu startet. Nach dem Text in Datenblatt sollte 
das funktionieren:
1
/* Example 22-4. Reset One Ramp Mode by Input Event Capture
2
In One Ramp mode, the counter can be reset by an input event capture. To achieve this, use input
3
event B and write 0x08 to the INPUTMODE bit field in the Input Control B (TCDn.INPUTCTRLB)
4
register.*/
5
TCD0.INPUTCTRLB = 0x08;

Habe ich auch gemacht, aber der läuft mir noch jedesmal in den Overflow, 
obwohl der da niemals ankommen dürfte.

von Ob S. (Firma: 1984now) (observer)


Lesenswert?

Wulf D. schrieb:

> Eine Sache klappt noch nicht: will dass der Timer nach dem Capture
> automatisch resettet und neu startet. Nach dem Text in Datenblatt sollte
> das funktionieren:
>
>
1
> /* Example 22-4. Reset One Ramp Mode by Input Event Capture
2
> In One Ramp mode, the counter can be reset by an input event capture. To 
3
> achieve this, use input
4
> event B and write 0x08 to the INPUTMODE bit field in the Input Control B 
5
> (TCDn.INPUTCTRLB)
6
> register.*/
7
> TCD0.INPUTCTRLB = 0x08;
8
>
>
> Habe ich auch gemacht, aber der läuft mir noch jedesmal in den Overflow,
> obwohl der da niemals ankommen dürfte.

Bleibt eigentlich nur zwei Fragen:

1) Bist du überhaupt im One-Ramp-Mode? Nur dafür wird diese Funktion 
versprochen.
2) Wie genau hast du sichergestellt, dass garantiert in jedem 
Timerzyklus mindestens ein Capture-Event auftritt?

von Wulf D. (holler)


Lesenswert?

Ob S. schrieb:

> Bleibt eigentlich nur zwei Fragen:
>
> 1) Bist du überhaupt im One-Ramp-Mode? Nur dafür wird diese Funktion
> versprochen.

Ja, das ist der default und den habe ich nicht verändert.

> 2) Wie genau hast du sichergestellt, dass garantiert in *jedem*
> Timerzyklus mindestens ein Capture-Event auftritt?

Habe hier einen kleinen Testaufbau mit einem Generator der die Events 
produziert.

Fehler habe ich gefunden, hatte den Inputmode nach dem ENABLE des TCD0 
gesetzt, was dann nicht übernommen wird. Hätte man im Datenblatt sehen 
können.

Jetzt habe ich es richtig gemacht, aber dann lese ich das 
CAPTUREB-Register immer mit 0x000. Hatte gehofft, dass vorm Reset des 
Counters noch ein Übertrag ins CAPTURE-Register erfolgt. Ist offenbar 
nicht so.

Dann bleibt vermutlich nur ein Workaround, dass ich die Differenz der 
CAPTURE-Werte von aufeinander folgenden Ereignissen rechne. Geht auch.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

soviel habe ich mit TCD noch nicht gemacht. Denkbar wäre, wenn ein 
Capture Ereignis eintritt, dass CaptureA/CaptureB Register auszulesen. 
Das sollte mit einer Interrupt Routine für das "Ereignis Flag" machbar 
sein. Zumindestens macht der Text zu Kapitel CAPTURE A und CAPTURE B die 
Hoffnung. 22.5.19.
Sollte ähnlich funktionieren wie beim capturen mit TCB.

Was möchtest du denn überhaupt mit TCD machen?

: Bearbeitet durch User
von Wulf D. (holler)


Lesenswert?

Hallo,
ich denke mal, dass der TCD in erster Linie zur Erzeugung von 
Steuersignalen für Motorsteller und Schaltregler ausgelegt ist. Dafür 
bietet der ja beste Vorraussetzungen.

Ist genau so wie du schreibst umgesetzt, in der Event-ISR 
(TCD0_TRIG_vect) werden die CAPTURE Register gelesen. Die werden 
übrigens nach dem Triggern so lange eingefroren, bis man die ausliest.
Das Trigger-Event kommt, der entsprechende Interrupt wird ausgelöst, 
aber im CAPTURE-Register steht nichts (mehr) drin.

Aber wie gesagt, ich kann problemlos auf den automatischen Counter-Reset 
verzichten und Differenzen bilden. Muss nur eine Fallunterscheidung 
wegen Counter-Überlauf treffen.

Ich will mit dem TCD über Hallsensoren, die an zwei Portpins hängen, 
u.a. die Drehzahl einer Maschine bestimmen. Gleichzeitig soll einer der 
Hallsensoren den TCA starten, der drehzahlabhängig weitere Steuersignale 
mit zeitlichem Abstand erzeugt.

Ich hatte das früher schon mal mit einem ATTiny85 gemacht, aber da 
benötigen einige Trigger SW dazwischen, so dass es unerwünscht jittert. 
Dessen 8-Bit Timer-Auflösung ist auch grenzwertig.

Mit dem ATtiny1616 sollte es rein signalbasiert funktionieren, außerdem 
verspreche ich mir von den Hallsensoren mehr Präzision als von einem 
zuvor verwendeten Induktivgeber.

Habe den TCD verwendet, weil der im Gegensatz zum TCB einen Vorteiler 
hat. Und der TCA bereits in der HW mit seinem Output Compare-Ausgang WO0 
verschaltet ist.
Wäre mit aktuellem Wissensstand wahrscheinlich umgekehrt einfacher 
umzusetzen.

von Georg M. (g_m)


Lesenswert?

Datasheet:
"The Timer/Counter type D (TCD) is a high-performance waveform 
generator...
... can run on a clock that is asynchronous to the peripheral clock...
... generates two independent outputs with optional dead-time."

TCB: "measurement of digital signals"

von Veit D. (devil-elec)


Lesenswert?

Hallo,

das wissen wir, dennoch kann man paar Dinge ausprobieren.

von Wulf D. (holler)


Lesenswert?

Hätte zur Drehzahlmessung sicher auch den TCB nehmen können. Hatte mich 
vom fehlenden Vorteiler abschrecken lassen, aber man kann den Vorteiler 
vom TCA einspannen. Dank 16 Bit Auflösung der Zähler ginge das auch.

Wie so oft, viele Wege führen nach Rom.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

@ Wulf

liest du die Capture Register A/B immer erst mit dem Low Byte und dann 
High Byte aus? Wenn beide gelesen werden sollen, dann erst von beiden 
das Low Byte, dann A High, dann B High.

von Wulf D. (holler)


Lesenswert?

Hier die ISR:
1
ISR (TCD0_TRIG_vect)
2
{
3
dummy = TCD0_CAPTUREB;
4
if (dummy>captalt) capt = dummy-captalt;
5
else capt= 0x1000+dummy-captalt;
6
captalt=dummy;
7
states |= (1<<s_drehz);
8
TCD0.INTFLAGS = TCD_TRIGB_bm;  
9
}
Nach dem ersten Lesezugriff wird das Capture-Register zurückgesetzt, 
deshalb muss man es retten (dummy). Das Differenz-Ergebnis steht nach 
der Fallunterscheidung in uint16_t capt. Alle Variablen sind uint16_t.

von Georg M. (g_m)


Lesenswert?

> vom fehlenden Vorteiler

Der ATtiny1616 hat 2x TCB.

Und beim ATtiny1626 kann man die sogar kaskadieren.
(Datasheet: " • 32-bit capture")

von Veit D. (devil-elec)


Lesenswert?

Hallo,

@ Wulf
okay, wenn das klappt dann ist gut. Ich dachte es hätte noch ein Problem 
gegeben. Ich wünsche noch viel Spass am ggf. tüfteln mit den neuen 
ATtinys.

von Georg M. (g_m)


Lesenswert?

AVR32EA32-I/RXB
VQFN-32 5×5mm
Two 16-bit Timer/Counters type A (TCA)
Four 16-bit Timer/Counters type B (TCB)
(DigiKey: 1,04 € +  MwSt.)

von Wulf D. (holler)


Lesenswert?

Funktioniert jetzt alles. Die neueren AVR machen schon Spaß bei harten 
Echtzeitanwendungen und kosten dabei praktisch nichts.

Das UPDI Debug Interface ist auch ein Fortschritt. An die QFN Gehäuse 
kann man sich gewöhnen, wobei es auch Alternativen gibt.

Nur die Qualität der Datenblätter war gefühlt früher besser, da 
konsistenter und ausführlicher.

von Veit D. (devil-elec)


Lesenswert?

Hallo,

das Thema Datenblatt scheint im Forum sehr unterschiedliche Auffassungen 
zu haben. :-)  Ich finde bspw. die Zusammenfassung aller Register je 
Hardwareinheit mit allen Bits sehr gut. Den Screenshot von hier meine 
ich. Beitrag "Re: AVR ATtiny Serie 1: Input Capture TCD0"
Kennt man die Einheit benötigt man fast nur noch diese Tabelle.
In den alten Manuals sind die Register über viele Seiten verstreut ohne 
jede Zusammenfassung der Hardwareinheit. Da musste man alles 
zusammensuchen. Die Beschreibung der Einheiten könnte durchaus mit paar 
Sätzen mehr ausführlicher sein. Das stimmt wiederum. Mit allen für und 
wider lese ich lieber die neuen statt alten Manuals. Wie gesagt, dass 
scheint im Forum Geschmackssache zu sein und eben so viel Gewohnheit. 
Bis auf den fehlenden kompletten Satz an Prescalern für TCB habe ich an 
den neuen Controllern nicht auszusetzen.

Wegen den RegisterNamen und BitNamen. Wir müssten ein Forum eigenes 
Headerfile schreiben. So wie uns das passt.  :-)  :-)  :-)
Die Marktmacht des Forums setzt sich durch. :-)  :-)  :-)
Quasi ein Fork der zur Außenwelt nicht kompatibel ist.

Jetzt höre ich auf. :-)

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.