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
 *********************************************************************
88 johboh 6
 * FileName:        $HeadURL: https://svn.auml.se/svn/HomeAutomation/trunk/EmbeddedSoftware/PIC/canBoot/Source/Main.c $
7
 * Last changed:    $LastChangedDate: 2007-01-28 14:58:11 +0100 (Sun, 28 Jan 2007) $
8
 * By:              $LastChangedBy: johboh $
9
 * Revision:        $Revision: 260 $
53 johboh 10
 ********************************************************************/
11
 
12
#include <compiler.h>
13
#include <stackTasks.h>
64 johboh 14
#include <CANdefs.h>
15
#include <CAN.h>
67 johboh 16
#include <boot.h>
91 johboh 17
#include <funcdefs.h>
101 johboh 18
#include <EEaccess.h>
53 johboh 19
 
67 johboh 20
/** V E C T O R  R E M A P P I N G *******************************************/
21
 
22
#pragma code _HIGH_INTERRUPT_VECTOR = 0x000008
23
void _high_ISR (void)
24
{
25
    _asm goto RM_HIGH_INTERRUPT_VECTOR _endasm
26
}
27
 
28
#pragma code _LOW_INTERRUPT_VECTOR = 0x000018
29
void _low_ISR (void)
30
{
31
    _asm goto RM_LOW_INTERRUPT_VECTOR _endasm
32
}
33
 
34
#pragma code
35
 
36
 
53 johboh 37
#ifdef USE_CAN
38
    #include <CAN.h>
39
#endif
40
 
64 johboh 41
static CAN_PROTO_MESSAGE cm;
42
static DWORD cnt =0;
43
 
53 johboh 44
static void mainInit(void);
64 johboh 45
static BOOL canGetPacket(void);
67 johboh 46
void TBLWT_Func(void);
47
void TBLWTPOSTINC_Func (void);
48
void TBLRD_Func(void);
53 johboh 49
 
67 johboh 50
#define TICK_SUB_COUNTER_10MS 312
51
#define PACKET_TIMEOUT 14
52
#define BOOTLOADER_INIT_TIMOUT 500
64 johboh 53
 
67 johboh 54
DWORD tickCounter = 0;
55
DWORD tickSubCounter = 0;
56
 
57
DWORD tickGet(void);
58
 
101 johboh 59
static int MY_ID = DEFAULT_ID;
60
static BYTE MY_NID = DEFAULT_NID;
61
 
53 johboh 62
void main()
63
{
64 johboh 64
    static PROGRAM_STATE pgs = pgsWATING_START;
67 johboh 65
    static DWORD t = 0;
64 johboh 66
    static WORD programmerSid=0;
67
 
101 johboh 68
    static BYTE errMsg = ACK_ERR_NO_ERROR;
64 johboh 69
    static PROGRAM_STATE afterAckPgs = pgsWATING_START;
70
    static DWORD pgmAddress = 0;
71
    static BYTE bytesReceived = 0;
53 johboh 72
 
67 johboh 73
    DWORD tBoot;
74
 
75
    static BYTE pgmData[64];
76
 
110 johboh 77
    CAN_PROTO_MESSAGE outCmHeart;
78
 
53 johboh 79
    // Inits
80
    mainInit();
81
 
82
    #ifdef USE_CAN
83
        canInit();
84
    #endif
85
 
67 johboh 86
    tBoot = tickGet();
64 johboh 87
 
101 johboh 88
    // Read ID and NID if exist.
89
    if (EERead(NODE_ID_EE)==NODE_HAS_ID)
90
    {
91
        MY_ID=(((WORD)EERead(NODE_ID_EE + 1))<<8)+EERead(NODE_ID_EE + 2);
92
        MY_NID=EERead(NODE_ID_EE + 3);
93
    }
64 johboh 94
 
260 johboh 95
 
110 johboh 96
    // Send bootloader startup heatbeat
97
    outCmHeart.funct                    = FUNCT_BOOTLOADER;
98
    outCmHeart.funcc                    = FUNCC_BOOT_HEARTBEAT;
99
    outCmHeart.nid                      = MY_NID;
100
    outCmHeart.sid                      = MY_ID;
101
    outCmHeart.data_length              = 1;
102
    outCmHeart.data[BOOT_DATA_HEARTBEAT_INDEX] = HEARTBEAT_BOOT_STARTUP;
103
    while(!canSendMessage(outCmHeart,PRIO_HIGH));
260 johboh 104
 
105
    LED0_IO= 1;
101 johboh 106
 
64 johboh 107
    for(;;)
53 johboh 108
    {
67 johboh 109
        BYTE i;
64 johboh 110
        CAN_PROTO_MESSAGE outCm;
111
        BOOL hasPacket = canGetPacket();
112
 
67 johboh 113
        tickSubCounter++;
114
        if (tickSubCounter>TICK_SUB_COUNTER_10MS)
64 johboh 115
        {
67 johboh 116
            tickCounter++;
117
            tickSubCounter=0;
88 johboh 118
            ClrWdt();
64 johboh 119
        }
120
 
121
        switch(pgs)
122
        {
123
            case pgsWATING_START:
124
                // Check if there is bootloader start packet
101 johboh 125
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_INIT && ((((unsigned int)cm.data[BOOT_DATA_RID_HIGH_INDEX])<<8)+cm.data[BOOT_DATA_RID_LOW_INDEX])==MY_ID && cm.nid==MY_NID)
64 johboh 126
                {
127
                    // Has new start packet
101 johboh 128
                    pgmAddress      = (((DWORD)cm.data[BOOT_DATA_ADDRU_INDEX])<<16)+(((DWORD)cm.data[BOOT_DATA_ADDRH_INDEX])<<8)+((DWORD)cm.data[BOOT_DATA_ADDRL_INDEX]);
64 johboh 129
                    programmerSid   = cm.sid;
130
                    t               = tickGet();
101 johboh 131
                    errMsg          = ACK_ERR_NO_ERROR;
64 johboh 132
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
133
                    pgs             = pgsSEND_ACK;
67 johboh 134
                    // save pgm adress.
135
 
64 johboh 136
                }
137
 
67 johboh 138
                // Bootloader timeout
139
                if ((tickGet()-tBoot)>BOOTLOADER_INIT_TIMOUT)
140
                {
260 johboh 141
                    LED0_IO= 0;
67 johboh 142
                    pgs = pgsDONE;
143
                }
64 johboh 144
            break;         
145
 
146
            case pgsSEND_ACK:
147
                // send ack
148
                outCm.funct             = FUNCT_BOOTLOADER;
149
                outCm.funcc             = FUNCC_BOOT_ACK;
150
                outCm.nid               = MY_NID;
151
                outCm.sid               = MY_ID;
152
                outCm.data_length       = 8;
101 johboh 153
                outCm.data[BOOT_DATA_ERR_INDEX] = errMsg;
64 johboh 154
                t                       = tickGet();
155
                pgs                     = afterAckPgs;
156
 
157
                while(!canSendMessage(outCm,PRIO_HIGH));
158
            break;
159
 
160
 
161
            case pgsWAIT_FIRST_PGM_PACKET:
162
                // wait for first pgm packet.
163
                if ((tickGet()-t)>PACKET_TIMEOUT)
164
                {
165
                    // Timeout, resend ack.
101 johboh 166
                    errMsg          = ACK_ERR_NO_ERROR;
64 johboh 167
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
168
                    pgs             = pgsSEND_ACK;
169
                }
170
 
171
                // If programming packet...
104 johboh 172
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && (cm.funcc & 0x3E3)==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
64 johboh 173
                {
67 johboh 174
                    BYTE localIndex = (BYTE)((cm.funcc & 0x1C)>>2)*8;
175
 
64 johboh 176
                    // Save bytes in memory, setup start adress etc..
67 johboh 177
                    bytesReceived   = 8;       
178
                    pgmData[localIndex+0]=cm.data[0]; pgmData[localIndex+1]=cm.data[1]; pgmData[localIndex+2]=cm.data[2]; pgmData[localIndex+3]=cm.data[3];
179
                    pgmData[localIndex+4]=cm.data[4]; pgmData[localIndex+5]=cm.data[5]; pgmData[localIndex+6]=cm.data[6]; pgmData[localIndex+7]=cm.data[7];
180
 
64 johboh 181
                    pgs             = pgsWAIT_PGM_PACKET;
182
                }
183
 
184
 
185
            break;
186
 
187
 
188
            case pgsWAIT_PGM_PACKET:
189
 
190
 
191
                // If programming packet...
104 johboh 192
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && (cm.funcc & 0x3E3)==FUNCC_BOOT_PGM && cm.nid==MY_NID && cm.sid==programmerSid)
64 johboh 193
                {
67 johboh 194
                    BYTE localIndex = (BYTE)((cm.funcc & 0x1C)>>2)*8;
64 johboh 195
                    // Save bytes in memory, inc received bytes.
67 johboh 196
                    pgmData[localIndex+0]=cm.data[0]; pgmData[localIndex+1]=cm.data[1]; pgmData[localIndex+2]=cm.data[2]; pgmData[localIndex+3]=cm.data[3];
197
                    pgmData[localIndex+4]=cm.data[4]; pgmData[localIndex+5]=cm.data[5]; pgmData[localIndex+6]=cm.data[6]; pgmData[localIndex+7]=cm.data[7];
198
 
64 johboh 199
                    bytesReceived   += 8;
200
                    pgs              = pgsWAIT_PGM_PACKET;
201
                }
202
 
203
                // If adress packet (control packet)..
204
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_ADDR && cm.nid==MY_NID && cm.sid==programmerSid)
205
                {
206
                    // Send ack and goto wait first packet.
67 johboh 207
                    // save adress.
101 johboh 208
                    errMsg          = ACK_ERR_NO_ERROR;
64 johboh 209
                    afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
210
                    pgs             = pgsSEND_ACK;
211
                }
212
 
213
                // If end packet...
214
                if (hasPacket==TRUE && cm.funct==FUNCT_BOOTLOADER && cm.funcc==FUNCC_BOOT_DONE && cm.nid==MY_NID && cm.sid==programmerSid)
215
                {
216
                    // write program.
217
                    // If no bytes received at all, assume end.
218
                    // If not 64 bytes received, send error ack and wait for first packet.
219
                    // If 64, write.
220
 
221
                    if (bytesReceived==0)
222
                    {
223
                        // No received, done.
101 johboh 224
                        errMsg          = ACK_ERR_NO_ERROR;
64 johboh 225
                        afterAckPgs     = pgsDONE;
226
                        pgs             = pgsSEND_ACK;
227
                    }
228
                    else if (bytesReceived!=64)
229
                    {
101 johboh 230
                        errMsg          = ACK_ERR_ERROR;
64 johboh 231
                        afterAckPgs     = pgsWAIT_FIRST_PGM_PACKET;
232
                        pgs             = pgsSEND_ACK;
233
                    }
234
                    else
235
                    {
236
                        pgs              = pgsWRITE_PROGRAM;
237
                        afterAckPgs     = pgsDONE;
238
                    }
239
                }
240
 
241
                // If bytes received 64, write..
242
                if (bytesReceived==64)
243
                {
244
                    LED0_IO=~LED0_IO;
245
                    pgs              = pgsWRITE_PROGRAM;
246
                    afterAckPgs     = pgsWAIT_PGM_PACKET;
247
                    // TODO! Send ack more than once..
248
                }
249
 
250
 
251
            break;
252
 
253
 
254
            case pgsWRITE_PROGRAM:
255
 
88 johboh 256
                ClrWdt();
67 johboh 257
 
64 johboh 258
                // Write program and send ack.
67 johboh 259
 
68 johboh 260
                // Check addr limit
261
                if (pgmAddress<RM_RESET_VECTOR)
262
                {              
101 johboh 263
                    errMsg          = ACK_ERR_ERROR;
68 johboh 264
                    pgs             = pgsSEND_ACK;
265
                    //Not allowed to write here!
266
 
267
                }
268
 
67 johboh 269
                //Load Table pointer registers with base address to erase.
270
                TBLPTRU = (BYTE)((pgmAddress & 0xFF0000)>>16);
271
                TBLPTRH = (BYTE)((pgmAddress & 0xFF00)>>8);
272
                TBLPTRL = (BYTE)(pgmAddress & 0xFF);
273
 
274
                // point to Flash program memory
275
                EECON1bits.EEPGD = 1;
276
                // access Flash program memory
277
                EECON1bits.CFGS = 0;
278
                // enable write to memory
279
                EECON1bits.WREN = 1;
280
                // enable Row Erase operation
281
                EECON1bits.FREE = 1;
282
                // disable interrupts
283
                INTCONbits.GIE = 0;
284
 
285
                // Do it!
286
                EECON2 = 0x55;
287
                EECON2 = 0xAA;
288
                EECON1bits.WR = 1;
289
 
290
                // enable interrupts
291
                INTCONbits.GIE = 1;
292
 
293
                //Load Table pointer registers with base address to program.
294
                TBLPTRU = (BYTE)((pgmAddress & 0xFF0000)>>16);
295
                TBLPTRH = (BYTE)((pgmAddress & 0xFF00)>>8);
296
                TBLPTRL = (BYTE)(pgmAddress & 0xFF);
297
 
298
                // Load bytes
299
                for(i=0;i<63;i++)
300
                {
301
                    TABLAT=pgmData[i];
302
                    TBLWTPOSTINC_Func();
303
                }
304
                TABLAT=pgmData[63];
305
                TBLWT_Func();
306
 
307
 
308
                // point to Flash program memory
309
                EECON1bits.EEPGD = 1;
310
                // access Flash program memory
311
                EECON1bits.CFGS = 0;
312
                // enable write to memory
313
                EECON1bits.WREN = 1;
314
                // disable interrupts
315
                INTCONbits.GIE = 0;
316
 
317
                // Do it!
318
                EECON2 = 0x55;
319
                EECON2 = 0xAA;
320
                EECON1bits.WR = 1;
321
 
322
                // enable interrupts
323
                INTCONbits.GIE = 1;
324
 
325
                // disable write to memory
326
                EECON1bits.WREN = 0;
327
 
64 johboh 328
                pgmAddress     += 64;
329
                bytesReceived   = 0;
101 johboh 330
                errMsg          = ACK_ERR_NO_ERROR;
64 johboh 331
                pgs             = pgsSEND_ACK;
332
 
333
            break;
334
 
335
 
336
            case pgsDONE:
67 johboh 337
                _asm  goto RM_RESET_VECTOR _endasm
64 johboh 338
            break;
339
 
340
 
341
 
342
 
343
            default:
344
                pgs = pgsWATING_START;
345
            break;
346
        }
347
 
348
 
53 johboh 349
    }
350
}
351
 
352
 
353
/*
354
*   Function: mainInit
355
*
356
*   Input:  none
357
*   Output: none
358
*   Pre-conditions: none
359
*   Affects: Se code
360
*   Depends: none.
361
*/
362
void mainInit()
363
{
364
    LED0_TRIS=0;   
365
 
366
    // Enable internal PORTB pull-ups
367
    INTCON2bits.RBPU = 0;
368
 
369
    // Enable Interrupts
370
    INTCONbits.GIEH = 1;
371
    INTCONbits.GIEL = 1;
372
 
373
    // Enable interrupt prirority
374
    RCONbits.IPEN=1;
375
 
376
 
377
}
378
 
64 johboh 379
 
380
 
381
/// CAN-------------------------------------------------------
382
 
383
 
384
#ifdef USE_CAN
385
 
386
 
53 johboh 387
/*
64 johboh 388
*   Function: canInit
53 johboh 389
*
64 johboh 390
*   Input:  none
53 johboh 391
*   Output: none
64 johboh 392
*   Pre-conditions: none
393
*   Affects: Changes can registers.
53 johboh 394
*   Depends: none.
395
*/
64 johboh 396
void canInit()
53 johboh 397
{
64 johboh 398
    CANCON = 0x80; //request config mode
399
    while ((CANSTAT & 0xE0) != 0x80 ); //wait for config mode request
400
 
401
    // BAUD AND TQS
402
 
260 johboh 403
    // 500Khz@40Mhz (new by the book)
404
    BRGCON1 = 0x04;
405
    BRGCON2 = 0xD1;
406
    BRGCON3 = 0x81;
407
 
408
    //BRGCON1=0;
64 johboh 409
 
410
    // Sync_Seq = 2 x TQ = 1
260 johboh 411
    //BRGCON1bits.SJW1=0;
412
    //BRGCON1bits.SJW0=1;
64 johboh 413
 
414
    // Setting BRP.
260 johboh 415
    //BRGCON1=BRGCON1|CAN_BRP;
64 johboh 416
 
417
    // Maximum PHEG1
260 johboh 418
    //BRGCON2bits.SEG2PHTS = 1;
64 johboh 419
 
420
    // Phase_Seg1 = 2 x TQ = 1
260 johboh 421
    //BRGCON2bits.SEG1PH2 = 0;
422
    //BRGCON2bits.SEG1PH1 = 0;
423
    //BRGCON2bits.SEG1PH0 = 1;
64 johboh 424
 
425
    // Prop_Seq = 2 x TQ = 1
260 johboh 426
    //BRGCON2bits.PRSEG2 = 0;
427
    //BRGCON2bits.PRSEG1 = 0;
428
    //BRGCON2bits.PRSEG0 = 1;
64 johboh 429
 
430
    //  Enableing bus wake-up
260 johboh 431
    //BRGCON3bits.WAKDIS = 0;
64 johboh 432
 
433
    // Dont use filter when wakeup
260 johboh 434
    //BRGCON3bits.WAKFIL = 0;
64 johboh 435
 
436
    // Phase_Seg2 = 2 x TQ = 1
260 johboh 437
    //BRGCON3bits.SEG2PH2 = 0;
438
    //BRGCON3bits.SEG2PH1 = 0;
439
    //BRGCON3bits.SEG2PH0 = 1;
64 johboh 440
 
441
    ECANCON=0;
96 johboh 442
    ECANCONbits.MDSEL1 = 1;
443
    ECANCONbits.MDSEL0 = 0;
64 johboh 444
 
445
 
446
    // FILTERS AND MASKS
447
    RXB0CONbits.RXM1=1;
448
    RXB0CONbits.RXM0=0;
449
 
450
 
451
    // INTERRUPTS
452
 
453
    // Diable transmit interrupt
454
    TXBIE = 0;
455
 
456
    //rx no interrupt
457
    PIR3 = 0;
458
    PIE3 = 0;
459
 
460
 
461
    // Programmable no buffers interrupt
462
    BIE0  = 0x00;  
463
 
464
 
465
    //loopback mode or not
466
    #ifdef CAN_LOOPBACK_MODE
467
        CANCON = 0x40;//request loopback mode
468
        while ((CANSTAT & 0xE0) != 0x40 );//wait for loopback mode
469
    #else
470
        CANCON = 0x00;//request normal mode
471
        while ((CANSTAT & 0xE0) != 0x00 );//wait for normal mode
472
    #endif
473
 
53 johboh 474
}
475
 
64 johboh 476
 
477
 
478
 
479
/*
480
*   Function: canGetPacket
481
*
482
*   Input:  none
483
*   Output: none
484
*   Pre-conditions: a call to canISR and an packet is available and banked to RXB0
485
*   Affects: Calls canParse() function in main for parsing received packet.
486
*   Depends: none.
487
*/
488
BOOL canGetPacket()
489
{
490
 
491
        // Get which buffer that is ful.
96 johboh 492
        ECANCON=(ECANCON&0b00000)|(0b10000|(CANCON&0x0F));
493
        if (!RXB0CONbits.RXFUL) return FALSE;
494
 
260 johboh 495
 
64 johboh 496
        //RXB0SIDH 28 27 26 25 24 23 22 21
497
        //RXB0SIDL 20 19 18 xx xx xx 17 16
498
        //RXB0EIDH 15 14 13 12 11 10 09 08
499
        //RXB0EIDL 07 06 05 04 03 02 01 00
500
 
501
        //funct xx xx xx xx 28 27 26 25
502
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
503
        //nid   xx xx 14 13 12 11 10 09 
504
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
505
 
506
 
507
        cm.funct=((RXB0SIDH & 0xF0)>>4);
508
        cm.funcc=(((WORD)(RXB0SIDH & 0x0F))<<6)+(((WORD)(RXB0SIDL & 0xE0))>>2)+(((WORD)(RXB0SIDL & 0x03))<<1)+(((WORD)(RXB0EIDH & 0x80))>>7);
509
        cm.nid=((RXB0EIDH & 0x7E)>>1);
510
        cm.sid=(((WORD)(RXB0EIDH & 0x01))<<8)+RXB0EIDL;
511
 
512
 
513
        // Data length
514
        cm.data_length=(RXB0DLCbits.DLC3<<3)+(RXB0DLCbits.DLC2<<2)+(RXB0DLCbits.DLC1<<1)+RXB0DLCbits.DLC0;
515
 
516
        // Data one bye one, for speed
517
        cm.data[0]=RXB0D0;  cm.data[1]=RXB0D1;
518
        cm.data[2]=RXB0D2;  cm.data[3]=RXB0D3;
519
        cm.data[4]=RXB0D4;  cm.data[5]=RXB0D5;
520
        cm.data[6]=RXB0D6;  cm.data[7]=RXB0D7;
521
 
522
        // Clear ful status
523
        RXB0CONbits.RXFUL=0;
524
 
525
        return TRUE;
526
}
527
 
528
 
529
/*
530
*   Function: canSendMessage
531
*
532
*   Input:  CAN_MESSAGE to send
533
*   Output: True if packet scheduled sucess, false otherwise.
534
*   Pre-conditions: canInit
535
*   Affects: ..
536
*   Depends: ..
537
*/
538
BOOL canSendMessage(CAN_PROTO_MESSAGE cm,CAN_PRIORITY prio)
539
{
540
 
541
    if ( TXB0CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00011; }
542
    if ( TXB1CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00100; }
543
    if ( TXB2CONbits.TXREQ == 0 )  { ECANCON=(ECANCON&0b00000)|0b00101; }
544
    // None of the transmit buffers were empty. 
545
    else { return FALSE;}
546
 
547
    if (prio<0 || prio>3) prio = 0;
548
 
549
 
550
        //RXB0SIDH 28 27 26 25 24 23 22 21
551
        //RXB0SIDL 20 19 18 xx xx xx 17 16
552
        //RXB0EIDH 15 14 13 12 11 10 09 08
553
        //RXB0EIDL 07 06 05 04 03 02 01 00
554
 
555
        //funct xx xx xx xx 28 27 26 25
556
        //funcc xx xx xx xx xx xx 24 23 22 21 20 19 18 17 16 15 
557
        //nid   xx xx 14 13 12 11 10 09 
558
        //sid   xx xx xx xx xx xx xx 08 07 06 05 04 03 02 01 00
559
 
560
        RXB0SIDH = (BYTE)((cm.funct & 0x0F)<<4)+(BYTE)((cm.funcc & 0x03C0)>>6);
561
        RXB0SIDL = (BYTE)((cm.funcc & 0x003F)<<2)+(BYTE)((cm.funcc & 0x0006)>>1);
562
        RXB0EIDH = (BYTE)((cm.funcc & 0x0001)<<7)+(BYTE)((cm.nid & 0x3F)<<1)+(BYTE)((cm.sid & 0x0100)>>8);
563
        RXB0EIDL = (BYTE)((cm.sid & 0x00FF));
564
 
565
        // Data length
566
        RXB0DLC = 0;
567
        if (cm.data_length>8) RXB0DLC=8; else RXB0DLC=cm.data_length;
568
 
88 johboh 569
        // NOT Remote request
570
        _asm
571
            bcf RXB0DLC, 6, 0
572
        _endasm
64 johboh 573
 
88 johboh 574
 
64 johboh 575
        // Data one bye one, for speed
576
        RXB0D0=cm.data[0];  RXB0D1=cm.data[1];
577
        RXB0D2=cm.data[2];  RXB0D3=cm.data[3];
578
        RXB0D4=cm.data[4];  RXB0D5=cm.data[5];
579
        RXB0D6=cm.data[6];  RXB0D7=cm.data[7];
580
 
581
        // set extended or not
582
        RXB0SIDLbits.EXID=1;
583
 
584
        // Priority
585
        RXB0CON = (RXB0CON & 0b11111100) | prio;
586
 
587
        // mark as redy to transmit
588
        _asm
589
            bsf RXB0CON, 3, 0
590
        _endasm
591
 
592
        return TRUE;
593
 
594
}
595
 
596
 
597
 
598
#endif //USE_CAN
67 johboh 599
 
600
 
601
 
602
 
603
void TBLRD_Func()
604
{
605
_asm
606
    TBLRD
607
_endasm
608
}
609
 
610
void TBLWT_Func()
611
{
612
_asm
613
    TBLWT
614
_endasm
615
}
616
 
617
 
618
void TBLWTPOSTINC_Func (void){
619
_asm
620
    TBLWTPOSTINC
621
_endasm
622
}
623
 
624
DWORD tickGet()
625
{
626
    return tickCounter;
627
}
628
 
629
 
630
#pragma code user = RM_RESET_VECTOR