So langsam hasse ich den AT91SAM7A2. Ich möchte eigentlich nur den
simple timer benutzen, um eine LED blinken zu lassen und es geht nicht.
Also die Interrupts funktionieren. Ich habe zum Ausprobieren den
externen Interrupt IRQ1 programmiert. Der ist mit einem Button
verbunden. Den kann ich mehrmals drücken und es gibt keine Probleme, die
LED geht an und aus. Nun versuche ich das gleiche mit dem simple tiemr
zu machen, streng nach Datenblatt:
1 | // configure interrupt
|
2 |
|
3 | // disable interrupt
|
4 | GIC->IDCR = GIC_ST0;
|
5 |
|
6 | // set source mode
|
7 | GIC->SMR[GIC_IDX_ST0] = 0;
|
8 |
|
9 | // set interrupt handler
|
10 | GIC->SVR[GIC_IDX_ST0] = (AT91_REG)ISR_Timer;
|
11 |
|
12 | // clear interrupt
|
13 | GIC->ICCR = GIC_ST0;
|
14 |
|
15 | // enable timer
|
16 | ST0->ECR = ST_ST;
|
17 |
|
18 | // software reset to initialize the timer
|
19 | ST0->CR = ST_CR_SWRST;
|
20 |
|
21 | // wait a little bit
|
22 | for (idx = 0; idx < 16; idx++)
|
23 | asm volatile ("NOP");
|
24 |
|
25 | // adjust timer: 1 tick per second
|
26 | ST0->PR0 = ST_PR_PRESCALAR(2) | ST_PR_AUTOREL | ST_PR_SYSCAL(74);
|
27 | ST0->CT0 = 50000;
|
28 |
|
29 | // enable channel end interrupt
|
30 | ST0->IER = ST_IR_CHEND0;
|
31 |
|
32 | // enable interrupt
|
33 | GIC->IECR = GIC_ST0;
|
34 |
|
35 | // start timer
|
36 | ST0->CR = ST_CR_CHEN0;
|
In der Interrupt-Routine lösche ich, wie im Datenblatt beschrieben, das
Interrupt Statusbit:
1 | // acknowledge interrupt by clearing status bit
|
2 | ST0->CSR = ST_CSR_CHEND0;
|
Aber trotzdem wird die Interrupt-Routine nur einmal aufgerufen, dann nie
wieder. Wie schon gesagt, mit dem anderen Interrupt funktioniert es, mit
dem simple timer nicht. Ich hab mir schon die Counter Register des Timer
angeschaut, die werden ordnungsgemäß runter gezählt. Aber der Interrupt
kommt nur einmal. Hat jemand eine Idee? (Falls nicht, dann werde ich die
anderen Timer verwenden.)