Subversion Repositories HomeAutomation

Rev

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

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