Hallo zusammen,
irgendwie habe ich ein (programmiertechnisches?) Problem mit dem
RTTC-Interrupt am AT91SAM7x256.
Ausgangssituation:
Ein Sys-Interrupt, der WDT, PIT, RTTC, DBGU etc. bedient.
PIT läuft mit 10ms Periode, RTCC soll mit 1s Periode laufen (und einen
SW-Counter hochzählen). DBGU bedient eine kleine Kommandozeilen-SHell
via RS232.
1 | void SYS_ISR(void)
|
2 | {
|
3 | // System Timer
|
4 | WDT_ISR();
|
5 | PIT_ISR();
|
6 |
|
7 | // Real-Time Clock
|
8 | RTC_ISR();
|
9 |
|
10 | // Power Management Controller
|
11 | PMC_ISR();
|
12 |
|
13 | // Memory Controller
|
14 | EFC_ISR();
|
15 |
|
16 | // Debug Unit
|
17 | DBGU_ISR();
|
18 | }
|
Alles inline-Funktionen.
Wenn ich den Sys-ISR als POSITIVE_EDGE triggere (wie in so ziemlich
allen Beispielen, die ich gefunden habe), dann wird der Interrupt nach
15-20min gar nicht mehr aufgerufen. Die Zeit läßt sich verkürzen, wenn
ich fröhlich einen PIO-Interrupt flackern lasse, ansonsten ist sie auch
nicht 100%if reproduierbar.
Wenn ich die Sys-ISR als HIGH_LEVEL triggere, dann funktioniert DBGU und
PIT einwandfrei, RTCC wird allerdings 3x pro Sekunde getriggert, aber
anscheinend immer schnell hintereinander (sehe ich am SW-Counter). Kann
also kein Problem mit einem falschen Prescaler sein.
1 | inline void RTC_ISR(void)
|
2 | {
|
3 | // Status lesen -> IRQ zurücksetzen
|
4 | unsigned long Status = *AT91C_RTTC_RTSR;
|
5 | if(Status==0) { return; }
|
6 |
|
7 | // Status auswerten
|
8 | if(Status & AT91C_RTTC_RTTINC) { // Timer inkrement
|
9 | InkrementTime();
|
10 | if(RTC_callback) { RTC_callback(); }
|
11 | }
|
12 | if(Status & AT91C_RTTC_ALMS) { // Alarm
|
13 | }
|
14 | }
|
Den callback habe ich schon probehalber auskommentiert, ändert nichts am
Symptom. Habe auch schon versucht, beim Timer-Inkrement das IEN-Bit im
Mode Register zurückzusetzen und wieder zu setzen. Hat auch nichts
gebracht.
Hat jemand eine tolle Idee, was ich falsch mache?
AndyK