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  | }
  |