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.)