[ARM] ATSAMD09 WDT und TC Problem

Gast #7031830
Lesenswert?

Ich grüße euch!

Ich habe zwei Probleme bei denen es hängt. Ich bedanke mich für eure 
Hilfe!

Ich habe einen Timer Konfiguriert der bei einem Match einen Ausgang 
setzen soll, z.B. PA05 (TC1/WO[1] (MUX: E)).
Timer selbst läuft aber nicht die Pinumschaltung. Ich denke ich habe den 
Pin falsch Konfiguriert, ich finde den Fehler aber nicht, vielleicht 
seht ihr etwas?
1
void timer_init(void)
2
{
3
  PM->APBCMASK.reg |= PM_APBCMASK_TC1;
4
  
5
  GCLK->GENDIV.reg = GCLK_GENDIV_ID(4) | GCLK_GENDIV_DIV(1024);
6
  GCLK->GENCTRL.reg = GCLK_GENCTRL_SRC(GCLK_GENCTRL_SRC_OSC8M_Val) |  GCLK_GENCTRL_GENEN | GCLK_GENCTRL_ID(4);
7
  GCLK->CLKCTRL.reg = GCLK_CLKCTRL_ID(GCLK_CLKCTRL_ID_TC1_TC2_Val) | GCLK_CLKCTRL_CLKEN | GCLK_CLKCTRL_GEN(4);
8
  
9
  TC1->COUNT16.CC[0].reg = TC_COUNT16_CC_CC(1000); //1ms -- changed in programm!
10

11
  //while (TC1->COUNT16.STATUS.bit.SYNCBUSY) {}
12
  
13
  //TEST for TC Output
14
  TC1->COUNT16.EVCTRL.reg = TC_EVCTRL_MCEO0;
15
  PORT->Group[0].DIRSET.reg |= (1 << TCPIN);
16
  PORT->Group[0].PINCFG[TCPIN].reg |= PORT_PINCFG_PMUXEN;
17
  PORT->Group[0].PMUX[TCPIN>>1].bit.PMUXO = PORT_PMUX_PMUXO_E_Val; //PIN is odd / ungerade
18
  
19
  TC1->COUNT16.CTRLA.reg = TC_CTRLA_PRESCALER(TC_CTRLA_PRESCALER_DIV1_Val) | TC_CTRLA_WAVEGEN(TC_CTRLA_WAVEGEN_MFRQ_Val) | TC_CTRLA_ENABLE;
20

21
//Interrupt enable
22
TC1->COUNT16.INTENSET.reg = TC_INTENSET_MC0;
23
NVIC_EnableIRQ(TC1_IRQn);
24
}


Zur zweiten, ich resette in der main schleife den WDT. Mir ist 
aufgefallen das dieser Befehl ca. 300us dauert, warum ist das so? Meiner 
Meinung nach habe ich dazu im Datenblatt nichts gelesen.. Egal ob der 
WDT aus oder an ist, die Dauer bleibt gleich. Ich habe dazu mal zwei 
Bilder angehängt, in denen man die Pulse mit dem WDT Reset Befehl sieht 
und ohne.
Ohne den WDT Reset dauert ein kompletter Pin Toggle keine 3us.

Der Code dazu zum Tracken sieht wie folgt aus,
Mit WDT Reset:
1
for(uint32_t x = 0; x < 20000; x++) { PORT->Group[0].OUTSET.reg |= (1 << SERVO_PULSE_PIN); WDT->CLEAR.reg = 0xA5;  PORT->Group[0].OUTCLR.bit.OUTCLR = (1 << SERVO_PULSE_PIN); }

Ohne WDT Reset:
1
for(uint32_t x = 0; x < 20000; x++) { PORT->Group[0].OUTSET.reg |= (1 << SERVO_PULSE_PIN); PORT->Group[0].OUTCLR.bit.OUTCLR = (1 << SERVO_PULSE_PIN); }

Die schleifen werden separat über Uart aufgerufen um die Ausgänge 
einfacher Analysieren zu können.
Ich hänge dazu das Assembler file an. Die schleife ohne WDT wird an 
Adresse 5d6 aufgerufen und die andere bei 5f0.

Beste Grüße
Moll
Angehängte Dateien:
(Firma: drx) #7032747
Lesenswert?

Alex Richard Moll schrieb:
> Mit WDT Reset

Die Lösung / der Grund ist Relativ einfach:
1
if(!(WDT->STATUS.reg & WDT_STATUS_SYNCBUSY)) WDT->CLEAR.reg = 0xA5;

Durch die vorherige Abfrage des SYNC Bits fällt die Zykluszeit auf unter 
10µs. Im Falle das SYNC = 0 ist, kostet es mich in meinem Test 0,7us 
mehr. Kompletter Zyklus:
1
SYNC = 0 : 5µs 
2
SYNC = 1 : 4,3µs.

Das Gilt übrigens für einige SAMD reihen bzw. Registerzugriffe.

BG
Umbrecht
(Firma: drx) #7033158
Lesenswert?

Alex Richard Moll schrieb:
> Timer Konfiguriert

Folgendes musst du zusätzlich konfigurieren:
1
PORT->Group[0].WRCONFIG.reg = (uint32_t)( PORT_WRCONFIG_WRPINCFG|
2
  PORT_WRCONFIG_WRPMUX|
3
  PORT_WRCONFIG_PINMASK(1<<TCPIN)|
4
  PORT_WRCONFIG_PMUXEN|
5
  PORT_WRCONFIG_PMUX(TCPIN+1));


Eine genauere Beschreibung kannst du hier finden: 
https://microchipdeveloper.com/32arm:saml10-timer-counter

BG
Umbrecht
Gast #7033369
Lesenswert?

Danke dir, hat soweit funktioniert.

Mir stellt sich aber jetzt die Frage wieso die Zyklen manchmal 
unterschiedlich sind..
Habe Count16.CC auf 0 eingestellt, ein Positiver Impuls dauert 125ns, 
ein Negativer Impuls dauert 125ns. Hin und wieder habe ich einen 
Positiven Impuls von 375ns dabei, einer hat sogar 1µs.. Ca. alle 60µs 
tritt eine solche Verzögerung ein..
Es sind keine Interrupts aktiv. Auch der Timer Interrupt ist aus.

Vielleicht weißt du oder jemand anders eine Antwort.
Vielen dank!

Beste Grüße
Moll
Angehängte Dateien:

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