Subversion Repositories HomeAutomation

Rev

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

Rev Author Line No. Line
53 johboh 1
/*********************************************************************
2
 *
3
 *                  Main application
4
 *
5
 *********************************************************************
6
 * FileName:        Main.c
7
 *
8
 * Author               Date    Comment
9
 *~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
10
 * Johan Böhlin     21-10-06    Original        (Rev 1.0)
11
 ********************************************************************/
12
 
13
#include <compiler.h>
14
#include <stackTasks.h>
64 johboh 15
#include <CANdefs.h>
16
#include <CAN.h>
17
#include <Tick.h>
53 johboh 18
 
19
#ifdef USE_CAN
20
    #include <CAN.h>
21
#endif
22
 
64 johboh 23
static CAN_PROTO_MESSAGE cm;
24
static BYTE ful=0;
25
static DWORD cnt =0;
26
 
53 johboh 27
static void mainInit(void);
64 johboh 28
static BOOL canGetPacket(void);
53 johboh 29
 
64 johboh 30
#define PACKET_TIMEOUT (TICK_SECOND/20)
31
#define BOOTLOADER_INIT_TIMOUT (TICK_SECOND*5)
32
 
53 johboh 33
void main()
34
{
64 johboh 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;
53 johboh 43
 
64 johboh 44
    static BYTE tmp;
45
 
53 johboh 46
    // Inits
47
 
48
    mainInit();
49
 
50
    #ifdef USE_CAN
51
        canInit();
52
    #endif
53
 
54
 
64 johboh 55
 
56
    tickInit();
57
 
58
 
59
 
60
    for(;;)
53 johboh 61
    {
64 johboh 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
 
53 johboh 219
    }
220
}
221
 
222
 
223
#pragma interruptlow HighISR
224
void HighISR(void)
225
{
64 johboh 226
    tickUpdate();
53 johboh 227
}
228
#pragma code highVector=0x08
229
void HighVector (void)
230
{
231
    _asm goto HighISR _endasm
232
}
233
#pragma code // Return to default code section
234
 
235
 
236
 
237
#pragma interruptlow LowISR
238
void LowISR(void)
239
{
240
 
241
}
242
#pragma code lowVector=0x18
243
void LowVector (void)
244
{
245
    _asm goto LowISR _endasm
246
}
247
#pragma code // Return to default code section
248
 
249
 
250
/*
251
*   Function: mainInit
252
*
253
*   Input:  none
254
*   Output: none
255
*   Pre-conditions: none
256
*   Affects: Se code
257
*   Depends: none.
258
*/
259
void mainInit()
260
{
261
    LED0_TRIS=0;   
262
 
263
    // Enable internal PORTB pull-ups
264
    INTCON2bits.RBPU = 0;
265
 
266
    // Enable Interrupts
267
    INTCONbits.GIEH = 1;
268
    INTCONbits.GIEL = 1;
269
 
270
    // Enable interrupt prirority
271
    RCONbits.IPEN=1;
272
 
273
 
274
}
275
 
64 johboh 276
 
277
 
278
/// CAN-------------------------------------------------------
279
 
280
 
281
#ifdef USE_CAN
282
 
283
 
53 johboh 284
/*
64 johboh 285
*   Function: canInit
53 johboh 286
*
64 johboh 287
*   Input:  none
53 johboh 288
*   Output: none
64 johboh 289
*   Pre-conditions: none
290
*   Affects: Changes can registers.
53 johboh 291
*   Depends: none.
292
*/
64 johboh 293
void canInit()
53 johboh 294
{
64 johboh 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
 
53 johboh 366
}
367
 
64 johboh 368
 
369
 
370
 
371
/*
372
*   Function: canGetPacket
373
*
374
*   Input:  none
375
*   Output: none
376
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
377
*   Affects: Calls canParse() function in main for parsing received packet.
378
*   Depends: none.
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
 
427
        return TRUE;
428
}
429
 
430
 
431
/*
432
*   Function: canSendMessage
433
*
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
479
        {
480
            _asm
481
                bcf RXB0DLC, 6, 0
482
            _endasm
483
        }
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