Subversion Repositories HomeAutomation

Rev

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

Rev 56 Rev 64
Line 10... Line 10...
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 <compiler.h>
13
#include <compiler.h>
14
#include <stackTasks.h>
14
#include <stackTasks.h>
-
 
15
#include <CANdefs.h>
-
 
16
#include <CAN.h>
-
 
17
#include <Tick.h>
15
 
18
 
16
#ifdef USE_CAN
19
#ifdef USE_CAN
17
    #include <CAN.h>
20
    #include <CAN.h>
18
#endif
21
#endif
19
 
22
 
-
 
23
static CAN_PROTO_MESSAGE cm;
-
 
24
static BYTE ful=0;
-
 
25
static DWORD cnt =0;
-
 
26
 
20
static void mainInit(void);
27
static void mainInit(void);
-
 
28
static BOOL canGetPacket(void);
21
 
29
 
-
 
30
#define PACKET_TIMEOUT (TICK_SECOND/20)
-
 
31
#define BOOTLOADER_INIT_TIMOUT (TICK_SECOND*5)
-
 
32
 
22
void main()
33
void main()
23
{
34
{
-
 
35
    static PROGRAM_STATE pgs = pgsWATING_START;
-
 
36
    static TICK t = 0;
-
 
37
    static WORD programmerSid=0;
-
 
38
   
-
 
39
    static BYTE errMsg = ERR_NO_ERROR;
-
 
40
    static PROGRAM_STATE afterAckPgs = pgsWATING_START;
-
 
41
    static DWORD pgmAddress = 0;
-
 
42
    static BYTE bytesReceived = 0;
-
 
43
 
-
 
44
    static BYTE tmp;
24
 
45
 
25
    // Inits
46
    // Inits
26
 
47
 
27
    mainInit();
48
    mainInit();
28
 
49
 
29
    #ifdef USE_CAN
50
    #ifdef USE_CAN
30
        canInit();
51
        canInit();
31
    #endif
52
    #endif
-
 
53
 
-
 
54
 
-
 
55
 
-
 
56
    tickInit();
32
 
57
 
-
 
58
   
33
 
59
 
34
    while(1)
60
    for(;;)
35
    {
61
    {
-
 
62
        CAN_PROTO_MESSAGE outCm;
-
 
63
        BOOL hasPacket = canGetPacket();
-
 
64
 
-
 
65
        if (hasPacket)
-
 
66
        {
-
 
67
                tmp=5;
-
 
68
        }
-
 
69
 
-
 
70
        switch(pgs)
-
 
71
        {
-
 
72
            case pgsWATING_START:
-
 
73
                // Check if there is bootloader start packet
-
 
74
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_INIT && cm.data[RID_INDEX]==MY_ID && cm.nid==MY_NID)
-
 
75
                {
-
 
76
                    // Has new start packet
-
 
77
                    pgmAddress      = (((DWORD)cm.data[ADDRU_INDEX])<<16)+(((DWORD)cm.data[ADDRH_INDEX])<<8)+((DWORD)cm.data[ADDRL_INDEX]);
-
 
78
                    programmerSid   = cm.sid;
-
 
79
                    t               = tickGet();
-
 
80
                    errMsg          = ERR_NO_ERROR;
-
 
81
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
-
 
82
                    pgs             = pgsSEND_ACK;
-
 
83
                }
-
 
84
 
-
 
85
                // TODO TIMEOUT!
-
 
86
                // tBoot = tickGet();
-
 
87
                // if ((tickGet()-tBoot)>BOOTLOADER_INIT_TIMOUT) goto userprgm;
-
 
88
            break;         
-
 
89
 
-
 
90
            case pgsSEND_ACK:
-
 
91
                // send ack
-
 
92
                outCm.funct             = FUNCT_BOOTLOADER;
-
 
93
                outCm.funcc             = FUNCC_BOOT_ACK;
-
 
94
                outCm.nid               = MY_NID;
-
 
95
                outCm.sid               = MY_ID;
-
 
96
                outCm.data_length       = 8;
-
 
97
                outCm.remote_request    = FALSE;
-
 
98
                outCm.data[ERR_INDEX]   = errMsg;
-
 
99
                t                       = tickGet();
-
 
100
                pgs                     = afterAckPgs;
-
 
101
 
-
 
102
                while(!canSendMessage(outCm,PRIO_HIGH));
-
 
103
            break;
-
 
104
 
-
 
105
 
-
 
106
            case pgsWAIT_FIRST_PGM_PACKET:
-
 
107
                // wait for first pgm packet.
-
 
108
                if ((tickGet()-t)>PACKET_TIMEOUT)
-
 
109
                {
-
 
110
                    // Timeout, resend ack.
-
 
111
                    errMsg          = ERR_NO_ERROR;
-
 
112
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
-
 
113
                    pgs             = pgsSEND_ACK;
-
 
114
                }
-
 
115
 
-
 
116
                // If programming packet...
-
 
117
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
-
 
118
                {
-
 
119
                    // Save bytes in memory, setup start adress etc..
-
 
120
                    bytesReceived   = 8;
-
 
121
                    pgs             = pgsWAIT_PGM_PACKET;
-
 
122
                }
-
 
123
 
-
 
124
 
-
 
125
            break;
-
 
126
 
-
 
127
 
-
 
128
            case pgsWAIT_PGM_PACKET:
-
 
129
       
-
 
130
           
-
 
131
                // If programming packet...
-
 
132
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
-
 
133
                {
-
 
134
                    // Save bytes in memory, inc received bytes.
-
 
135
                    bytesReceived   += 8;
-
 
136
                    pgs              = pgsWAIT_PGM_PACKET;
-
 
137
                }
-
 
138
 
-
 
139
                // If adress packet (control packet)..
-
 
140
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_ADDR && cm.nid==MY_NID && cm.sid==programmerSid)
-
 
141
                {
-
 
142
                    // Send ack and goto wait first packet.
-
 
143
                    errMsg          = ERR_NO_ERROR;
-
 
144
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
-
 
145
                    pgs             = pgsSEND_ACK;
-
 
146
                }
-
 
147
               
-
 
148
                // If end packet...
-
 
149
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_DONE && cm.nid==MY_NID && cm.sid==programmerSid)
-
 
150
                {
-
 
151
                    // write program.
-
 
152
                    // If no bytes received at all, assume end.
-
 
153
                    // If not 64 bytes received, send error ack and wait for first packet.
-
 
154
                    // If 64, write.
-
 
155
 
-
 
156
                    if (bytesReceived==0)
-
 
157
                    {
-
 
158
                        // No received, done.
-
 
159
                        errMsg          = ERR_NO_ERROR;
-
 
160
                        afterAckPgs     = pgsDONE;
-
 
161
                        pgs             = pgsSEND_ACK;
-
 
162
                    }
-
 
163
                    else if (bytesReceived!=64)
-
 
164
                    {
-
 
165
                        errMsg          = ERR_ERROR;
-
 
166
                        afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
-
 
167
                        pgs             = pgsSEND_ACK;
-
 
168
                    }
-
 
169
                    else
-
 
170
                    {
-
 
171
                        pgs              = pgsWRITE_PROGRAM;
-
 
172
                        afterAckPgs     = pgsDONE;
-
 
173
                    }
-
 
174
                }
-
 
175
 
-
 
176
                // If bytes received 64, write..
-
 
177
                if (bytesReceived==64)
-
 
178
                {
-
 
179
                    LED0_IO=~LED0_IO;
-
 
180
                    pgs              = pgsWRITE_PROGRAM;
-
 
181
                    afterAckPgs     = pgsWAIT_PGM_PACKET;
-
 
182
                    // TODO! Send ack more than once..
-
 
183
                }
-
 
184
 
-
 
185
 
-
 
186
            break;
-
 
187
 
-
 
188
 
-
 
189
            case pgsWRITE_PROGRAM:
-
 
190
 
-
 
191
                // Write program and send ack.
-
 
192
                pgmAddress     += 64;
-
 
193
                bytesReceived   = 0;
-
 
194
                errMsg          = ERR_NO_ERROR;
-
 
195
                pgs             = pgsSEND_ACK;
-
 
196
 
-
 
197
            break;
-
 
198
 
-
 
199
 
-
 
200
            case pgsDONE:
-
 
201
                // Goto main program.
-
 
202
                if ((tickGet()-t)>=TICK_SECOND/4)
-
 
203
                {
-
 
204
                   
-
 
205
                    LED0_IO=~LED0_IO;
-
 
206
                    t=tickGet();
-
 
207
                }
-
 
208
            break;
-
 
209
 
-
 
210
       
-
 
211
 
-
 
212
 
-
 
213
            default:
-
 
214
                pgs = pgsWATING_START;
-
 
215
            break;
-
 
216
        }
-
 
217
   
-
 
218
 
36
    }
219
    }
37
}
220
}
38
 
221
 
39
 
222
 
40
#pragma interruptlow HighISR
223
#pragma interruptlow HighISR
41
void HighISR(void)
224
void HighISR(void)
42
{
225
{
43
 
-
 
44
 
-
 
45
    #ifdef USE_CAN
-
 
46
        canISR();
226
    tickUpdate();
47
    #endif
-
 
48
 
-
 
49
}
227
}
50
#pragma code highVector=0x08
228
#pragma code highVector=0x08
51
void HighVector (void)
229
void HighVector (void)
52
{
230
{
53
    _asm goto HighISR _endasm
231
    _asm goto HighISR _endasm
Line 56... Line 234...
56
 
234
 
57
 
235
 
58
 
236
 
59
#pragma interruptlow LowISR
237
#pragma interruptlow LowISR
60
void LowISR(void)
238
void LowISR(void)
61
{
239
{
62
 
240
 
63
}
241
}
64
#pragma code lowVector=0x18
242
#pragma code lowVector=0x18
65
void LowVector (void)
243
void LowVector (void)
66
{
244
{
67
    _asm goto LowISR _endasm
245
    _asm goto LowISR _endasm
Line 90... Line 268...
90
    INTCONbits.GIEL = 1;
268
    INTCONbits.GIEL = 1;
91
 
269
 
92
    // Enable interrupt prirority
270
    // Enable interrupt prirority
93
    RCONbits.IPEN=1;
271
    RCONbits.IPEN=1;
94
   
272
   
95
 
273
 
96
}
274
}
-
 
275
 
-
 
276
 
-
 
277
 
-
 
278
/// CAN-------------------------------------------------------
-
 
279
 
-
 
280
 
-
 
281
#ifdef USE_CAN
-
 
282
 
97
 
283
 
98
/*
284
/*
99
*   Function: canParse
285
*   Function: canInit
100
*
286
*
-
 
287
*   Input:  none
-
 
288
*   Output: none
-
 
289
*   Pre-conditions: none
101
*   Input:  Received can message
290
*   Affects: Changes can registers.
-
 
291
*   Depends: none.
-
 
292
*/
-
 
293
void canInit()
-
 
294
{
-
 
295
    CANCON = 0x80; //request config mode
-
 
296
    while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
-
 
297
 
-
 
298
    // BAUD AND TQS
-
 
299
 
-
 
300
    BRGCON1=0;
-
 
301
   
-
 
302
    // Sync_Seq = 2 x TQ = 1
-
 
303
    BRGCON1bits.SJW1=0;
-
 
304
    BRGCON1bits.SJW0=1;
-
 
305
   
-
 
306
    // Setting BRP.
-
 
307
    BRGCON1=BRGCON1|CAN_BRP;
-
 
308
   
-
 
309
    // Maximum PHEG1
-
 
310
    BRGCON2bits.SEG2PHTS = 1;
-
 
311
   
-
 
312
    // Phase_Seg1 = 2 x TQ = 1
-
 
313
    BRGCON2bits.SEG1PH2 = 0;
-
 
314
    BRGCON2bits.SEG1PH1 = 0;
-
 
315
    BRGCON2bits.SEG1PH0 = 1;
-
 
316
   
-
 
317
    // Prop_Seq = 2 x TQ = 1
-
 
318
    BRGCON2bits.PRSEG2 = 0;
-
 
319
    BRGCON2bits.PRSEG1 = 0;
-
 
320
    BRGCON2bits.PRSEG0 = 1;
-
 
321
   
-
 
322
    //  Enableing bus wake-up
-
 
323
    BRGCON3bits.WAKDIS = 0;
-
 
324
   
-
 
325
    // Dont use filter when wakeup
-
 
326
    BRGCON3bits.WAKFIL = 0;
-
 
327
   
-
 
328
    // Phase_Seg2 = 2 x TQ = 1
-
 
329
    BRGCON3bits.SEG2PH2 = 0;
-
 
330
    BRGCON3bits.SEG2PH1 = 0;
-
 
331
    BRGCON3bits.SEG2PH0 = 1;
-
 
332
 
-
 
333
    ECANCON=0;
-
 
334
    ECANCONbits.MDSEL1 = 0;
-
 
335
    ECANCONbits.MDSEL0 = 1;
-
 
336
 
-
 
337
 
-
 
338
    // FILTERS AND MASKS
-
 
339
    RXB0CONbits.RXM1=1;
-
 
340
    RXB0CONbits.RXM0=0;
-
 
341
 
-
 
342
 
-
 
343
    // INTERRUPTS
-
 
344
   
-
 
345
    // Diable transmit interrupt
-
 
346
    TXBIE = 0;
-
 
347
 
-
 
348
    //rx no interrupt
-
 
349
    PIR3 = 0;
-
 
350
    PIE3 = 0;
-
 
351
 
-
 
352
 
-
 
353
    // Programmable no buffers interrupt
-
 
354
    BIE0  = 0x00;  
-
 
355
 
-
 
356
 
-
 
357
    //loopback mode or not
-
 
358
    #ifdef CAN_LOOPBACK_MODE
-
 
359
        CANCON = 0x40;//request loopback mode
-
 
360
        while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
-
 
361
    #else
-
 
362
        CANCON = 0x00;//request normal mode
-
 
363
        while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
-
 
364
    #endif
-
 
365
 
-
 
366
}
-
 
367
 
-
 
368
 
-
 
369
 
-
 
370
 
-
 
371
/*
-
 
372
*   Function: canGetPacket
-
 
373
*
-
 
374
*   Input:  none
102
*   Output: none
375
*   Output: none
103
*   Pre-conditions: canInit and received packet.
376
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
104
*   Affects: Sensors/actuators/etc. See code.
377
*   Affects: Calls canParse() function in main for parsing received packet.
105
*   Depends: none.
378
*   Depends: none.
106
*/
379
*/
-
 
380
BOOL canGetPacket()
-
 
381
{
-
 
382
 
-
 
383
        // Get which buffer that is ful.
-
 
384
             if (RXB0CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10000;  }
-
 
385
        else if (RXB1CONbits.RXFUL) { ECANCON=(ECANCON&0b00000)|0b10001;  }
-
 
386
        else if (B0CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10010;  }
-
 
387
        else if (B1CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10011;  }
-
 
388
        else if (B2CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10100;  }
-
 
389
        else if (B3CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10101;  }
-
 
390
        else if (B4CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10110;  }
-
 
391
        else if (B5CONbits.RXFUL)   { ECANCON=(ECANCON&0b00000)|0b10111;  }
-
 
392
        else return FALSE;
-
 
393
 
-
 
394
 
-
 
395
        //RXB0SIDH 28 27 26 25 24 23 22 21
-
 
396
        //RXB0SIDL 20 19 18 xx xx xx 17 16
-
 
397
        //RXB0EIDH 15 14 13 12 11 10 09 08
-
 
398
        //RXB0EIDL 07 06 05 04 03 02 01 00
-
 
399
 
-
 
400
        //funct xx xx xx xx 28 27 26 25
-
 
401
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
-
 
402
        //nid   xx xx 14 13 12 11 10 09 
-
 
403
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
-
 
404
 
-
 
405
 
-
 
406
        cm.funct=((RXB0SIDH & 0xF0)>>4);
-
 
407
        cm.funcc=(((WORD)(RXB0SIDH & 0x0F))<<6)+(((WORD)(RXB0SIDL & 0xE0))>>2)+(((WORD)(RXB0SIDL & 0x03))<<1)+(((WORD)(RXB0EIDH & 0x80))>>7);
-
 
408
        cm.nid=((RXB0EIDH & 0x7E)>>1);
-
 
409
        cm.sid=(((WORD)(RXB0EIDH & 0x01))<<8)+RXB0EIDL;
-
 
410
 
-
 
411
 
-
 
412
        // Data length
-
 
413
        cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
-
 
414
 
-
 
415
        // Remote request
-
 
416
        cm.remote_request=(RXB0DLCbits.RXRTR==0?FALSE:TRUE);
-
 
417
 
-
 
418
        // Data one bye one, for speed
-
 
419
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
-
 
420
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
-
 
421
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
-
 
422
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
-
 
423
 
-
 
424
        // Clear ful status
-
 
425
        RXB0CONbits.RXFUL=0;
-
 
426
 
107
#ifdef USE_CAN
427
        return TRUE;
-
 
428
}
-
 
429
 
-
 
430
 
-
 
431
/*
-
 
432
*   Function: canSendMessage
-
 
433
*
108
void canParse(CAN_MESSAGE cm)
434
*   Input:  CAN_MESSAGE to send
-
 
435
*   Output: True if packet scheduled sucess, false otherwise.
-
 
436
*   Pre-conditions: canInit
-
 
437
*   Affects: ..
-
 
438
*   Depends: ..
-
 
439
*/
-
 
440
BOOL canSendMessage(CAN_PROTO_MESSAGE cm,CAN_PRIORITY prio)
-
 
441
{
-
 
442
   
-
 
443
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
-
 
444
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
-
 
445
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
-
 
446
    // None of the transmit buffers were empty. 
-
 
447
    else { return FALSE;}
-
 
448
 
-
 
449
    if (prio<0 || prio>3) prio = 0;
-
 
450
 
-
 
451
 
-
 
452
        //RXB0SIDH 28 27 26 25 24 23 22 21
-
 
453
        //RXB0SIDL 20 19 18 xx xx xx 17 16
-
 
454
        //RXB0EIDH 15 14 13 12 11 10 09 08
-
 
455
        //RXB0EIDL 07 06 05 04 03 02 01 00
-
 
456
 
-
 
457
        //funct xx xx xx xx 28 27 26 25
-
 
458
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
-
 
459
        //nid   xx xx 14 13 12 11 10 09 
-
 
460
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
-
 
461
 
-
 
462
        RXB0SIDH = (BYTE)((cm.funct & 0x0F)<<4)+(BYTE)((cm.funcc & 0x03C0)>>6);
-
 
463
        RXB0SIDL = (BYTE)((cm.funcc & 0x003F)<<2)+(BYTE)((cm.funcc & 0x0006)>>1);
-
 
464
        RXB0EIDH = (BYTE)((cm.funcc & 0x0001)<<7)+(BYTE)((cm.nid & 0x3F)<<1)+(BYTE)((cm.sid & 0x0100)>>8);
-
 
465
        RXB0EIDL = (BYTE)((cm.sid & 0x00FF));
-
 
466
 
-
 
467
        // Data length
-
 
468
        RXB0DLC = 0;
-
 
469
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
-
 
470
       
-
 
471
        // Remote request
-
 
472
        if (cm.remote_request==TRUE)
-
 
473
        {
-
 
474
            _asm
-
 
475
                bsf RXB0DLC, 6, 0
-
 
476
            _endasm
-
 
477
        }
-
 
478
        else
109
{
479
        {
-
 
480
            _asm
110
    LED0_IO=~LED0_IO;
481
                bcf RXB0DLC, 6, 0
-
 
482
            _endasm
111
}
483
        }
112
#endif
-
 
113
 
484
 
-
 
485
        // Data one bye one, for speed
-
 
486
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
-
 
487
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
-
 
488
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
-
 
489
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
-
 
490
 
-
 
491
        // set extended or not
-
 
492
        RXB0SIDLbits.EXID=1;
-
 
493
 
-
 
494
        // Priority
-
 
495
        RXB0CON = (RXB0CON & 0b11111100) | prio;
-
 
496
 
-
 
497
        // mark as redy to transmit
-
 
498
        _asm
-
 
499
            bsf RXB0CON, 3, 0
-
 
500
        _endasm
-
 
501
 
-
 
502
        return TRUE;
-
 
503
 
-
 
504
}
-
 
505
 
-
 
506
 
-
 
507
 
-
 
508
#endif //USE_CAN