Forum: Mikrocontroller und Digitale Elektronik AT91SAM7X Interrupt Handler wird nur einmal aufgerufen


von Kristof K. (Firma: HS Bochum) (kosh)


Lesenswert?

Hallo,

ich kämpfe nun schon ewig an diesem Problem und hoffe das ich hier neue 
Anregungen/Lösungen bekomme. Ich arbeite auf einem eigenen Board mit 
einem AT91SAM7X512 und benutze im Moment CAN zum empfangen von Daten und 
USB HID zum senden an den PC. Das soll mal ein CAN-Gamepad werden.

Can Initialisierung und Interrupt handler scheinen zu funktionieren, 
denn eine Nachricht wird korrekt bearbeitet. Das [b}Problem[/b] liegt 
darin das danach absolute Funkstille herrscht. Keine weitere Nachricht 
löst einen Interrupt aus. Das SR Register ist clear, CAN und Interrupts 
sind eingeschaltet.
1
void can_init(void){
2
  printf("--Init CANBUS\r\n");
3
  //enable Pins for CAN
4
  AT91C_BASE_PIOA->PIO_ASR = AT91C_PA19_CANRX|AT91C_PA20_CANTX;
5
  AT91C_BASE_PIOA->PIO_PDR = AT91C_PA19_CANRX|AT91C_PA20_CANTX;
6
  //Enable Peripheral Clock in PMC (Seite 520)
7
  AT91C_BASE_PMC->PMC_PCER = (1 << AT91C_ID_CAN);    //Enable Peripheral Clock
8
  AT91C_BASE_AIC->AIC_IDCR = (1 << AT91C_ID_CAN);   //Disable Interrupt
9
10
  AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_MB0|AT91C_CAN_MB1|AT91C_CAN_MB2|AT91C_CAN_MB3
11
              |AT91C_CAN_MB4|AT91C_CAN_MB5|AT91C_CAN_MB6;      //Disable Mailbox 0 Interrupt
12
  AT91C_BASE_AIC->AIC_SMR[AT91C_ID_CAN] = 0x47;        //Set prior = 7 + high level sensitive
13
  AT91C_BASE_AIC->AIC_SVR[AT91C_ID_CAN] = (unsigned int) CANIrqHandler;
14
  //Enable CAN Controller Interrupt in the AIC (Seite 520)
15
  AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_CAN);    //Clear Interrupt
16
  AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_CAN);     //Enable Interrupt
17
18
  //Set Baudrate
19
  AT91C_BASE_CAN->CAN_BR = CAN_BR_500K;
20
  //enable WAKEUP Int
21
  //AT91C_BASE_CAN->CAN_IER = AT91C_CAN_WAKEUP;
22
  //enable Error Ints
23
  //AT91C_BASE_CAN->CAN_IER = AT91C_CAN_AERR | AT91C_CAN_CERR;// |AT91C_CAN_SERR;//| AT91C_CAN_BERR
24
25
  // Configure Mailbox 0, RX
26
  AT91C_BASE_CAN_MB0->CAN_MB_MAM    = 0x7FF << 18;   //accept all -> 0x000
27
  AT91C_BASE_CAN_MB0->CAN_MB_MID    = 0xC2 << 18;
28
  AT91C_BASE_CAN_MB0->CAN_MB_MMR    = AT91C_CAN_MOT_RXOVERWRITE;
29
30
  // Configure Mailbox 1, RX
31
  AT91C_BASE_CAN_MB1->CAN_MB_MAM    = 0x7FF << 18;   //accept all -> 0x000
32
  AT91C_BASE_CAN_MB1->CAN_MB_MID    = 0x310 << 18;
33
  AT91C_BASE_CAN_MB1->CAN_MB_MMR    = AT91C_CAN_MOT_RXOVERWRITE;
34
35
  // Configure Mailbox 2, RX
36
  AT91C_BASE_CAN_MB2->CAN_MB_MAM    = 0x7FF << 18;   //accept all -> 0x000
37
  AT91C_BASE_CAN_MB2->CAN_MB_MID    = 0x90 << 18;
38
  AT91C_BASE_CAN_MB2->CAN_MB_MMR    = AT91C_CAN_MOT_RXOVERWRITE;
39
40
  // Configure Mailbox 3, RX
41
  AT91C_BASE_CAN_MB3->CAN_MB_MAM    = 0x7FF << 18;   //accept all -> 0x000
42
  AT91C_BASE_CAN_MB3->CAN_MB_MID    = 0x23A << 18;
43
  AT91C_BASE_CAN_MB3->CAN_MB_MMR    = AT91C_CAN_MOT_RXOVERWRITE;
44
  //ToDo
45
  // Enable WAKEUP RAUSGENOMMEN!!
46
  //Interrupt Enable
47
  AT91C_BASE_CAN->CAN_IER = AT91C_CAN_MB0|AT91C_CAN_MB1|AT91C_CAN_MB2|AT91C_CAN_MB3;
48
                //|AT91C_CAN_MB4|AT91C_CAN_MB5|AT91C_CAN_MB6|AT91C_CAN_MB7|AT91C_CAN_MB8
49
                //|AT91C_CAN_AERR|AT91C_CAN_CERR//AT91C_CAN_SERR
50
                //|AT91C_CAN_BERR;
51
                //|AT91C_CAN_FERR;
52
                //|AT91C_CAN_WAKEUP;
53
  // Clears the MRDY Signal
54
  AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;
55
  AT91C_BASE_CAN->CAN_MB1.CAN_MB_MCR = AT91C_CAN_MTCR;
56
  AT91C_BASE_CAN->CAN_MB2.CAN_MB_MCR = AT91C_CAN_MTCR;
57
  AT91C_BASE_CAN->CAN_MB3.CAN_MB_MCR = AT91C_CAN_MTCR;
58
  // Enable CAN in "Listen Only" mode
59
  AT91C_BASE_CAN->CAN_MR = AT91C_CAN_ABM | AT91C_CAN_CANEN;
60
  //Wait for Wakeup Flag (11 rezessive bits)
61
  while((AT91C_BASE_CAN->CAN_SR & AT91C_CAN_WAKEUP) != AT91C_CAN_WAKEUP);
62
}
1
void CANIrqHandler (void){
2
3
  printf("--Handler\r\n");
4
  volatile unsigned int status;
5
  unsigned short MBnummer = 10;
6
  volatile unsigned char EP = 10;
7
  //Read AIV_IV for ack (Seite 159)
8
  AT91C_BASE_AIC->AIC_IVR;
9
  //CHECK for enabled interrupt
10
  status = ((AT91C_BASE_CAN->CAN_SR) & (AT91C_BASE_CAN->CAN_IMR));
11
  //Disable Interrupt & Clear
12
  AT91C_BASE_AIC->AIC_IDCR = (0x1 << AT91C_ID_CAN)|(0x1 << AT91C_ID_SYS);
13
  //AT91C_BASE_CAN->CAN_IDR = 0xFF; //((status = 1))
14
  printf("vor_CAN_SR = %x\r\n",AT91C_BASE_CAN->CAN_SR);
15
  printf("vor_CAN_IMR = %x\r\n",AT91C_BASE_CAN->CAN_IMR);
16
  printf("vor_CAN_SR & CAN_IMR = %x\r\n", status);
17
18
  //ToDo
19
  //WAKEUP interrupt
20
  if(status & AT91C_CAN_WAKEUP){
21
    AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP;
22
  }
23
  //ALTERNATIVE WAKEUP SOFORT DISABLE!
24
  //AT91C_BASE_CAN->CAN_IDR = AT91C_CAN_WAKEUP;
25
26
  //MB0 0xC2
27
  if(status &  AT91C_CAN_MB0){
28
    InterruptFunctionMB0();
29
    MBnummer = 0;
30
    EP = 0;
31
  }
32
  //MB1 0x310
33
  else if(status & AT91C_CAN_MB1){
34
    printf("MAB1\r\n");
35
    InterruptFunctionMB1();
36
    MBnummer = 1;
37
    EP = 1;
38
  }
39
  //MB2 0x90
40
  else if(status & AT91C_CAN_MB2){
41
    printf("MAB2\r\n");
42
    InterruptFunctionMB2();
43
    MBnummer = 2;
44
    EP = 2;
45
  }
46
  //MB3 0x23A
47
  else if(status & AT91C_CAN_MB3){
48
    printf("MAB3\r\n");
49
    InterruptFunctionMB3();
50
    MBnummer = 3;
51
    EP = 3;
52
  }
53
  else printf("nix\r\n");
54
55
  //Check for Errors
56
  if ((status&0xFFCF0000) != 0) {
57
    CAN_ErrorHandling(status, EP);
58
    }
59
  //Clears MRDY (Seite 562)
60
  printf("Mailbox NR = %x\r\n", MBnummer);
61
  AT91C_BASE_CAN->CAN_MB0.CAN_MB_MMR = AT91C_CAN_MOT;
62
  AT91C_BASE_CAN->CAN_MB1.CAN_MB_MMR = AT91C_CAN_MOT;
63
  AT91C_BASE_CAN->CAN_MB2.CAN_MB_MMR = AT91C_CAN_MOT;
64
  AT91C_BASE_CAN->CAN_MB3.CAN_MB_MMR = AT91C_CAN_MOT;
65
  switch(MBnummer){
66
    case 0: AT91C_BASE_CAN->CAN_MB0.CAN_MB_MCR = AT91C_CAN_MTCR;
67
        break;
68
    case 1: AT91C_BASE_CAN->CAN_MB1.CAN_MB_MCR = AT91C_CAN_MTCR;
69
        break;
70
    case 2: AT91C_BASE_CAN->CAN_MB2.CAN_MB_MCR = AT91C_CAN_MTCR;
71
        break;
72
    case 3: AT91C_BASE_CAN->CAN_MB3.CAN_MB_MCR = AT91C_CAN_MTCR;
73
        break;
74
  }
75
76
  unsigned int i = AT91C_BASE_CAN_MB0->CAN_MB_MSR;
77
  i = AT91C_BASE_CAN_MB1->CAN_MB_MSR;
78
  i = AT91C_BASE_CAN_MB2->CAN_MB_MSR;
79
  i = AT91C_BASE_CAN_MB3->CAN_MB_MSR;
80
  printf("end_0MSR = %x\r\n",AT91C_BASE_CAN_MB0->CAN_MB_MSR);
81
  printf("end_1MSR = %x\r\n",AT91C_BASE_CAN_MB1->CAN_MB_MSR);
82
  printf("end_2MSR = %x\r\n",AT91C_BASE_CAN_MB2->CAN_MB_MSR);
83
  printf("end_3MSR = %x\r\n",AT91C_BASE_CAN_MB3->CAN_MB_MSR);
84
  printf("end_CAN_SR = %x\r\n",AT91C_BASE_CAN->CAN_SR);
85
86
  //write to EOICR = exit point
87
  AT91C_BASE_AIC->AIC_ICCR = (1 << AT91C_ID_CAN)|(1 << AT91C_ID_SYS);
88
  //Enable Interrupt
89
  AT91C_BASE_AIC->AIC_IECR = (1 << AT91C_ID_SYS) | (1 << AT91C_ID_CAN);
90
  AT91C_BASE_AIC->AIC_EOICR = 0x0;
91
  printf("ENDHANDLER\r\n");
92
}

Danke fürs durchlesen!

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.