Subversion Repositories HomeAutomation

Rev

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

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