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!