Subversion Repositories HomeAutomation

Rev

Rev 282 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

Rev 282 Rev 339
Line 2... Line 2...
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: 2007-02-03 16:58:13 +0100 (Sat, 03 Feb 2007) $
7
 * Last changed:    $LastChangedDate: 2007-02-25 20:51:08 +0100 (Sun, 25 Feb 2007) $
8
 * By:              $LastChangedBy: johboh $
8
 * By:              $LastChangedBy: johboh $
9
 * Revision:        $Revision: 282 $
9
 * Revision:        $Revision: 339 $
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>
Line 16... Line 16...
16
#include <funcdefs.h>
16
#include <funcdefs.h>
17
#include <Tick.h>
17
#include <Tick.h>
18
 
18
 
19
TICK heartbeat;
19
TICK heartbeat;
20
static int MY_ID = DEFAULT_ID;
20
static int MY_ID = DEFAULT_ID;
21
static BYTE MY_NID = DEFAULT_NID;
-
 
22
static CAN_MESSAGE outCm;
21
static CAN_PACKET outCp;
23
 
22
 
24
static void canGetPacket(void);
23
static void canGetPacket(void);
25
 
24
 
26
 
25
 
27
/*
26
/*
Line 119... Line 118...
119
 
118
 
120
 
119
 
121
    // Read ID and NID if exist.
120
    // Read ID and NID if exist.
122
    if (EERead(NODE_ID_EE)==NODE_HAS_ID)
121
    if (EERead(NODE_ID_EE)==NODE_HAS_ID)
123
    {
122
    {
124
        MY_ID=(((WORD)EERead(NODE_ID_EE + 1))<<8)+EERead(NODE_ID_EE + 2);
-
 
125
        MY_NID=EERead(NODE_ID_EE + 3);
123
        MY_ID=+EERead(NODE_ID_EE + 1);
126
    }
124
    }
127
 
125
 
128
    // Send user program startup heatbeat
126
    // Send user program startup heatbeat
-
 
127
    outCp.type=ptPGM;
129
    outCm.funct                     = FUNCT_BOOTLOADER;
128
    outCp.pgm.class=pcCTRL;
130
    outCm.funcc                     = FUNCC_BOOT_HEARTBEAT;
129
    outCp.pgm.id=pctAPPBOOT;
131
    outCm.data_length               = 1;
130
    outCp.length=0;
132
    outCm.data[BOOT_DATA_HEARTBEAT_INDEX] = HEARTBEAT_USER_STARTUP;
-
 
133
    canSendMessage(outCm,PRIO_HIGH);
131
    while(!canSendMessage(outCp,PRIO_HIGH));
134
 
-
 
135
}
132
}
136
 
133
 
137
 
134
 
138
/*
135
/*
139
*   Function: canISR
136
*   Function: canISR
140
*
137
*
141
*   Input:  none
138
*   Input:  none
Line 144... Line 141...
144
*   Affects: interrupt registers and receive data buffers
141
*   Affects: interrupt registers and receive data buffers
145
*   Depends: ..
142
*   Depends: ..
146
*/
143
*/
147
void canISR()
144
void canISR()
148
{
145
{
-
 
146
    ClrWdt();
-
 
147
 
149
    if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
148
    if (PIR3bits.RXBnIF || PIR3bits.RXB1IF || PIR3bits.RXB0IF)
150
    {
149
    {
151
        ECANCON=(ECANCON&0b00000)|(0b10000|(CANCON&0x0F));
150
        ECANCON=(ECANCON&0b00000)|(0b10000|(CANCON&0x0F));
152
        if (RXB0CONbits.RXFUL) canGetPacket();
151
        if (RXB0CONbits.RXFUL) canGetPacket();
153
   
152
   
154
        if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0; return;}
153
        if (PIR3bits.RXBnIF) {PIR3bits.RXBnIF = 0; return;}
155
        if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0; return;}
154
        if (PIR3bits.RXB1IF) {PIR3bits.RXB1IF = 0; return;}
Line 159... Line 158...
159
    tickUpdate();
158
    tickUpdate();
160
 
159
 
161
    if ((tickGet()-heartbeat)>TICK_SECOND*5)
160
    if ((tickGet()-heartbeat)>TICK_SECOND*5)
162
    {
161
    {
163
        // Send alive heartbeat
162
        // Send alive heartbeat
-
 
163
        outCp.type=ptPGM;
164
        outCm.funct                     = FUNCT_BOOTLOADER;
164
        outCp.pgm.class=pcCTRL;
165
        outCm.funcc                     = FUNCC_BOOT_HEARTBEAT;
165
        outCp.pgm.id=pctHEARTBEAT;
166
        outCm.data_length               = 1;
166
        outCp.length=0;
167
        outCm.data[BOOT_DATA_HEARTBEAT_INDEX] = HEARTBEAT_ALIVE;
-
 
168
        canSendMessage(outCm,PRIO_HIGH);
167
        canSendMessage(outCp,PRIO_HIGH);
169
           
168
           
170
        heartbeat = tickGet();
169
        heartbeat = tickGet();
171
    }
170
    }
172
 
171
 
173
    ClrWdt();
172
   
174
}
173
}
175
 
174
 
176
 
175
 
177
/*
176
/*
178
*   Function: canGetPacket
177
*   Function: canGetPacket
179
*
178
*
180
*   Input:  none
179
*   Input:  none
181
*   Output: none
180
*   Output: none
182
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
181
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
183
*   Affects: Calls canParse() function in main for parsing received packet.
182
*   Affects: Calls canParse() function in main for parsing received packet.
184
*   Depends: none.
183
*   Depends: none.
185
*/
184
*/
186
void canGetPacket()
185
void canGetPacket()
187
{
186
{
188
        CAN_MESSAGE cm;
187
        CAN_PACKET cp;
189
 
188
 
190
        //RXB0SIDH 28 27 26 25 24 23 22 21
189
        //RXB0SIDH 28 27 26 25 24 23 22 21
191
        //RXB0SIDL 20 19 18 xx xx xx 17 16
190
        //RXB0SIDL 20 19 18 xx xx xx 17 16
192
        //RXB0EIDH 15 14 13 12 11 10 09 08
191
        //RXB0EIDH 15 14 13 12 11 10 09 08
193
        //RXB0EIDL 07 06 05 04 03 02 01 00
192
        //RXB0EIDL 07 06 05 04 03 02 01 00
-
 
193
 
194
 
194
 
195
        //funct xx xx xx xx 28 27 26 25
195
        cp.type = ((RXB0SIDH&0xC)>>6);
196
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
-
 
197
        //nid   xx xx 14 13 12 11 10 09 
-
 
198
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
-
 
199
 
196
 
200
 
197
 
-
 
198
        if (cp.type==ptBOOT)
-
 
199
        {
201
        cm.funct=((RXB0SIDH & 0xF0)>>4);
200
            cp.boot.type  = ((RXB0SIDH&0x38)>>3);
202
        cm.funcc=(((WORD)(RXB0SIDH & 0x0F))<<6)+(((WORD)(RXB0SIDL & 0xE0))>>2)+(((WORD)(RXB0SIDL & 0x03))<<1)+(((WORD)(RXB0EIDH & 0x80))>>7);
201
            cp.boot.offset= ((RXB0SIDH&0x7)<<5)+((RXB0SIDL&0xE0)>>3)+(RXB0SIDL&0x3);
-
 
202
            cp.boot.rid   = RXB0EIDH;
-
 
203
        }
-
 
204
        else
-
 
205
        {
203
        cm.nid=((RXB0EIDH & 0x7E)>>1);
206
            cp.pgm.class= ((RXB0SIDH&0x3C)>>2);
204
        cm.sid=(((WORD)(RXB0EIDH & 0x01))<<8)+RXB0EIDL;
207
            cp.pgm.id   = (((WORD)RXB0SIDH&0x3)<<13)+(((WORD)RXB0SIDL&0xE0)<<5)+((RXB0SIDL&0x3)<<8)+RXB0EIDH;
-
 
208
        }
-
 
209
        cp.sid   = RXB0EIDL;
205
 
210
 
206
 
211
 
207
        // Data length
212
        // Data length
208
        cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
213
        cp.length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
209
 
214
 
210
        // Data one bye one, for speed
215
        // Data one bye one, for speed
211
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
216
        cp.data[0]=RXB0D0;  cp.data[1]=RXB0D1;
212
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
217
        cp.data[2]=RXB0D2;  cp.data[3]=RXB0D3;
213
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
218
        cp.data[4]=RXB0D4;  cp.data[5]=RXB0D5;
214
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
219
        cp.data[6]=RXB0D6;  cp.data[7]=RXB0D7;
215
 
220
 
216
        // Clear ful status
221
        // Clear ful status
217
        RXB0CONbits.RXFUL=0;
222
        RXB0CONbits.RXFUL=0;
218
 
223
 
219
 
224
 
220
 
225
 
221
        // Check if FUNCT_BOOTLOADER specific.
226
        // Check if bootloader request specific.
222
        // reset and id change
227
        // reset and id change
223
        if (cm.funct==FUNCT_BOOTLOADER)
228
        if (cp.type==ptBOOT)
224
        {
-
 
225
            if (cm.nid==MY_NID && ((((unsigned int)cm.data[BOOT_DATA_RID_HIGH_INDEX])<<8)+cm.data[BOOT_DATA_RID_LOW_INDEX])==MY_ID)
-
 
226
            {
229
        {
-
 
230
            if (cp.boot.rid==MY_ID)
-
 
231
            {
227
                if (cm.funcc==FUNCC_BOOT_INIT) Reset(); // Reset me.
232
                if (cp.boot.type==btADDR) Reset(); // Reset me.
228
                if (cm.funcc==FUNCC_BOOT_SET_ID)
233
                if (cp.boot.type==btCHANGEID)
229
                {
234
                {
230
                        // Change my ID and NID
235
                        // Change my ID and NID
231
                        MY_ID=(((WORD)cm.data[BOOT_DATA_NEW_ID_HIGH_INDEX])<<8)+cm.data[BOOT_DATA_NEW_ID_LOW_INDEX];
-
 
232
                        MY_NID=cm.data[BOOT_DATA_NEW_NID_INDEX];
236
                        MY_ID=cp.data[0];
233
                        EEWrite(NODE_ID_EE+1,cm.data[BOOT_DATA_NEW_ID_HIGH_INDEX]);
-
 
234
                        EEWrite(NODE_ID_EE+2,cm.data[BOOT_DATA_NEW_ID_LOW_INDEX]);
-
 
235
                        EEWrite(NODE_ID_EE+3,cm.data[BOOT_DATA_NEW_NID_INDEX]);
237
                        EEWrite(NODE_ID_EE+1,cp.data[0]);
236
                        EEWrite(NODE_ID_EE,NODE_HAS_ID);
238
                        EEWrite(NODE_ID_EE,NODE_HAS_ID);
237
                        // Send ack with new id.
239
                        // Send ack with new id.
238
                        outCm.funct                     = FUNCT_BOOTLOADER;
240
                        outCp.type=ptBOOT;
239
                        outCm.funcc                     = FUNCC_BOOT_ACK;
241
                        outCp.boot.type=btACK;
240
                        outCm.data_length               = 8;
242
                        outCp.length=0;
241
                        outCm.data[BOOT_DATA_ERR_INDEX] = ACK_ERR_NO_ERROR;
-
 
242
                        while(!canSendMessage(outCm,PRIO_HIGH));
243
                        while(!canSendMessage(outCp,PRIO_HIGH));
243
                }
244
                }
244
            }
245
            }
245
        }
246
        }
246
 
247
 
247
 
248
 
248
        //Call main parser
249
        //Call main parser
249
        canParse(cm);
250
        if (cp.type==ptPGM) canParse(cp);
250
}
251
}
251
 
252
 
252
 
253
 
253
/*
254
/*
254
*   Function: canSendMessage
255
*   Function: canSendMessage
Line 257... Line 258...
257
*   Output: True if packet scheduled sucess, false otherwise.
258
*   Output: True if packet scheduled sucess, false otherwise.
258
*   Pre-conditions: canInit
259
*   Pre-conditions: canInit
259
*   Affects: ..
260
*   Affects: ..
260
*   Depends: ..
261
*   Depends: ..
261
*/
262
*/
262
BOOL canSendMessage(CAN_MESSAGE cm,CAN_PRIORITY prio)
263
BOOL canSendMessage(CAN_PACKET cp, CAN_PRIORITY prio)
263
{
264
{
264
   
265
   
265
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
266
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
266
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
267
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
267
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
268
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
268
    // None of the transmit buffers were empty. 
269
    // None of the transmit buffers were empty. 
269
    else { return FALSE;}
270
    else { return FALSE;}
270
 
271
 
271
    if (prio<0 || prio>3) prio = 0;
272
    if (prio<0 || prio>3) prio = 0;
272
 
-
 
273
        // Append my id and nid
-
 
274
        cm.nid  = MY_NID;
-
 
275
        cm.sid  = MY_ID;
-
 
276
 
273
 
277
 
274
 
278
        //RXB0SIDH 28 27 26 25 24 23 22 21
275
    //RXB0SIDH 28 27 26 25 24 23 22 21
279
        //RXB0SIDL 20 19 18 xx xx xx 17 16
276
    //RXB0SIDL 20 19 18 xx xx xx 17 16
280
        //RXB0EIDH 15 14 13 12 11 10 09 08
277
    //RXB0EIDH 15 14 13 12 11 10 09 08
281
        //RXB0EIDL 07 06 05 04 03 02 01 00
278
    //RXB0EIDL 07 06 05 04 03 02 01 00
282
 
279
 
283
        //funct xx xx xx xx 28 27 26 25
-
 
284
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
-
 
285
        //nid   xx xx 14 13 12 11 10 09 
-
 
286
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
-
 
287
 
280
 
-
 
281
    if (cp.type==ptBOOT)
-
 
282
    {
288
        RXB0SIDH = (BYTE)((cm.funct & 0x0F)<<4)+(BYTE)((cm.funcc & 0x03C0)>>6);
283
        RXB0SIDH = ((cp.type&0x3)<<6)+((cp.boot.type&0x7)<<3)+((cp.boot.offset&0xE0)>>5);
289
        RXB0SIDL = (BYTE)((cm.funcc & 0x003F)<<2)+(BYTE)((cm.funcc & 0x0006)>>1);
284
        RXB0SIDL = ((cp.boot.offset&0x1C)<<3)+(cp.boot.offset&0x3);
-
 
285
        RXB0EIDH = cp.boot.rid;
-
 
286
    }
-
 
287
    else
-
 
288
    {
290
        RXB0EIDH = (BYTE)((cm.funcc & 0x0001)<<7)+(BYTE)((cm.nid & 0x3F)<<1)+(BYTE)((cm.sid & 0x0100)>>8);
289
        RXB0SIDH = ((cp.type&0x3)<<6)+((cp.pgm.class&0xF)<<2)+((cp.pgm.id&0x6000)>>13);
-
 
290
        RXB0SIDL = ((cp.pgm.id&0x1C00)>>5)+((cp.pgm.id&0x300)>>8);
291
        RXB0EIDL = (BYTE)((cm.sid & 0x00FF));
291
        RXB0EIDH = (cp.pgm.id&0xFF);
-
 
292
    }
-
 
293
    RXB0EIDL = MY_ID;
292
 
294
 
293
        // Data length
295
    // Data length
294
        RXB0DLC = 0;
296
    RXB0DLC = 0;
295
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
297
    if (cp.length>8) RXB0DLC=8; else RXB0DLC=cp.length;
296
       
298
   
297
 
-
 
298
        // NOT Remote request
299
    // NOT Remote request
299
        _asm
300
    _asm
300
            bcf RXB0DLC, 6, 0
301
        bcf RXB0DLC, 6, 0
301
        _endasm
302
    _endasm
302
       
303
   
303
 
304
   
304
        // Data one bye one, for speed
305
    // Data one bye one, for speed
305
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
306
    RXB0D0=cp.data[0];  RXB0D1=cp.data[1];
306
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
307
    RXB0D2=cp.data[2];  RXB0D3=cp.data[3];
307
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
308
    RXB0D4=cp.data[4];  RXB0D5=cp.data[5];
308
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
309
    RXB0D6=cp.data[6];  RXB0D7=cp.data[7];
309
 
-
 
310
        // set extended
310
    // set extended
311
        RXB0SIDLbits.EXID=1;
311
    RXB0SIDLbits.EXID=1;
312
 
312
   
313
        // Priority
313
    // Priority
314
        RXB0CON = (RXB0CON & 0b11111100) | prio;
314
    RXB0CON = (RXB0CON & 0b11111100) | prio;