Subversion Repositories HomeAutomation

Rev

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

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