Forum: Mikrocontroller und Digitale Elektronik [ARM] ATSAMD09 WDT und TC Problem


von Alex Richard Moll (Gast)


Angehängte Dateien:

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

von Helmut (Gast)


Lesenswert?

Hi,
wie ist der WDT definiert?

von Alex Richard Moll (Gast)


Lesenswert?

Helmut schrieb:
> wie ist der WDT definiert?
1
//GCLK(2) is automatically set on ATSAMD09 (see Datasheet) with the internal 32khzULP Oscillator 
2
  WDT->CONFIG.reg = WDT_CONFIG_PER(WDT_CONFIG_PER_16K_Val);
3
  WDT->CTRL.reg = WDT_CTRL_ENABLE;

von Stored B. (Firma: drx) (umbrecht)


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

von Stored B. (Firma: drx) (umbrecht)


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

von Alex Richard Moll (Gast)


Angehängte Dateien:

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

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.