1 | #include <p33Exxxx.h>
|
2 |
|
3 | #define FCY 60000000
|
4 | #include <libpic30.h>
|
5 | #include <stdint.h>
|
6 |
|
7 | #define Delay_us __delay_us
|
8 |
|
9 | _FOSCSEL(FNOSC_FRC)
|
10 |
|
11 | // Enable clock switching and fail safe clock monitor disabled
|
12 | _FOSC(FCKSM_CSECMD & OSCIOFNC_ON & IOL1WAY_OFF)
|
13 |
|
14 | // Watchdog aus
|
15 | _FWDT(FWDTEN_OFF)
|
16 |
|
17 | _FICD(ICS_PGD2 & JTAGEN_OFF)
|
18 |
|
19 | void SysInit()
|
20 | {
|
21 | // Configure Oscillator to operate the device at 60Mhz
|
22 | // Fosc= Fin*M/(N1*N2), Fcy=Fosc/2
|
23 | // Fosc= 7.37*(65)/(2*2)=120Mhz for Fosc, Fcy = 60Mhz
|
24 |
|
25 | // Configure PLL prescaler, PLL postscaler, PLL divisor
|
26 | PLLFBD = 63; // M = PLLFBD + 2
|
27 | CLKDIVbits.PLLPOST = 0; // N1 = 2
|
28 | CLKDIVbits.PLLPRE = 0; // N2 = 2
|
29 |
|
30 | __builtin_write_OSCCONH(0x01); // New Oscillator selection FRC w/ PLL
|
31 | __builtin_write_OSCCONL(0x01); // Enable Switch
|
32 |
|
33 | while (OSCCONbits.COSC != 0b001); // Wait for Oscillator to switch to FRC w/ PLL
|
34 | while (OSCCONbits.LOCK != 1); // Wait for Pll to Lock
|
35 | Delay_us(200);
|
36 | }
|
37 |
|
38 |
|
39 | #define CAN_OPMODE_CONFIG 0x4
|
40 | #define CAN_OPMODE_LOOPBACK 0x2
|
41 | #define CAN_OPMODE_NORMAL 0x0
|
42 | #define NUM_OF_ECAN_BUFFERS 32
|
43 |
|
44 | uint16_t m_Can_ECanTXRXMsgBuf[NUM_OF_ECAN_BUFFERS][8] __attribute__((aligned(NUM_OF_ECAN_BUFFERS * 16)));
|
45 |
|
46 | void Can_Init()
|
47 | {
|
48 | // Can Rx/Tx den Pins zuweisen
|
49 | // Unlock Registers
|
50 | __builtin_write_OSCCONL(OSCCON & 0xbf);
|
51 |
|
52 | // IO Register initialisieren RPINR26 = RP39 0x27
|
53 | RPINR26 = 0x27;
|
54 | // Output RP41 to C1TX (0xE oder 14) setzen
|
55 | RPOR3bits.RP41R = 0xE;
|
56 |
|
57 | // Lock Registers
|
58 | __builtin_write_OSCCONL(OSCCON | 0x40);
|
59 |
|
60 |
|
61 | // Can Baustein in Konfigurationsmode versetzen
|
62 | C1CTRL1bits.REQOP = CAN_OPMODE_CONFIG;
|
63 | while(C1CTRL1bits.OPMODE != CAN_OPMODE_CONFIG)
|
64 | ;
|
65 |
|
66 | C1CTRL1bits.CANCKS = 0;
|
67 | C1CTRL1bits.CSIDL = 0;
|
68 | C1CTRL1bits.CANCAP = 0;
|
69 |
|
70 | // ermittelt mit dem bittime calc Plugin
|
71 | C1CFG1=0x001A;
|
72 | C1CFG2=0x0059;
|
73 |
|
74 | C1FCTRL = 0xC01F;
|
75 |
|
76 | /* DMA Config Channel 0 for TX IRQ = 70 */
|
77 | DMA0CON = 0x2020;
|
78 | DMA0REQ = 70;
|
79 | DMA0CNT = 7;
|
80 | DMA0PAD = (volatile unsigned int)&C1TXD;
|
81 | DMA0STAL = (unsigned int) &m_Can_ECanTXRXMsgBuf;
|
82 | DMA0STAH = 0;
|
83 | DMA0CONbits.CHEN = 0x1;
|
84 |
|
85 | DMA2CON = 0x0020;
|
86 | DMA2REQ = 34;
|
87 | DMA2CNT = 7;
|
88 | DMA2PAD = (volatile unsigned int) &C1RXD;
|
89 | DMA2STAL = (unsigned int) &m_Can_ECanTXRXMsgBuf;
|
90 | DMA2STAH = 0;
|
91 | DMA2CONbits.CHEN=1;
|
92 |
|
93 | //IEC0bits.DMA1IE = 1;
|
94 |
|
95 | /* Set SFR Window to Buffer register in RAM */
|
96 | C1CTRL1bits.WIN = 1;
|
97 | /* RX Filter */
|
98 | /* Select Acceptance Filter Mask 0 for Acceptance Filter 0 */
|
99 | C1FMSKSEL1bits.F0MSK = 0x0;
|
100 | /* Configure Acceptance Filter Mask 0 register to mask SID<2:0>
|
101 | * Mask Bits (11-bits) : 0b111 1111 1000 */
|
102 | C1RXM0SIDbits.SID = 0x7F8;
|
103 | // C1RXM0SIDbits.SID = 0x000;
|
104 |
|
105 | /* Configure Acceptance Filter 0 to match standard identifier
|
106 | Filter Bits (11-bits): 0b011 1010 xxx with the mask setting, message with SID
|
107 | range 0x1D0-0x1D7 will be accepted by the ECAN module. */
|
108 | C1RXF0SIDbits.SID = 0x01D0;
|
109 | /* Acceptance Filter 0 to check for Standard Identifier */
|
110 | C1RXM0SIDbits.MIDE = 0x1;
|
111 | // C1RXM0SIDbits.MIDE = 0x0;
|
112 | C1RXF0SIDbits.EXIDE = 0x0;
|
113 | /* Acceptance Filter 0 to use Message Buffer 10 to store message */
|
114 | C1BUFPNT1bits.F0BP = 0xA;
|
115 | /* Filter 0 enabled for Identifier match with incoming message */
|
116 | C1FEN1 = 0x0;
|
117 | C1FEN1bits.FLTEN0 = 0x1;
|
118 |
|
119 | /* Set SFR Window to Control register in RAM */
|
120 | C1CTRL1bits.WIN = 0;
|
121 |
|
122 |
|
123 | // Configure Message Buffer 0 for Transmission and assign priority
|
124 | C1TR01CONbits.TXEN0 = 0x1;
|
125 | C1TR01CONbits.TX0PRI = 0x3;
|
126 |
|
127 | // C1TR01CONbits.TXEN1 = 0x0;
|
128 | // C1TR01CONbits.TX1PRI = 0x3;
|
129 |
|
130 |
|
131 | // start Can
|
132 | C1CTRL1bits.REQOP = CAN_OPMODE_NORMAL;
|
133 | while(C1CTRL1bits.OPMODE != CAN_OPMODE_NORMAL)
|
134 | ;
|
135 |
|
136 | //C1CTRL1bits.REQOP = CAN_OPMODE_LOOPBACK;
|
137 | //while(C1CTRL1bits.OPMODE != CAN_OPMODE_LOOPBACK)
|
138 | // ;
|
139 |
|
140 | m_Can_ECanTXRXMsgBuf[0][0] = 0x01D3 << 2; // IDE, SRR = 0 SID = 1D2
|
141 | m_Can_ECanTXRXMsgBuf[0][1] = 0x0000; // EID = 0
|
142 | m_Can_ECanTXRXMsgBuf[0][2] = 0x0008; // RTR = 0, DLC = Data Length counter = 8 = 8 Wörter sollen übertragen werden
|
143 | m_Can_ECanTXRXMsgBuf[0][3] = 0xabcd;
|
144 | m_Can_ECanTXRXMsgBuf[0][4] = 0xabcd;
|
145 | m_Can_ECanTXRXMsgBuf[0][5] = 0xabcd;
|
146 | m_Can_ECanTXRXMsgBuf[0][6] = 0xabcd;
|
147 |
|
148 | // Empfangspuffer leer setzen
|
149 | C1RXFUL1 = 0;
|
150 |
|
151 |
|
152 | while (1)
|
153 | {
|
154 | // Request sende Nachricht
|
155 | C1TR01CONbits.TXREQ0 = 0x1;
|
156 |
|
157 | // Warte auf gesendet
|
158 | while(C1TR01CONbits.TXREQ0 == 1);
|
159 |
|
160 | Delay_us(100000);
|
161 |
|
162 | // Message was received.
|
163 | while (C1RXFUL1bits.RXFUL10 == 0);
|
164 | C1RXFUL1bits.RXFUL10 = 0;
|
165 | uint16_t test = m_Can_ECanTXRXMsgBuf[10][0];
|
166 | test = test >> 2;
|
167 | }
|
168 | }
|
169 |
|
170 | int main()
|
171 | {
|
172 |
|
173 | SysInit();
|
174 | Can_Init();
|
175 | }
|