Subversion Repositories HomeAutomation

Rev

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

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