Subversion Repositories HomeAutomation

Rev

Rev 73 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 73 Rev 97
1
/*********************************************************************
1
/*********************************************************************
2
 *
2
 *
3
 *                  CAN driver
3
 *                  CAN driver
4
 *
4
 *
5
 *********************************************************************
5
 *********************************************************************
6
 * FileName:        CAN.c
6
 * FileName:        $HeadURL: https://svn.auml.se/svn/HomeAutomation/trunk/EmbeddedSoftware/PIC/canToSerial/Source/CAN.c $
7
 *
-
 
8
 * Author               Date    Comment
7
 * Last changed:    $LastChangedDate: 2006-11-14 21:22:17 +0100 (Tue, 14 Nov 2006) $
9
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
8
 * By:              $LastChangedBy: johboh $
10
 * Johan Böhlin     21-10-06    Original        (Rev 1.0)
9
 * Revision:        $Revision: 97 $
11
 ********************************************************************/
10
 ********************************************************************/
12
 
11
 
13
#include <CANdefs.h>
12
#include <CANdefs.h>
14
#include <stackTasks.h>
13
#include <stackTasks.h>
15
#include <CAN.h>
14
#include <CAN.h>
16
 
15
 
17
static void canGetPacket(void);
16
static void canGetPacket(void);
18
 
17
 
19
#ifdef USE_CAN
18
#ifdef USE_CAN
20
 
19
 
21
 
20
 
22
/*
21
/*
23
*   Function: canInit
22
*   Function: canInit
24
*
23
*
25
*   Input:  none
24
*   Input:  none
26
*   Output: none
25
*   Output: none
27
*   Pre-conditions: none
26
*   Pre-conditions: none
28
*   Affects: Changes can registers.
27
*   Affects: Changes can registers.
29
*   Depends: none.
28
*   Depends: none.
30
*/
29
*/
31
void canInit()
30
void canInit()
32
{
31
{
33
    CANCON = 0x80; //request config mode
32
    CANCON = 0x80; //request config mode
34
    while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
33
    while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
35
 
34
 
36
    // BAUD AND TQS
35
    // BAUD AND TQS
37
 
36
 
38
    BRGCON1=0;
37
    BRGCON1=0;
39
   
38
   
40
    // Sync_Seq = 2 x TQ = 1
39
    // Sync_Seq = 2 x TQ = 1
41
    BRGCON1bits.SJW1=0;
40
    BRGCON1bits.SJW1=0;
42
    BRGCON1bits.SJW0=1;
41
    BRGCON1bits.SJW0=1;
43
   
42
   
44
    // Setting BRP.
43
    // Setting BRP.
45
    BRGCON1=BRGCON1|CAN_BRP;
44
    BRGCON1=BRGCON1|CAN_BRP;
46
   
45
   
47
    // Maximum PHEG1
46
    // Maximum PHEG1
48
    BRGCON2bits.SEG2PHTS = 1;
47
    BRGCON2bits.SEG2PHTS = 1;
49
   
48
   
50
    // Phase_Seg1 = 2 x TQ = 1
49
    // Phase_Seg1 = 2 x TQ = 1
51
    BRGCON2bits.SEG1PH2 = 0;
50
    BRGCON2bits.SEG1PH2 = 0;
52
    BRGCON2bits.SEG1PH1 = 0;
51
    BRGCON2bits.SEG1PH1 = 0;
53
    BRGCON2bits.SEG1PH0 = 1;
52
    BRGCON2bits.SEG1PH0 = 1;
54
   
53
   
55
    // Prop_Seq = 2 x TQ = 1
54
    // Prop_Seq = 2 x TQ = 1
56
    BRGCON2bits.PRSEG2 = 0;
55
    BRGCON2bits.PRSEG2 = 0;
57
    BRGCON2bits.PRSEG1 = 0;
56
    BRGCON2bits.PRSEG1 = 0;
58
    BRGCON2bits.PRSEG0 = 1;
57
    BRGCON2bits.PRSEG0 = 1;
59
   
58
   
60
    //  Enableing bus wake-up
59
    //  Enableing bus wake-up
61
    BRGCON3bits.WAKDIS = 0;
60
    BRGCON3bits.WAKDIS = 0;
62
   
61
   
63
    // Dont use filter when wakeup
62
    // Dont use filter when wakeup
64
    BRGCON3bits.WAKFIL = 0;
63
    BRGCON3bits.WAKFIL = 0;
65
   
64
   
66
    // Phase_Seg2 = 2 x TQ = 1
65
    // Phase_Seg2 = 2 x TQ = 1
67
    BRGCON3bits.SEG2PH2 = 0;
66
    BRGCON3bits.SEG2PH2 = 0;
68
    BRGCON3bits.SEG2PH1 = 0;
67
    BRGCON3bits.SEG2PH1 = 0;
69
    BRGCON3bits.SEG2PH0 = 1;
68
    BRGCON3bits.SEG2PH0 = 1;
70
 
69
 
71
    ECANCON=0;
70
    ECANCON=0;
72
    ECANCONbits.MDSEL1 = 0;
71
    ECANCONbits.MDSEL1 = 1;
73
    ECANCONbits.MDSEL0 = 1;
72
    ECANCONbits.MDSEL0 = 0;
74
 
73
 
75
 
74
 
76
    // FILTERS AND MASKS
75
    // FILTERS AND MASKS
77
    RXB0CONbits.RXM1=1;
76
    RXB0CONbits.RXM1=1;
78
    RXB0CONbits.RXM0=0;
77
    RXB0CONbits.RXM0=0;
79
 
78
 
80
 
79
 
81
    // INTERRUPTS
80
    // INTERRUPTS
82
   
81
   
83
    // Diable transmit interrupt
82
    // Diable transmit interrupt
84
    TXBIE = 0;
83
    TXBIE = 0;
85
 
84
 
86
    //rx any interrupt
85
    //rx any interrupt
87
    PIR3 = 0;
86
    PIR3 = 0;
88
    PIE3 = 0b00000011;
87
    PIE3 = 0b00000011;
89
 
88
 
90
    // High interrupt
89
    // High interrupt
91
    IPR3 =0b00000011;
90
    IPR3 =0b00000011;
92
 
91
 
93
    // Programmable buffers interrupt
92
    // Programmable buffers interrupt
94
    BIE0  = 0xFF;  
93
    BIE0  = 0xFF;  
95
 
94
 
96
 
95
 
97
    //loopback mode or not
96
    //loopback mode or not
98
    #ifdef CAN_LOOPBACK_MODE
97
    #ifdef CAN_LOOPBACK_MODE
99
        CANCON = 0x40;//request loopback mode
98
        CANCON = 0x40;//request loopback mode
100
        while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
99
        while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
101
    #else
100
    #else
102
        CANCON = 0x00;//request normal mode
101
        CANCON = 0x00;//request normal mode
103
        while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
102
        while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
104
    #endif
103
    #endif
105
 
104
 
106
}
105
}
107
 
106
 
108
 
107
 
109
/*
108
/*
110
*   Function: canISR
109
*   Function: canISR
111
*
110
*
112
*   Input:  none
111
*   Input:  none
113
*   Output: none
112
*   Output: none
114
*   Pre-conditions: a call to canInit()
113
*   Pre-conditions: a call to canInit()
115
*   Affects: interrupt registers and receive data buffers
114
*   Affects: interrupt registers and receive data buffers
116
*   Depends: ..
115
*   Depends: ..
117
*/
116
*/
118
void canISR()
117
void canISR()
119
{
118
{
120
   
-
 
121
 
-
 
122
    if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
119
    if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
123
    {
120
    {
124
        // Get which buffer that is ful.
-
 
125
             if (RXB0CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10000; canGetPacket(); }
121
        ECANCON=(ECANCON&0b00000)|(0b10000|(CANCON&0x0F));
126
        else if (RXB1CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10001; canGetPacket(); }
122
        if (RXB0CONbits.RXFUL) canGetPacket();
127
        else if (B0CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10010; canGetPacket(); }
-
 
128
        else if (B1CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10011; canGetPacket(); }
-
 
129
        else if (B2CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10100; canGetPacket(); }
-
 
130
        else if (B3CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10101; canGetPacket(); }
-
 
131
        else if (B4CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10110; canGetPacket(); }
-
 
132
        else if (B5CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10111; canGetPacket(); }
-
 
133
   
-
 
134
        if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0;}
-
 
135
        if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0;}
-
 
136
        if (PIR3bits.RXB0IF) {PIR3bits.RXB0IF = 0;}
-
 
137
   
123
   
-
 
124
        if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0; return;}
-
 
125
        if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0; return;}
-
 
126
        if (PIR3bits.RXB0IF) {PIR3bits.RXB0IF = 0; return;}
138
    }
127
    }
139
}
128
}
140
 
129
 
141
 
130
 
142
/*
131
/*
143
*   Function: canGetPacket
132
*   Function: canGetPacket
144
*
133
*
145
*   Input:  none
134
*   Input:  none
146
*   Output: none
135
*   Output: none
147
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
136
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
148
*   Affects: Calls canParse() function in main for parsing received packet.
137
*   Affects: Calls canParse() function in main for parsing received packet.
149
*   Depends: none.
138
*   Depends: none.
150
*/
139
*/
151
void canGetPacket()
140
void canGetPacket()
152
{
141
{
153
        CAN_MESSAGE cm;
142
        CAN_MESSAGE cm;
154
 
143
 
155
        // Set extended mode or not.
144
        // Set extended mode or not.
156
        cm.extended=(RXB0SIDLbits.EXID==0?FALSE:TRUE);
145
        cm.extended=(RXB0SIDLbits.EXID==0?FALSE:TRUE);
157
 
146
 
158
        // Clear
147
        // Clear
159
        cm.ident=0;
148
        cm.ident=0;
160
 
149
 
161
 
150
 
162
        if (cm.extended==TRUE)
151
        if (cm.extended==TRUE)
163
        {
152
        {
164
            //Read extended ident.
153
            //Read extended ident.
165
 
154
 
166
            //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
155
            //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
167
 
156
 
168
            //RXB0SIDH 28 27 26 25 24 23 22 21
157
            //RXB0SIDH 28 27 26 25 24 23 22 21
169
            //RXB0SIDL 20 19 18 xx xx xx 17 16
158
            //RXB0SIDL 20 19 18 xx xx xx 17 16
170
            //RXB0EIDH 15 14 13 12 11 10 09 08
159
            //RXB0EIDH 15 14 13 12 11 10 09 08
171
            //RXB0EIDL 07 06 05 04 03 02 01 00
160
            //RXB0EIDL 07 06 05 04 03 02 01 00
172
 
161
 
173
 
162
 
174
            cm.ident = (((DWORD)RXB0SIDH)<<21) + (((DWORD)(RXB0SIDL & 0xE0))<<13) + (((DWORD)(RXB0SIDL & 0x03))<<16) + (((DWORD)RXB0EIDH)<<8) + (BYTE)RXB0EIDL;
163
            cm.ident = (((DWORD)RXB0SIDH)<<21) + (((DWORD)(RXB0SIDL & 0xE0))<<13) + (((DWORD)(RXB0SIDL & 0x03))<<16) + (((DWORD)RXB0EIDH)<<8) + (BYTE)RXB0EIDL;
175
 
164
 
176
        }
165
        }
177
        else
166
        else
178
        {
167
        {
179
            //Read standard ident.
168
            //Read standard ident.
180
 
169
 
181
            //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
170
            //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
182
 
171
 
183
            //RXB0SIDH 10 09 08 07 06 05 04 03
172
            //RXB0SIDH 10 09 08 07 06 05 04 03
184
            //RXB0SIDL 02 01 00 xx xx xx xx xx
173
            //RXB0SIDL 02 01 00 xx xx xx xx xx
185
 
174
 
186
            cm.ident = (((DWORD)RXB0SIDH)<<3) + (((DWORD)RXB0SIDL)>>5);
175
            cm.ident = (((DWORD)RXB0SIDH)<<3) + (((DWORD)RXB0SIDL)>>5);
187
        }
176
        }
188
 
177
 
189
        // Data length
178
        // Data length
190
        cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
179
        cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
191
 
180
 
192
        // Remote request
181
        // Remote request
193
        cm.remote_request=(RXB0DLCbits.RXRTR==0?FALSE:TRUE);
182
        cm.remote_request=(RXB0DLCbits.RXRTR==0?FALSE:TRUE);
194
 
183
 
195
        // Data one bye one, for speed
184
        // Data one bye one, for speed
196
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
185
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
197
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
186
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
198
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
187
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
199
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
188
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
200
 
189
 
201
        // Clear ful status
190
        // Clear ful status
202
        RXB0CONbits.RXFUL=0;
191
        RXB0CONbits.RXFUL=0;
203
 
192
 
204
        //Call main parser
193
        //Call main parser
205
        canParse(cm);
194
        canParse(cm);
206
}
195
}
207
 
196
 
208
 
197
 
209
/*
198
/*
210
*   Function: canSendMessage
199
*   Function: canSendMessage
211
*
200
*
212
*   Input:  CAN_MESSAGE to send
201
*   Input:  CAN_MESSAGE to send
213
*   Output: True if packet scheduled sucess, false otherwise.
202
*   Output: True if packet scheduled sucess, false otherwise.
214
*   Pre-conditions: canInit
203
*   Pre-conditions: canInit
215
*   Affects: ..
204
*   Affects: ..
216
*   Depends: ..
205
*   Depends: ..
217
*/
206
*/
218
BOOL canSendMessage(CAN_MESSAGE cm,CAN_PRIORITY prio)
207
BOOL canSendMessage(CAN_MESSAGE cm,CAN_PRIORITY prio)
219
{
208
{
220
   
209
   
221
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
210
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
222
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
211
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
223
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
212
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
224
    // None of the transmit buffers were empty. 
213
    // None of the transmit buffers were empty. 
225
    else { return FALSE;}
214
    else { return FALSE;}
226
 
215
 
227
    if (prio<0 || prio>3) prio = 0;
216
    if (prio<0 || prio>3) prio = 0;
228
 
217
 
229
 
218
 
230
        if (cm.extended==TRUE)
219
        if (cm.extended==TRUE)
231
        {
220
        {
232
            //Write extended ident.
221
            //Write extended ident.
233
   
222
   
234
            //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
223
            //xx xx xx 28 27 26 25 24   23 22 21 20 19 18 17 16   15 14 13 12 11 10 09 08   07 06 05 04 03 02 01 00
235
 
224
 
236
            //RXB0SIDH 28 27 26 25 24 23 22 21
225
            //RXB0SIDH 28 27 26 25 24 23 22 21
237
            //RXB0SIDL 20 19 18 xx xx xx 17 16
226
            //RXB0SIDL 20 19 18 xx xx xx 17 16
238
            //RXB0EIDH 15 14 13 12 11 10 09 08
227
            //RXB0EIDH 15 14 13 12 11 10 09 08
239
            //RXB0EIDL 07 06 05 04 03 02 01 00
228
            //RXB0EIDL 07 06 05 04 03 02 01 00
240
 
229
 
241
 
230
 
242
            RXB0SIDH =  (BYTE)((cm.ident>>21));
231
            RXB0SIDH =  (BYTE)((cm.ident>>21));
243
            RXB0SIDL = ((BYTE)(cm.ident>>16) & 0x03) + ((BYTE)(cm.ident>>13) & 0xE0);
232
            RXB0SIDL = ((BYTE)(cm.ident>>16) & 0x03) + ((BYTE)(cm.ident>>13) & 0xE0);
244
            RXB0EIDH =  (BYTE)(cm.ident>>8);
233
            RXB0EIDH =  (BYTE)(cm.ident>>8);
245
            RXB0EIDL =  (BYTE)cm.ident;
234
            RXB0EIDL =  (BYTE)cm.ident;
246
 
235
 
247
        }
236
        }
248
        else
237
        else
249
        {
238
        {
250
            //Write standard ident.
239
            //Write standard ident.
251
       
240
       
252
            //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
241
            //xx xx xx xx xx 10 09 08   07 06 05 04 03 02 01 00
253
 
242
 
254
            //RXB0SIDH 10 09 08 07 06 05 04 03
243
            //RXB0SIDH 10 09 08 07 06 05 04 03
255
            //RXB0SIDL 02 01 00 xx xx xx xx xx
244
            //RXB0SIDL 02 01 00 xx xx xx xx xx
256
 
245
 
257
            RXB0SIDH=  (BYTE)(cm.ident>>3);
246
            RXB0SIDH=  (BYTE)(cm.ident>>3);
258
            RXB0SIDL= ((BYTE)(cm.ident<<5) & 0xE0);
247
            RXB0SIDL= ((BYTE)(cm.ident<<5) & 0xE0);
259
 
248
 
260
        }
249
        }
261
 
250
 
262
        // Data length
251
        // Data length
263
        RXB0DLC = 0;
252
        RXB0DLC = 0;
264
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
253
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
265
       
254
       
266
        // Remote request
255
        // Remote request
267
        if (cm.remote_request==TRUE)
256
        if (cm.remote_request==TRUE)
268
        {
257
        {
269
            _asm
258
            _asm
270
                bsf RXB0DLC, 6, 0
259
                bsf RXB0DLC, 6, 0
271
            _endasm
260
            _endasm
272
        }
261
        }
273
        else
262
        else
274
        {
263
        {
275
            _asm
264
            _asm
276
                bcf RXB0DLC, 6, 0
265
                bcf RXB0DLC, 6, 0
277
            _endasm
266
            _endasm
278
        }
267
        }
279
 
268
 
280
        // Data one bye one, for speed
269
        // Data one bye one, for speed
281
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
270
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
282
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
271
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
283
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
272
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
284
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
273
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
285
 
274
 
286
        // set extended or not
275
        // set extended or not
287
        RXB0SIDLbits.EXID=(cm.extended==TRUE?1:0);
276
        RXB0SIDLbits.EXID=(cm.extended==TRUE?1:0);
288
 
277
 
289
        // Priority
278
        // Priority
290
        RXB0CON = (RXB0CON & 0b11111100) | prio;
279
        RXB0CON = (RXB0CON & 0b11111100) | prio;
291
 
280
 
292
        // mark as redy to transmit
281
        // mark as redy to transmit
293
        _asm
282
        _asm
294
            bsf RXB0CON, 3, 0
283
            bsf RXB0CON, 3, 0
295
        _endasm
284
        _endasm
296
 
285
 
297
        return TRUE;
286
        return TRUE;
298
 
287
 
299
}
288
}
300
 
289
 
301
 
290
 
302
 
291
 
303
#endif //USE_CAN
292
#endif //USE_CAN
304
 
293