Subversion Repositories HomeAutomation

Rev

Rev 339 | Only display areas with differences | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed

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