1 | #include "can.h"
|
2 |
|
3 | /* Assign 32x8 Word Message Buffers for ECAN1 in DMA RAM */
|
4 | unsigned int ecan1MsgBuf[32][8] __attribute__((space(dma)));
|
5 |
|
6 | void init_can()
|
7 | {
|
8 | /* Set the Operating Frequency of the device to be 40MHz */
|
9 | #define FCY 40000000
|
10 |
|
11 | //Peripherie den Pins zuweisen
|
12 | // Unlock Registers
|
13 | __builtin_write_OSCCONL(OSCCON & ~(1<<6));
|
14 | // Assign C1Rx To Pin RP12
|
15 | RPINR26bits.C1RXR = 12;
|
16 | // Assign C1Tx To Pin RP13
|
17 | RPOR6bits.RP13R = 0b10000;
|
18 | // Lock Registers
|
19 | __builtin_write_OSCCONL(OSCCON | (1<<6));
|
20 |
|
21 | TRISBbits.TRISB12 = 1; //C1RX als Eingang definieren
|
22 | TRISBbits.TRISB13 = 0; //C1TX als Ausgang definieren
|
23 |
|
24 | /* Enable Window to Access Acceptance Filter Registers */
|
25 | C1CTRL1bits.WIN=0x1;
|
26 | /* Select Acceptance Filter Mask 0 for Acceptance Filter 0 */
|
27 | C1FMSKSEL1bits.F0MSK=0x0;
|
28 | /* Configure Acceptance Filter Mask 0 register to mask SID<2:0>
|
29 | Mask Bits (11-bits) : 0b000 0000 0000 */
|
30 | C1RXM0SIDbits.SID = 0x0000;
|
31 | /* Configure Acceptance Filter 0 to match standard identifier
|
32 | Filter Bits (11-bits): 0b011 1010 xxx */
|
33 | C1RXF0SIDbits.SID = 0x01D0;
|
34 | /* Acceptance Filter 0 to check for Standard Identifier */
|
35 | C1RXM0SIDbits.MIDE = 0x1;
|
36 | C1RXF0SIDbits.EXIDE= 0x0;
|
37 | /* Acceptance Filter 0 to use Message Buffer 10 to store message */
|
38 | C1BUFPNT1bits.F0BP = 0xA;
|
39 | /* Filter 0 enabled for Identifier match with incoming message */
|
40 | C1FEN1bits.FLTEN0=0x1;
|
41 | /* Clear Window Bit to Access ECAN Control Registers */
|
42 | C1CTRL1bits.WIN=0x0;
|
43 |
|
44 | /* Set the ECAN module for Configuration Mode before writing into the Baud Rate Control Registers*/
|
45 | C1CTRL1bits.REQOP = 4;
|
46 | /* Wait for the ECAN module to enter into Configuration Mode */
|
47 | while(C1CTRL1bits.OPMODE != 4);
|
48 | /* Phase Segment 1 time is 8 TQ */
|
49 | C1CFG2bits.SEG1PH = 0x7;
|
50 | /* Phase Segment 2 time is set to be programmable */
|
51 | C1CFG2bits.SEG2PHTS = 0x1;
|
52 | /* Phase Segment 2 time is 6 TQ */
|
53 | C1CFG2bits.SEG2PH = 0x5;
|
54 | /* Propagation Segment time is 5 TQ */
|
55 | C1CFG2bits.PRSEG = 0x4;
|
56 | /* Bus line is sampled three times at the sample point */
|
57 | C1CFG2bits.SAM = 0x1;
|
58 | /* Synchronization Jump Width set to 4 TQ */
|
59 | C1CFG1bits.SJW = 0x3;
|
60 | /* Baud Rate Prescaler bits set to 1:1, i.e., TQ = (2*1*1)/ FCAN */
|
61 | C1CFG1bits.BRP = 0x0;
|
62 |
|
63 | /* Configure Message Buffer 0 for Transmission and assign priority*/
|
64 | C1TR01CONbits.TXEN0 = 0x1;
|
65 | C1TR01CONbits.TX0PRI = 0x3;
|
66 |
|
67 | /*DMA0-Config-Transmit*/
|
68 |
|
69 | /* Data Transfer Size: Word Transfer Mode */
|
70 | DMA0CONbits.SIZE = 0x0;
|
71 | /* Data Transfer Direction: DMA RAM to Peripheral */
|
72 | DMA0CONbits.DIR = 0x1;
|
73 | /* DMA Addressing Mode: Peripheral Indirect Addressing mode */
|
74 | DMA0CONbits.AMODE = 0x2;
|
75 | /* Operating Mode: Continuous, Ping-Pong modes disabled */
|
76 | DMA0CONbits.MODE = 0x0;
|
77 | /* Assign ECAN1 Transmit event for DMA Channel 0 */
|
78 | DMA0REQ = 70;
|
79 | /* Set Number of DMA Transfer per ECAN message to 8 words */
|
80 | DMA0CNT = 7;
|
81 | /* Peripheral Address: ECAN1 Transmit Register */
|
82 | DMA0PAD = (volatile unsigned int)&C1TXD;
|
83 | /* Start Address Offset for ECAN1 Message Buffer 0x0000 */
|
84 | DMA0STA = __builtin_dmaoffset(ecan1MsgBuf);
|
85 | /* Channel Enable: Enable DMA Channel 0 */
|
86 | DMA0CONbits.CHEN = 0x1;
|
87 | /* Channel Interrupt Enable: Enable DMA Channel 0 Interrupt */
|
88 | IEC0bits.DMA0IE = 1;
|
89 |
|
90 | /*DMA1-Config-Receive*/
|
91 |
|
92 | /* Data Transfer Size: Word Transfer Mode */
|
93 | DMA1CONbits.SIZE = 0x0;
|
94 | /* Data Transfer Direction: Peripheral to DMA RAM */
|
95 | DMA1CONbits.DIR = 0x0;
|
96 | /* DMA Addressing Mode: Peripheral Indirect Addressing mode */
|
97 | DMA1CONbits.AMODE = 0x2;
|
98 | /* Operating Mode: Continuous, Ping-Pong modes disabled */
|
99 | DMA1CONbits.MODE = 0x0;
|
100 | /* Assign ECAN1 Receive event for DMA Channel 0 */
|
101 | DMA1REQ = 34;
|
102 | /* Set Number of DMA Transfer per ECAN message to 8 words */
|
103 | DMA1CNT = 7;
|
104 | /* Peripheral Address: ECAN1 Receive Register */
|
105 | DMA1PAD = (volatile unsigned int)&C1RXD;
|
106 | /* Start Address Offset for ECAN1 Message Buffer 0x0000 */
|
107 | DMA1STA = 0x0000;
|
108 | /* Channel Enable: Enable DMA Channel 1 */
|
109 | DMA1CONbits.CHEN = 0x1;
|
110 | /* Channel Interrupt Enable: Enable DMA Channel 1 Interrupt */
|
111 | IEC0bits.DMA1IE = 1;
|
112 |
|
113 | /* Put the ECAN Module into Normal Mode Operating Mode*/
|
114 | C1CTRL1bits.REQOP = 0;
|
115 | /* Wait for the ECAN module to enter into Normal Operating Mode */
|
116 | while(C1CTRL1bits.OPMODE != 0);
|
117 | }
|
118 |
|
119 | void __attribute__((__interrupt__,no_auto_psv)) _DMA1Interrupt(void)
|
120 | {
|
121 | IFS0bits.DMA1IF = 0; //Clear the DMA3 Interrupt Flag
|
122 | }
|
123 |
|
124 | void send_can()
|
125 | {
|
126 | /* WRITE TO MESSAGE BUFFER 0 */
|
127 | ecan1MsgBuf[0][0] = 0x123C;
|
128 | ecan1MsgBuf[0][1] = 0x0000;
|
129 | ecan1MsgBuf[0][2] = 0x8;
|
130 | /* WRITE MESSAGE DATA BYTES */
|
131 | ecan1MsgBuf[0][3] = 0xabcd;
|
132 | ecan1MsgBuf[0][4] = 0xabcd;
|
133 | ecan1MsgBuf[0][5] = 0xabcd;
|
134 | ecan1MsgBuf[0][6] = 0xabcd;
|
135 | /* REQUEST MESSAGE BUFFER 0 TRANSMISSION */
|
136 | C1TR01CONbits.TXREQ0 = 0x1;
|
137 | }
|