AVRxDB und Verwandte - alle TCBs kaskadieren

OP #7597320
Lesenswert?

Hallo,

übrigens, was ich einmal die Runde werfen möchte ist, man kann bspw. beim AVRxDB Controller nicht nur 2 TCB kaskadieren. Das suggeriert zwar erstmal das Manual, weil von 32Bit Kaskadierung die Rede ist, aber man kann alle verfügbaren TCBs kaskadieren.

Bsp. mit 3 TCBs, 48Bit Counter, den jeweilige Overflow Event bekommt der nächste TCB als sein Zähleingang per Event Channel verpasst. Und alle TCBs hängen noch auf dem gleichen Event Channel vom eigentlichen Takteingang damit alle zum gleichen Zeitpunkt ihre Zählerwerte in die Register speichern. Hier wäre Pin PA4 der Takteingang für die gesamte Kaskade.

1
void initEventSystem (void)
2
{
3
  EVSYS.CHANNEL0 = EVSYS_CHANNEL0_PORTA_PIN4_gc;    // set Pin PA4 as input event
4
  EVSYS.USERTCB0CAPT = EVSYS_USER_CHANNEL0_gc;      // Connect user to event channel 0
5
  EVSYS.USERTCB1CAPT = EVSYS_USER_CHANNEL0_gc;      //
6
  EVSYS.USERTCB2CAPT = EVSYS_USER_CHANNEL0_gc;      //
7
  
8
  EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
9
  EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
10
  
11
  EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
12
  EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;
13
}
14

15
void initTCB (void)
16
{
17
  // *** LSB 16-Bit *** //
18
  TCB0.CTRLA = TCB_CLKSEL_DIV1_gc;     // CLK_PER divider
19
  TCB0.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
20
  TCB0.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
21
  TCB0.INTCTRL = TCB_CAPT_bm;          // Enable Capture interrupt
22

23
  // *** 1. MSB 16-Bit *** //
24
  TCB1.CTRLA = TCB_CASCADE_bm | TCB_CLKSEL_EVENT_gc; 
25
  TCB1.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
26
  TCB1.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
27

28
  // *** 2. MSB 16-Bit *** //
29
  TCB2.CTRLA = TCB_CASCADE_bm | TCB_CLKSEL_EVENT_gc; 
30
  TCB2.CTRLB = TCB_CNTMODE_FRQPW_gc;   // Capture Mode
31
  TCB2.EVCTRL = TCB_CAPTEI_bm;         // Enable Event Input and positive Edge
32
  
33
  // einschalten
34
  TCB0.CTRLA = TCB0.CTRLA | TCB_ENABLE_bm;  // Enable TCB0
35
  TCB1.CTRLA = TCB1.CTRLA | TCB_ENABLE_bm;  // Enable TCB1
36
  TCB2.CTRLA = TCB2.CTRLA | TCB_ENABLE_bm;  // Enable TCB2
37
}
38

39
ISR(TCB0_INT_vect) // alles auslesen
40
{    
41
  //  hier entsprechend auslesen
42
  TCB0.CNT;       // read out CNT first, then CCMP
43
  TCB1.CNT;          
44
  TCB2.CNT;   
45
  TCB0.CCMP;
46
  TCB1.CCMP;
47
  TCB2.CCMP;
48
  TCB0.INTFLAGS = TCB_CAPT_bm;   // Clear the interrupt flag
49
}
OP #7598058
Lesenswert?

Gerhard H. schrieb:

Interessante Info. Der Interrupt für TCB0 löst dann beim 48Bit Overflow aus?

Ein Overflow löst hier keinen Interrupt aus. Weil bei keinem Timer der Overflow Interrupt aktiviert ist. Es ist nur der Capture Interrupt von TCB0 aktiviert. Zeile 21. Es wird nur das Overflow Ereignis an den nächsten Timer weitergereicht. Oder man könnte einen Overflow Interrupt in Software pollen ohne Overflow ISR. Hier aber nicht sinnvoll. Es kommt hier nur auf das Eingangssignal an was man vermessen möchte. In dem Fall mit der Konfig die steigende Flanke. Wenn es hier zu einem Overflow der 48 Bit kommen würde, würde man das nicht mitbekommen, dann wäre der Zählumfang zu kurz. Wenn man einen Überlauf überwachen möchte könnte man auf den Overflow vom letzten (höchstwertigen) Timer pollen oder dessen Overflow Interrupt aktivieren. Vielleicht hilft es auch zu wissen das die ISR von TCBn eine Sammel-ISR ist. Wenn man beide Interrupts aktivieren würde und man müsste wissen welcher ausgelöst hat, müsste man das in der ISR abfragen.

(Firma: 1984now) #7598066
Lesenswert?

Veit D. schrieb:

Ob S. schrieb:

Nein, der 48bit-Overflow ist natürlich der von TCB2. Schau dir doch einfach die Verkettung an, die ist: TCB0->TCB1->TCB2.

Falsch.

Wieso meinst du, das wäre falsch?

Da steht's doch:

1
  EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
2
  EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
3

4
  EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
5
  EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;
OP #7598083
Lesenswert?

Ob S. schrieb:

Wieso meinst du, das wäre falsch?

Da steht's doch:

1
>   EVSYS.CHANNEL3 = EVSYS_CHANNEL3_TCB0_OVF_gc;      //
2
>   EVSYS.USERTCB1COUNT = EVSYS_USER_CHANNEL3_gc;
3
> 
4
>   EVSYS.CHANNEL4 = EVSYS_CHANNEL4_TCB1_OVF_gc;      //
5
>   EVSYS.USERTCB2COUNT = EVSYS_USER_CHANNEL4_gc;
6
>

Ich will mich hier nicht streiten und nicht verkomplizieren. Original bezog sich die Nachfrage auf den 48Bit Overflow Interrupt auf TCB0, so habe ich das verstanden, der jedoch bei keinem Timer aktiviert ist und damit auch in der TCB0 ISR nicht auslösen kann. In der TCB0 ISR löst nur der Capture Interrupt aus. Die gezeigten Codezeilen betrifft nur das Eventsystem für die Kaskadierung.

(Firma: 1984now) #7598098
Lesenswert?

Veit D. schrieb:

Ich will mich hier nicht streiten und nicht verkomplizieren. Original bezog sich die Nachfrage auf den 48Bit Overflow Interrupt auf TCB0, so habe ich das verstanden

Genau. Und da isser eben definitiv falsch, weil sich eben aus der Verkettung ergibt, dass, wenn überhaupt, nur der Overflow von TCB2 in Frage kommt, um den 48-Bit Übertrag mitzubekommen.

Dass der dazu auch aktiviert werden muss und dass in der ISR verzweigt werden muss, weil es halt nur einen Vector für TCB2 gibt, steht außer Frage und war nie Thema der Diskussion.

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