Forum: Mikrocontroller und Digitale Elektronik Atmel SAM3s: gated Timer soll ADC triggern


von Michael H. (michael_h45)


Angehängte Dateien:

Lesenswert?

Hallo,

Ich hab ein Problem mit einem Atmel SAM3S4B. Datenblatt: 
http://www.atmel.com/Images/doc6500.pdf
Die Timer sind ab Seite 743 zu finden.

Folgendes Vorhaben:
- Timer 0 erzeugt ein Signal mit ~1ms Periode und 4 * 5us an-Zeit.
- in diesen 4 * 5us wird die Clock für Timer 2 freigegeben.
- Timer 2 macht dann 4 Perioden zu je 5us und triggert jedes Mal den 
ADC.
- (Timer 0 und 2 haben den selben Prescaler und sind synchronisiert).

Ich will also alle 1ms 4 ADC-Shots. Danach einen Interrupt.
Das klappt auch mehr oder weniger gut. Immer die erste Periode von Timer 
0 erzeugt einen Puls zu wenig an Timer 2. Und ich verstehe nicht, warum.
Anbei Aufzeichnungen von meinem Logcanalyzer.
led_rt: active low im Interrupt - also nach 4 ADC-Shots.
TIOA2: Trigger-Signal an den ADC.

1.png: der gesamte Ablauf.
Bei den Pulsen im gelben Kreis beginnt der ganze Ablauf. Die Pulse davor 
sind vom vorherigen Ablauf und uninteressant.
Hier wird Timer 0 angestoßen und löst das erste mal beim orangen Kreis 
aus.
Beim organgen Kreis würde ich dann auch den ersten Interrupt erwarten. 
Wie in 2.png und 3.png zu sehen ist, passiert das aber nicht, weil der 
TIOA2 den ADC nur 3 mal triggert und nicht 4 mal.
Erst ab dem zweiten Auslösen des Timers 0 läuft alles wie gewollt - zu 
sehen in 4.png.

Die eigentliche Frage: warum hat der Timer 2 beim ersten Auslösen von 
Timer 0 nur drei Perioden anstatt vier.

Der Code zum Timer-Setup:
1
#define ADCSHOTS    4
2
3
PMC_ENABLE_PC(TC0IRQ);
4
PMC_ENABLE_PC(TC2IRQ);
5
6
/*
7
 * timer2 as the adc trigger source
8
 * burst mode for ADC_SHOTS samples at 200kHz
9
 */
10
TCB0_BASE->TC[2].TC_CMR = TCMCK2 | BurstXc2 | WAVE | CPCTRG | \
11
    (ClearOutput << B_ACPA) | (SetOutput  << B_ACPC);
12
TCB0_BASE->TC[2].TC_RC = sys_clock / 2 / 200000;
13
TCB0_BASE->TC[2].TC_RA = TCB0_BASE->TC[2].TC_RC / 2;
14
15
/*
16
 * timer0 as the tc2 gate
17
 * 1000Hz sampling rate
18
 */
19
TCB0_BASE->TC[0].TC_CMR = TCMCK2 | BurstNone | WAVE | CPCTRG | \
20
    (SetOutput << B_ACPA) | (ClearOutput  << B_ACPC);
21
TCB0_BASE->TC[0].TC_RC = sys_clock / 2 / 1000;
22
TCB0_BASE->TC[0].TC_RA = TCB0_BASE->TC[0].TC_RC - (TCB0_BASE->TC[2].TC_RC * ADC_SHOTS);
23
24
/* gate clk of tc2 by tc0 */
25
TCB0_BASE->TC_BMR = TIOA0XC2;

Gestartet werden die Timer damit:
1
di();
2
TCB0_BASE->TC[0].TC_CCR = CLKEN;
3
TCB0_BASE->TC[2].TC_CCR = CLKEN;
4
TCB0_BASE->TC_BCR = TCSYNC;
5
ei();

Grüße,
Michael

von Michael H. (michael_h45)


Angehängte Dateien:

Lesenswert?

Ich hab jetzt noch eine Leitung zum TIOA0 gefädelt.
Es scheint, als wären die beiden Timer nicht synchron. Sie werden aber 
über das Block_Control_Register gleichzeitig mit der gleichen Clock 
getriggert. Ein Trigger macht einen Zähler-Reset und Clock-Enable.

Und noch ein Nachtrag zum Ausgangspost: die Timer laufen völlig 
unbeeinflusst, bis der Interrupt n Mal ausgeführt wurde. Dann erst 
werden die Timer wieder angehalten und zurückgesetzt.
Es werden keine Register von Timern geschrieben und nicht mal gelesen, 
während die Messung läuft.

von Michael C. (Gast)


Lesenswert?

Hm ich würd an Deiner Stelle mal die AT91support hotline anschreiben, 
ich hab bei meinen Problemchen immer recht schnell eine Antwort 
bekommen. Kannst gern das Ergebnis hier Posten, ich verwende zwar SAM3A 
aber hatte bisher noch nicht mit derart Timern gearbeitet.

von Michael H. (michael_h45)


Lesenswert?

Falls jemand diesen Thread über eine Suche findet:
Heute die Bestätigung bekommen: das wird ein neues Errata...
Der Synchronisierungs-Block vorm Clock-Eingang hat einen Fehler, der in 
den ersten paar µs Pulse verschluckt.

von Michael C. (Gast)


Lesenswert?

Hi Michael,

ist ein Workaround bekannt? Kannst Du bitte die Antwort posten?

Vielen Dank!
Michael

von Michael H. (michael_h45)


Lesenswert?

Sie haben "empfohlen", DMA nicht zu verwenden und einen Timer-Interrupt 
aufzusetzen, anstatt den Timer triggern zu lassen.

Das allerdings für meinen Anwendungsfall. Im nächsten Datenblatt-Release 
kann auch etwas anderes stehen.

Nachdem das ganze auch schon ein Workaround für das 
ADC-Sequencing-Errata ist, werde ich auf einen anderen Prozessor 
umsteigen.
Meine Stromverbrauchsanforderungen lassen das ganze Interrupt-Gehampele 
nicht zu.

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.