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