1 | //CAN
|
2 | C1CTRL1bits.REQOP = 0b100; //Switch to configuration mode
|
3 | while(C1CTRL1bits.OPMODE != 0b100); //Wait for operation mode to change
|
4 |
|
5 | C1CTRL1bits.WIN = 1; //filter window
|
6 | C1CTRL1bits.CSIDL = 0; //CAN module continues operation in device IDLE
|
7 | C1CTRL1bits.CANCKS = 0; //F_CAN is equal to F_P=17,5MHz
|
8 | C1CFG1bits.BRP = 0b000111; //T_Q is 2x7x1/F_CAN= 800ns
|
9 | C1CFG1bits.SJW = 0b00; //SJW is 1T_Q
|
10 | C1CFG2bits.PRSEG = 0b100; //Prop segment is 3T_Q
|
11 | C1CFG2bits.SEG1PH = 0b100; //Segment 1 is 3T_Q
|
12 | C1CFG2bits.SEG2PH = 0b100; //Segment 2 is 3T_Q
|
13 | C1CFG2bits.SEG2PHTS = 0;
|
14 | C1CFG2bits.SAM = 1; //Bus line is sampled three times per sample point
|
15 | C1CFG2bits.WAKFIL = 0; //CAN bus line filter is used for wake up
|
16 | C1FEN1 = 0x3FFF; //Enable Filter 0:13
|
17 | C1BUFPNT1 = 0xFFFF; //messages are received in FIFO buffer
|
18 | C1BUFPNT2 = 0xFFFF;
|
19 | C1BUFPNT3 = 0xFFFF;
|
20 | C1BUFPNT4 = 0x00FF;
|
21 |
|
22 | C1RXF0SIDbits.SID = 0b00000000001; //Filter 0
|
23 | C1RXF0SIDbits.EID = 0b00; //Filter 0 (Extended Identifier)
|
24 | C1RXF0EID = 0x0000; //Filter 0 (Extended Identifier)
|
25 | C1RXF1SIDbits.SID = 0b00000000010; //Filter 1
|
26 | C1RXF1SIDbits.EID = 0b00; //Filter 1 (Extended Identifier)
|
27 | C1RXF1EID = 0x0000; //Filter 1 (Extended Identifier)
|
28 | C1RXF2SIDbits.SID = 0b00000000011; //Filter 2
|
29 | C1RXF2SIDbits.EID = 0b00; //Filter 2 (Extended Identifier)
|
30 | C1RXF2EID = 0x0000; //Filter 2 (Extended Identifier)
|
31 | C1RXF3SIDbits.SID = 0b00000000100; //Filter 3
|
32 | C1RXF3SIDbits.EID = 0b00; //Filter 3 (Extended Identifier)
|
33 | C1RXF3EID = 0x0000; //Filter 3 (Extended Identifier)
|
34 | C1RXF4SIDbits.SID = 0b00000000101; //Filter 4
|
35 | C1RXF4SIDbits.EID = 0b00; //Filter 4 (Extended Identifier)
|
36 | C1RXF4EID = 0x0000; //Filter 4 (Extended Identifier)
|
37 | C1RXF5SIDbits.SID = 0b00000000110; //Filter 5
|
38 | C1RXF5SIDbits.EID = 0b00; //Filter 5 (Extended Identifier)
|
39 | C1RXF5EID = 0x0000; //Filter 5 (Extended Identifier)
|
40 | C1RXF6SIDbits.SID = 0b00000000111; //Filter 6
|
41 | C1RXF6SIDbits.EID = 0b00; //Filter 6 (Extended Identifier)
|
42 | C1RXF6EID = 0x0000; //Filter 6 (Extended Identifier)
|
43 | C1RXF7SIDbits.SID = 0b00000001000; //Filter 7
|
44 | C1RXF7SIDbits.EID = 0b00; //Filter 7 (Extended Identifier)
|
45 | C1RXF7EID = 0x0000; //Filter 7 (Extended Identifier)
|
46 | C1RXF8SIDbits.SID = 0b00000001001; //Filter 8
|
47 | C1RXF8SIDbits.EID = 0b00; //Filter 8 (Extended Identifier)
|
48 | C1RXF8EID = 0x0000; //Filter 8 (Extended Identifier)
|
49 | C1RXF9SIDbits.SID = 0b00000001010; //Filter 9
|
50 | C1RXF9SIDbits.EID = 0b00; //Filter 9 (Extended Identifier)
|
51 | C1RXF9EID = 0x0000; //Filter 9 (Extended Identifier)
|
52 | C1RXF10SIDbits.SID = 0b0000001011; //Filter 10
|
53 | C1RXF10SIDbits.EID = 0b00; //Filter 10 (Extended Identifier)
|
54 | C1RXF10EID = 0x0000; //Filter 10 (Extended Identifier)
|
55 | C1RXF11SIDbits.SID = 0b00000001100; //Filter 11
|
56 | C1RXF11SIDbits.EID = 0b00; //Filter 11 (Extended Identifier)
|
57 | C1RXF11EID = 0x0000; //Filter 11 (Extended Identifier)
|
58 | C1RXF12SIDbits.SID = 0b00000001101; //Filter 12
|
59 | C1RXF12SIDbits.EID = 0b00; //Filter 12
|
60 | C1RXF12EID = 0x0000; //Filter 12
|
61 | C1RXF13SIDbits.SID = 0b00000001110; //Filter 13
|
62 | C1RXF13SIDbits.EID = 0b00; //Filter 13 (Extended Identifier)
|
63 | C1RXF13EID = 0x0000; //Filter 13 (Extended Identifier)
|
64 |
|
65 | C1FMSKSEL1 = 0x0000; //Mask0 determines the acceptance mask for all used filters
|
66 | C1FMSKSEL2 = 0x0000;
|
67 | C1RXM0SID = 0xFFF7; //All identifier digits are relevant, standard fames and extended frames are receivable
|
68 | C1RXM0EID = 0xFFFF;
|
69 |
|
70 | C1CTRL1bits.WIN = 0; //buffer window
|
71 | C1FCTRLbits.DMABS = 0b100; //16 DMA buffers in RAM
|
72 | C1FCTRLbits.FSA = 0b00001; // FIFO area from TRB1 to RB15
|
73 | C1TR01CONbits.TXEN0 = 1; //Set TRB0 as transmit buffer
|
74 | IEC4bits.C1TXIE = 0; //deactivate interrpt processing by CPU
|
75 | IEC2bits.C1RXIE = 0;
|
76 |
|
77 | //DMA
|
78 | DMA0CONbits.AMODE = 0b10; //Peripheral indirect mode
|
79 | DMA0REQbits.IRQSEL = 0b00100010; //Connect to CAN RX peripheral
|
80 | DMA0PAD = (volatile unsigned int) &C1RXD; //Read from CAN1 RX register (address)
|
81 | IEC0bits.DMA0IE = 1; //Enable interrupt for DMA channel 0
|
82 | DMA0CNT = 7; //8 words to be transmitted
|
83 | DMA1CONbits.AMODE = 0b10; //Peripheral indirect mode
|
84 | DMA1CONbits.DIR = 1; //Channel 1 reads data from RAM to CAN
|
85 | DMA1REQbits.IRQSEL = 0b01000110; //Connect to CAN TX peripheral
|
86 | DMA1PAD = (volatile unsigned int) &C1TXD; //Writes to CAN1 TX register (address)
|
87 | IEC0bits.DMA1IE = 1; //Enable interrupt for DMA channel 1
|
88 | DMA1CNT = 7; //8 words to be transmitted
|
89 |
|
90 | DMA0STAL = (unsigned int) &canbuf; //CAN receive FIFO buffer (16 buffer, 8 words each)
|
91 | DMA0STAH = 0x0000;
|
92 | DMA1STAL = (unsigned int) &canbuf;
|
93 | DMA1STAH = 0x0000;
|
94 |
|
95 | DMA0CONbits.CHEN = 1; //Enable DMA channel 0 for CAN RX
|
96 | DMA1CONbits.CHEN = 1; //Enable DMA channel 1 for CAN TX
|
97 |
|
98 | C1CTRL1bits.REQOP = 0b000; //Switch to normal CAN operation mode
|
99 | while(C1CTRL1bits.OPMODE != 0b000); //Wait for opeation mode to change
|
100 |
|
101 | //MUST be last operation here
|
102 | IFS1bits.CNIF = 0; //Reset all used interrupt flags
|
103 | IFS0bits.DMA0IF = 0;
|
104 | IFS0bits.DMA1IF = 0;
|
105 | IFS0bits.T1IF = 0;
|
106 | IFS2bits.C1RXIF = 0;
|
107 | IFS4bits.C1TXIF = 0;
|
108 | INTCON2bits.GIE = 1; //Global interrupt enable
|