Subversion Repositories HomeAutomation

Rev

Details | Last modification | View Log | SVN | RSS feed

Rev Author Line No. Line
24 johboh 1
#include "../Include/CANdefs.h"
2
#include "../Include/stackTasks.h"
3
#include "../Include/CAN.h"
4
#include "../Include/uart.h"
5
 
6
 
7
#ifdef USE_CAN
8
 
9
 
10
 
11
 
12
/*
13
*   Function: canInit
14
*
15
*   Input:  none
16
*   Output: none
17
*   Pre-conditions: none
18
*   Affects: Changes can registers.
19
*   Depends: none.
20
*/
21
void canInit()
22
{
23
 
24
    // 1. Ensure that the ECAN module is in Configuration mode.
25
    CANCON=0;
26
 
27
    CANCONbits.REQOP2=1; // Request configruation mode
28
    while(!CANSTATbits.OPMODE2); // Wait for configuration mode
29
 
30
    //2. Select ECAN operational mode.
31
    #ifdef CAN_ENCHANCED_MODE
32
        // Use Mode 1: Enchanged Legacy mode
33
        // ECANCON.MDSEL1:MDSEL0 = 1
34
        ECANCONbits.MDSEL1 = 0;
35
        ECANCONbits.MDSEL0 = 1;
36
    #else
37
        // Use Mode 0: Legacy mode
38
        // ECANCON.MDSEL1:MDSEL0 = 0
39
        ECANCONbits.MDSEL1 = 0;
40
        ECANCONbits.MDSEL0 = 0;
41
    #endif
42
 
43
 
44
    // BUFFERS
45
 
46
    // Make all programmable buffers receive buffers
47
    BSEL0 = 0x00;
48
 
49
    // Setup the receive buffers
50
    RXB0CON = 0;
51
    RXB1CON = 0;
52
    B0CON = 0;
53
    B1CON = 0;
54
    B2CON = 0;
55
    B3CON = 0;
56
    B4CON = 0;
57
    B5CON = 0;
58
 
59
 
60
 
61
    //3. Set up the baud rate registers.
62
    // Times for different time segments:
63
    // Sync_Seq + Prop_Seq + Phase_Seg1 + Phase_Seg2 = 8
64
    // Sync_Seq = 2, Prop_Seq = 2, Phase_Seg1 = 2, Phase_Seg2 = 2
65
    // BRGCON1.SJW1:SJW0 = 1
66
    // BRGCON1.BRP5:BRP0 = CAN_BRP
67
    // BRGCON2.SEG2PHTS = 0 //Maximum PHEG1
68
    // BRGCON2.SEG1PH2:SEG1PH0 = 1
69
    // BRGCON2.PRSEG2:PRSEG0 = 1
70
    // BRGCON3.WAKDIS = 1/0  1=Dsiable CAN bus wake up
71
    // BRGCON3.WAKFIL = 1/0  1=Use filter on wake up
72
    // BRGCON3.SEG2PH2:SEG2PH0 = 1
73
 
74
    BRGCON1=0;
75
 
76
    // Sync_Seq = 2 x TQ = 1
77
    BRGCON1bits.SJW1=0;
78
    BRGCON1bits.SJW0=1;
79
 
80
    // Setting BRP.
81
    BRGCON1=BRGCON1|CAN_BRP;
82
 
83
    // Maximum PHEG1
84
    BRGCON2bits.SEG2PHTS = 1;
85
 
86
    // Phase_Seg1 = 2 x TQ = 1
87
    BRGCON2bits.SEG1PH2 = 0;
88
    BRGCON2bits.SEG1PH1 = 0;
89
    BRGCON2bits.SEG1PH0 = 1;
90
 
91
    // Prop_Seq = 2 x TQ = 1
92
    BRGCON2bits.PRSEG2 = 0;
93
    BRGCON2bits.PRSEG1 = 0;
94
    BRGCON2bits.PRSEG0 = 1;
95
 
96
    //  Enableing bus wake-up
97
    BRGCON3bits.WAKDIS = 0;
98
 
99
    // Dont use filter when wakeup
100
    BRGCON3bits.WAKFIL = 0;
101
 
102
    // Phase_Seg2 = 2 x TQ = 1
103
    BRGCON3bits.SEG2PH2 = 0;
104
    BRGCON3bits.SEG2PH1 = 0;
105
    BRGCON3bits.SEG2PH0 = 1;
106
 
107
 
108
    //4. Set up the filter and mask registers.
109
 
110
    // Disable all filters
111
    RXFCON0 = 0;
112
    RXFCON1 = 0;
113
 
114
 
115
    // No data byte filtering
116
    SDFLC = 0;
117
 
118
    // Setup filter/buffer association, two filters per buffer
119
    RXFBCON0 = 0x00;
120
    RXFBCON1 = 0x11;
121
    RXFBCON2 = 0x22;
122
    RXFBCON3 = 0x33;
123
    RXFBCON4 = 0x44;
124
    RXFBCON5 = 0x55;
125
    RXFBCON6 = 0x66;
126
    RXFBCON7 = 0x77;
127
 
128
    // Setup filter/mask association to Mask 0
129
    MSEL0 = MSEL1 = MSEL2 = MSEL3 = 0;
130
 
131
    // Set Mask 0 to not mask any filter bit
132
    RXM0SIDH = 0xFF;
133
    RXM0SIDL = 0xE3;
134
    RXM0EIDH = 0xFF;
135
    RXM0EIDL = 0xFF;   
136
 
137
    // Set I/O control CANTX pin will drive VDD when recessive
138
    CIOCON = 0x20;
139
 
140
    // Set interrupts   
141
    // Diable transmit interrupt
142
    TXBIE = 0;
143
 
144
    //rx any interrupt
145
    PIR3 = 0;
146
    PIE3 = 0b00000011;
147
 
148
    // High interrupt
149
    IPR3 =0b00000011;
150
 
151
    // Programmable buffers interrupt
152
    BIE0  = 0xFF;  
153
 
154
    //5. Set the ECAN module to normal mode or any other mode required by the application logic.
155
    #ifdef CAN_LOOPBACK_MODE
156
        // Use Loopback mode
157
        CANCON=0b01000000;
158
    #else
159
        // Use Normal mode
160
        CANCON=0b00000000;
161
    #endif
162
 
163
    while(CANSTATbits.OPMODE2); // Wait for configuration mode
164
}
165
 
166
 
167
/*
168
*   Function: canISR
169
*
170
*   Input:  none
171
*   Output: none
172
*   Pre-conditions: a call to canInit()
173
*   Affects: interrupt registers and receive data buffers
174
*   Depends: ..
175
*/
176
void canISR()
177
{
178
    BYTE defECANCON;
179
 
180
 
181
    if (PIR3bits.RXBnIF==1 && PIE3bits.RXBnIE==1 || PIR3bits.RXB1IF==1 || PIR3bits.RXB0IF==1)
182
    {
183
        uartPutrs("canISR!");
184
 
185
 
186
        // Save default ECANCON 
187
        #ifdef CAN_ENCHANCED_MODE
188
            defECANCON=(ECANCON&0b00000)|0b10000;
189
        #else
190
            defECANCON=(CANCON&0b000)|0b000;
191
        #endif
192
 
193
             if (RXB0CONbits.RXFUL==1)  
194
            {          
195
                #ifdef CAN_ENCHANCED_MODE
196
                    ECANCON = defECANCON|0b10000;
197
                #else
198
                    CANCON = defECANCON|0b000;
199
                #endif
200
 
201
                canGetPacket();
202
                RXB0CONbits.RXFUL=0;
203
            }
204
        else if (RXB1CONbits.RXFUL==1)  
205
        {
206
 
207
            #ifdef CAN_ENCHANCED_MODE
208
                ECANCON = defECANCON|0b10001;
209
            #else
210
                CANCON = defECANCON|0b101;
211
            #endif  
212
 
213
            canGetPacket();
214
            RXB1CONbits.RXFUL=0;
215
        }
216
        #ifdef CAN_ENCHANCED_MODE
217
            else if (B0CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10010; canGetPacket(); B0CONbits.RXFUL=0; }
218
            else if (B1CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10011; canGetPacket(); B1CONbits.RXFUL=0; }
219
            else if (B2CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10100; canGetPacket(); B2CONbits.RXFUL=0; }
220
            else if (B3CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10101; canGetPacket(); B3CONbits.RXFUL=0; }
221
            else if (B4CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10110; canGetPacket(); B4CONbits.RXFUL=0; }
222
            else if (B5CONbits.RXFUL==1)    { ECANCON = defECANCON|0b10111; canGetPacket(); B5CONbits.RXFUL=0; }
223
        #endif
224
        else {PIR3bits.RXBnIF=0; PIR3bits.RXB1IF=0; PIR3bits.RXB0IF=0; return;}
225
 
226
        // Restore mapping
227
        #ifdef CAN_ENCHANCED_MODE
228
            ECANCON = defECANCON;
229
        #else
230
            CANCON = defECANCON;
231
        #endif  
232
 
233
        PIR3bits.RXBnIF=0;
234
    }
235
 
236
}
237
/*
238
*   Function: canGetPacket
239
*
240
*   Input:  none
241
*   Output: none
242
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
243
*   Affects: Calls canParse() function in main for parsing received packet.
244
*   Depends: none.
245
*/
246
void canGetPacket()
247
{
248
        CAN_MESSAGE cm;
249
 
250
        // Set extended mode or not.
251
        cm.extended=RXB0SIDLbits.EXID;
252
 
253
        // Clear
254
        cm.ident[0]=cm.ident[1]=cm.ident[2]=cm.ident[3]=0;
255
 
256
 
257
        if (cm.extended==TRUE)
258
        {
259
            //Read extended ident.
260
            cm.ident[0]=RXB0EIDL;
261
            cm.ident[1]=RXB0EIDH;
262
            cm.ident[2]=(RXB0SIDL & 0b00000011)+((RXB0SIDL & 0b11100000)>3)+((RXB0SIDH & 0b00000111)<5);
263
            cm.ident[3]=RXB0SIDH>3;
264
        }
265
        else
266
        {
267
            //Read standard ident.
268
            cm.ident[0]=((RXB0SIDL & 0b11100000)>5)+(RXB0SIDH>2);
269
            cm.ident[1]=RXB0SIDH>5;
270
        }
271
 
272
        // Data length
273
        cm.data_length=RXB0DLC;
274
 
275
        // Data one bye one, for speed
276
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
277
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
278
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
279
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
280
 
281
 
282
        //Call main parser
283
        canParse(cm);
284
 
285
        //RXBnCON.RXFUL to know if there actually is a message.
286
        //RXB0 och RXB1 (0 <= n <= 1)
287
        //RXBnCON.FILHIT  do determine filter hit.
288
 
289
        //EXID =  1:extended frame
290
        //RXBnSIDH  = high standard ident (bit10->bit3 if standard, bit28->bit21 if ext)
291
        //RXBnSIDL(7:5) = low standard ident (bit2->bit0 if standard, bit20->bit18 if ext)
292
        //RXBnSIDL(1:0) = low standard ident (bit17->bit16 if ext)
293
        //RXBnEIDH      = high extended ident (bit15->bit8)
294
        //RXBnEIDL      = low extended ident (bit7->bit0)
295
        //RXBnDLC = Data length
296
        //RXBnDm = Data bytes. (0 <= m <= 7)
297
 
298
        // Same for Bn...  (1 <= n <= 5)
299
 
300
}
301
 
302
 
303
/*
304
*   Function: canSendMessage
305
*
306
*   Input:  CAN_MESSAGE to send
307
*   Output: True if packet scheduled sucess, false otherwise.
308
*   Pre-conditions: canInit
309
*   Affects: ..
310
*   Depends: ..
311
*/
312
BOOL canSendMessage(CAN_MESSAGE cm)
313
{
314
    BYTE defECANCON;
315
 
316
    // Save default ECANCON 
317
    #ifdef CAN_ENCHANCED_MODE
318
        defECANCON=(ECANCON&0b00000)|0b10000;
319
    #else
320
        defECANCON=(CANCON&0b000)|0b100;
321
    #endif
322
 
323
    // Find the first empty transmitter. 
324
    if ( TXB0CONbits.TXREQ == 0 )
325
    {
326
        // TxBuffer0 is empty. Set EWIN bits to point to TXB0 
327
        #ifdef CAN_ENCHANCED_MODE
328
            ECANCON=(defECANCON&0b00000)|0b00011;
329
        #else
330
            //CANCON=(defECANCON&0b000)|0b100;
331
        #endif
332
    }
333
    else if ( TXB1CONbits.TXREQ == 0 )
334
    {
335
        // TxBuffer1 is empty. Set EWIN bits to point to TXB1 
336
        #ifdef CAN_ENCHANCED_MODE
337
            ECANCON=(defECANCON&0b00000)|0b00100;
338
        #else
339
            //CANCON=(defECANCON&0b000)|0b011;
340
        #endif
341
    }
342
    else if ( TXB2CONbits.TXREQ == 0 )
343
    {
344
        // TxBuffer2 is empty. Set EWIN bits to point to TXB2 
345
        #ifdef CAN_ENCHANCED_MODE
346
            ECANCON=(defECANCON&0b00000)|0b00101;
347
        #else
348
            //CANCON=(defECANCON&0b000)|0b010;
349
        #endif
350
    }
351
    // None of the transmit buffers were empty. 
352
    else { return FALSE;}
353
 
354
 
355
 
356
        uartPutrs("Sending..");
357
 
358
        // Set extended mode or not.
359
        TXB0SIDLbits.EXIDE=cm.extended;
360
 
361
        if (cm.extended==TRUE)
362
        {
363
            //Write extended ident.
364
            TXB0SIDH=(cm.ident[3]<3)+(cm.ident[2]>5);
365
            TXB0SIDL=(TXB0SIDL & 0b00011100)+((cm.ident[2] & 0b0001100)<3)+(cm.ident[2] & 0b00000011);
366
            TXB0EIDH=cm.ident[1];
367
            TXB0EIDL=cm.ident[0];
368
        }
369
        else
370
        {
371
            //Write standard ident.
372
            TXB0SIDH=(cm.ident[1]<5)+(cm.ident[0]>3);
373
            TXB0SIDL=(TXB0SIDL & 0b00011111)+(cm.ident[0]<5);
374
        }
375
 
376
        // Data length
377
        if (cm.data_length>8) TXB0DLC=8; else TXB0DLC=cm.data_length;
378
 
379
        // Data one bye one, for speed
380
        TXB0D0=cm.data[0];  TXB0D1=cm.data[1];
381
        TXB0D2=cm.data[2];  TXB0D3=cm.data[3];
382
        TXB0D4=cm.data[4];  TXB0D5=cm.data[5];
383
        TXB0D6=cm.data[6];  TXB0D7=cm.data[7];
384
 
385
        // mark as redy to transmit
386
        TXB0CONbits.TXREQ=1;
387
 
388
        uartPutrs("While");
389
        while(TXB0CONbits.TXREQ);
390
        uartPutrs("after");
391
 
392
 
393
/*
394
        // Set extended mode or not.
395
        //RXB0SIDLbits.EXID=cm.extended;
396
        if (cm.extended==TRUE)
397
        {
398
            _asm
399
                bsf RXB0SIDL, 3, 0
400
            _endasm
401
        }
402
        else
403
        {
404
            _asm
405
                bcf RXB0SIDL, 3, 0
406
            _endasm
407
        }
408
 
409
 
410
        if (cm.extended==TRUE)
411
        {
412
            //Write extended ident.
413
            RXB0SIDH=(cm.ident[3]<3)+(cm.ident[2]>5);
414
            RXB0SIDL=(RXB0SIDL & 0b00011100)+((cm.ident[2] & 0b0001100)<3)+(cm.ident[2] & 0b00000011);
415
            RXB0EIDH=cm.ident[1];
416
            RXB0EIDL=cm.ident[0];
417
        }
418
        else
419
        {
420
            //Write standard ident.
421
            RXB0SIDH=(cm.ident[1]<5)+(cm.ident[0]>3);
422
            RXB0SIDL=(RXB0SIDL & 0b00011111)+(cm.ident[0]<5);
423
        }
424
 
425
        // Data length
426
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
427
 
428
        // Data one bye one, for speed
429
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
430
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
431
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
432
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
433
 
434
        // mark as redy to transmit
435
        _asm
436
            bsf RXB0CON, 3, 0
437
        _endasm
438
 
439
        // restore mapping
440
        #ifdef CAN_ENCHANCED_MODE
441
            ECANCON = defECANCON;
442
        #else
443
            CANCON = defECANCON;
444
        #endif
445
*/
446
 
447
 
448
 
449
 
450
        return TRUE;
451
 
452
}
453
 
454
 
455
#endif //USE_CAN