1  | #define CAN_OPMODE_CONFIG 0x4
  | 
2  | #define CAN_OPMODE_LOOPBACK 0x2
  | 
3  | #define CAN_OPMODE_NORMAL 0x0
  | 
4  | #define NUM_OF_ECAN_BUFFERS 32
  | 
5  | 
  | 
6  | 
  | 
7  | __eds__ uint16 m_Can_ECanTXRXMsgBuf[NUM_OF_ECAN_BUFFERS][8] __attribute__((eds,aligned(NUM_OF_ECAN_BUFFERS * 16)));
  | 
8  | 
  | 
9  | 
  | 
10  | void Can_Init()
  | 
11  | {
 | 
12  |     /* IO Register initialisieren RPINR26 = RPI41 0x2A RPOR5 = RPI54 0x36 */
  | 
13  |     RPINR26 = 0x2A;
  | 
14  |     /* Output RP54 to C1TX (0xD oder 14) setzen */
  | 
15  |     RPOR5bits.RP54R = 0xD;
  | 
16  | 
  | 
17  |     /* Can Baustein in Konfigurationsmode versetzen */
  | 
18  |     CAN1SetOperationModeNoWait(CAN_REQ_OPERMODE_CONFIG, CAN_DO_NOT_CMP_DATABYTES);
  | 
19  |     while(C1CTRL1bits.OPMODE != CAN_OPMODE_CONFIG);
  | 
20  | 
  | 
21  | 
  | 
22  |     C1CTRL1bits.CANCKS = 0;
  | 
23  |     C1CTRL1bits.CSIDL = 0;
  | 
24  |     C1CTRL1bits.CANCAP = 0;
  | 
25  | 
  | 
26  |     /* Config */
  | 
27  |     C1CTRL1bits.WIN = 1;
  | 
28  |     /* Bit Timings */
  | 
29  |     /* Berechnungsschritte für Can Bit Timing Konfiguration
  | 
30  |      *
  | 
31  |      * Step1: CALCULATE THE TIME QUANTUM FREQUENCY (FTQ) Ftq = N*Fbaud
  | 
32  |      * 12 TQ Pro Bit, gewählt weil es gerade Ergebnisse gibt
  | 
33  |      * N = 12 -> 250Kbits/s = 4µs Bittime = 12 Quanta/bit = 250ns/Quanta
  | 
34  |      * Ftq = 12*250*10^3 = 3*10^6
  | 
35  |      *
  | 
36  |      * STEP 2: CALCULATE THE BAUD RATE PRESCALER
  | 
37  |      * BRP = (Fcan/(2 × FTQ))-1 = Fcan = Fcy = 60 * 10^6 Hz
  | 
38  |      * BRP = (60*10^6/(2*3*10^6))-1 = (60/60)-1 = 0
  | 
39  |      *
  | 
40  |      * STEP 3: SELECT THE INDIVIDUAL BIT TIME SEGMENTS
  | 
41  |      * Phase Segment 2 = 25% -> Gerade TQ Zahl und Sample Point 75%
  | 
42  |      * Bit Time = Sync Segment + (Sync Jump Width) + Propagation Segment + Phase Segment 1 + Phase Segment 2
  | 
43  |      * 12 = 1 + (2) + 2 + 6 + 3 */
  | 
44  |     C1CFG1bits.BRP = 0x0;
  | 
45  |     C1CFG1bits.SJW = 0x1;
  | 
46  |     C1CFG2bits.SEG1PH = 0x5;
  | 
47  |     C1CFG2bits.SEG2PHTS = 0x1;
  | 
48  |     C1CFG2bits.SEG2PH = 0x2;
  | 
49  |     C1CFG2bits.PRSEG = 0x1;
  | 
50  | 
  | 
51  |     C1FCTRL = 0xC01F;
  | 
52  | 
  | 
53  |     /* Configure Message Buffer 0 for Transmission and assign priority */
  | 
54  |     C1TR01CONbits.TXEN0 = 0x1;
  | 
55  |     C1TR01CONbits.TX0PRI = 0x3;
  | 
56  | 
  | 
57  | 
  | 
58  |     uint32 adMsgBuf;
  | 
59  | 
  | 
60  |     /* DMA Config Channel 0 for TX IRQ = 70*/
  | 
61  |     DMA0CON = 0x2020;
  | 
62  |     DMA0REQ = 70;
  | 
63  |     DMA0CNT = 7;
  | 
64  |     DMA0PAD = (volatile unsigned int)&C1TXD;
  | 
65  |     adMsgBuf = __builtin_edsoffset(m_Can_ECanTXRXMsgBuf);
  | 
66  |     adMsgBuf = adMsgBuf & 0x7FFF;
  | 
67  |     adMsgBuf += __builtin_edspage(m_Can_ECanTXRXMsgBuf) <<15;
  | 
68  |     DMA0STAL = adMsgBuf & 0xFFFF;
  | 
69  |     DMA0STAH = adMsgBuf >> 16;
  | 
70  |     DMA0CONbits.CHEN = 0x1;
  | 
71  | 
  | 
72  |     /* Assign 32x8word Message Buffers for ECAN1 in device RAM. This example uses DMA1 for RX.
  | 
73  |     Refer to 21.8.1 ?DMA Operation for Transmitting Data? for details on DMA channel
  | 
74  |     configuration for ECAN transmit. */
  | 
75  |     DMA1CONbits.SIZE = 0x0;
  | 
76  |     DMA1CONbits.DIR = 0x0;
  | 
77  |     DMA1CONbits.AMODE = 0x2;
  | 
78  |     DMA1CONbits.MODE = 0x0;
  | 
79  |     DMA1REQ = 34;
  | 
80  |     DMA1CNT = 7;
  | 
81  |     DMA1PAD = (volatile unsigned int) &C1RXD;
  | 
82  |     adMsgBuf = __builtin_edsoffset(m_Can_ECanTXRXMsgBuf);
  | 
83  |     adMsgBuf = adMsgBuf & 0x7FFF;
  | 
84  |     adMsgBuf += __builtin_edspage(m_Can_ECanTXRXMsgBuf) << 15;
  | 
85  |     DMA1STAL = adMsgBuf & 0xFFFF;
  | 
86  |     DMA1STAH = adMsgBuf >> 16;
  | 
87  |     DMA1CONbits.CHEN = 0x1;
  | 
88  | 
  | 
89  |     /* RX Filter */
  | 
90  |     /* Select Acceptance Filter Mask 0 for Acceptance Filter 0 */
  | 
91  |     C1FMSKSEL1bits.F0MSK = 0x0;
  | 
92  |     /* Configure Acceptance Filter Mask 0 register to mask SID<2:0>
  | 
93  |      * Mask Bits (11-bits) : 0b111 1111 1000 */
  | 
94  |     C1RXM0SIDbits.SID = 0x7F8;
  | 
95  |     /* Configure Acceptance Filter 0 to match standard identifier
  | 
96  |     Filter Bits (11-bits): 0b011 1010 xxx with the mask setting, message with SID
  | 
97  |     range 0x1D0-0x1D7 will be accepted by the ECAN module. */
  | 
98  |     C1RXF0SIDbits.SID = 0x01D0;
  | 
99  |     /* Acceptance Filter 0 to check for Standard Identifier */
  | 
100  |     C1RXM0SIDbits.MIDE = 0x1;
  | 
101  |     C1RXF0SIDbits.EXIDE = 0x0;
  | 
102  |     /* Acceptance Filter 0 to use Message Buffer 10 to store message */
  | 
103  |     C1BUFPNT1bits.F0BP = 0xA;
  | 
104  |     /* Filter 0 enabled for Identifier match with incoming message */
  | 
105  |     C1FEN1bits.FLTEN0 = 0x1;
  | 
106  |     /* Clear Window Bit to Access ECAN
  | 
107  |      * Control Registers */
  | 
108  |     C1CTRL1bits.WIN = 0x0;
  | 
109  | 
  | 
110  |     /* start Can */
  | 
111  | //    C1CTRL1bits.REQOP = CAN_OPMODE_NORMAL;
  | 
112  | //    while(C1CTRL1bits.OPMODE != CAN_OPMODE_NORMAL);
  | 
113  | 
  | 
114  |     C1CTRL1bits.REQOP = CAN_OPMODE_LOOPBACK;
  | 
115  |     while(C1CTRL1bits.OPMODE != CAN_OPMODE_LOOPBACK);
  | 
116  | 
  | 
117  |     m_Can_ECanTXRXMsgBuf[0][0] = 0x01D2 << 2;    /* IDE, SRR = 0 SID = 1D2 */
  | 
118  |     m_Can_ECanTXRXMsgBuf[0][1] = 0x0000;        /* EID = 0 */
  | 
119  |     m_Can_ECanTXRXMsgBuf[0][2] = 0x0008;        /* RTR = 0, DLC = Data Length counter = 8 = 8 Wörter sollen übertragen werden */
  | 
120  |     m_Can_ECanTXRXMsgBuf[0][3] = 0xabcd;
  | 
121  |     m_Can_ECanTXRXMsgBuf[0][4] = 0xabcd;
  | 
122  |     m_Can_ECanTXRXMsgBuf[0][5] = 0xabcd;
  | 
123  |     m_Can_ECanTXRXMsgBuf[0][6] = 0xabcd;
  | 
124  | 
  | 
125  |     /* Request sende Nachricht */
  | 
126  |     C1TR01CONbits.TXREQ0 = 0x1;
  | 
127  |     /* Warte auf gesendet */
  | 
128  |     //while(C1TR01CONbits.TXREQ0 == 1);
  | 
129  |     while(1)
  | 
130  |     {
 | 
131  |         /* Message was received. */
  | 
132  |         while (C1RXFUL1bits.RXFUL10 == 0);
  | 
133  |         C1RXFUL1bits.RXFUL10 = 0;
  | 
134  |     }
  |