Rev 315 | Show entire file | Regard whitespace | Details | Blame | Last modification | View Log | SVN | RSS feed
| Rev 315 | Rev 319 | ||
|---|---|---|---|
| Line 221... | Line 221... | ||
| 221 | bios_msg.Data.words[2]); |
221 | bios_msg.Data.words[2]); |
| 222 | // flash_copy_data will never return. |
222 | // flash_copy_data will never return. |
| 223 | } |
223 | } |
| 224 | break; |
224 | break; |
| 225 | case BIOS_PGM: |
225 | case BIOS_PGM: |
| - | 226 | // Default to send CAN_NMT_PGM_ACK(offset) |
|
| - | 227 | tx_msg.Id = CAN_ID_NMT_PGM_ACK; |
|
| - | 228 | ||
| 226 | if (nmt_type == CAN_NMT_PGM_DATA) { |
229 | if (nmt_type == CAN_NMT_PGM_DATA) { |
| 227 | // Set address = base address + offset. |
230 | // Set address = base address + offset. |
| 228 | offset = bios_msg.Data.words[0]; |
231 | offset = bios_msg.Data.words[0]; |
| 229 | addr = base_addr + offset; |
232 | addr = base_addr + offset; |
| 230 | 233 | ||
| 231 | // One of ACK and NACK will be sent, both have offset as data. |
234 | // One of ACK and NACK will be sent, both have offset as data. |
| 232 | tx_msg.Data.words[0] = offset; |
235 | tx_msg.Data.words[0] = offset; |
| 233 | send_msg = 1; |
236 | send_msg = 1; |
| 234 | // Default to send CAN_NMT_PGM_ACK(offset) |
- | |
| 235 | tx_msg.Id = CAN_ID_NMT_PGM_ACK; |
- | |
| 236 | 237 | ||
| 237 | // Flash all data sent, beginning at addr. |
238 | // Flash all data sent, beginning at addr. |
| 238 | len = (bios_msg.DataLength+1)/2; // Number of words in message, rounded up. |
239 | len = (bios_msg.DataLength+1)/2; // Number of words in message, rounded up. |
| 239 | uint8_t i; |
240 | uint8_t i; |
| 240 | for (i=1; i<len; i++) { // Skip first word (offset). |
241 | for (i=1; i<len; i++) { // Skip first word (offset). |
| Line 242... | Line 243... | ||
| 242 | // Abort if trying to write in BIOS area. |
243 | // Abort if trying to write in BIOS area. |
| 243 | if (addr >= (uint16_t)&__bios_start) { |
244 | if (addr >= (uint16_t)&__bios_start) { |
| 244 | // Send CAN_NMT_PGM_NACK(offset). |
245 | // Send CAN_NMT_PGM_NACK(offset). |
| 245 | tx_msg.Id = CAN_ID_NMT_PGM_NACK; |
246 | tx_msg.Id = CAN_ID_NMT_PGM_NACK; |
| 246 | break; //for loop |
247 | break; //for loop |
| 247 | } |
248 | } |
| 248 | 249 | ||
| 249 | data = bios_msg.Data.words[i]; |
250 | data = bios_msg.Data.words[i]; |
| 250 | flash_write_word(addr, data); |
251 | flash_write_word(addr, data); |
| 251 | addr += 2; |
252 | addr += 2; |
| 252 | } |
253 | } |
| 253 | // Adjust addr if an odd number of bytes were sent, for use in crc calc. |
254 | // Adjust addr if an odd number of bytes were sent, for use in crc calc. |
| 254 | addr -= bios_msg.DataLength & 1; |
255 | addr -= bios_msg.DataLength & 1; |
| 255 | } |
256 | } |
| 256 | if (nmt_type == CAN_NMT_PGM_END) { |
257 | if (nmt_type == CAN_NMT_PGM_END) { |
| 257 | // Make sure a partly filled page will be flashed. |
258 | // Make sure a partly filled page will be flashed. |
| 258 | flash_flush_buffer(); |
259 | flash_flush_buffer(); |
| 259 | 260 | ||
| 260 | // Calculate crc on written data. |
261 | // Calculate crc on written data. |
| 261 | //TODO: This will not work if data is not sent sequentially without |
262 | //TODO: This will not work if data is not sent sequentially without |
| 262 | // holes, starting with offset=0. We might want to send a NACK if the |
263 | // holes, starting with offset=0. We might want to send a NACK if the |
| 263 | // offset in a CAN_NMT_PGM_DATA msg differs from the expected offset. |
264 | // offset in a CAN_NMT_PGM_DATA msg differs from the expected offset. |
| 264 | uint16_t loc, crc = 0; |
265 | uint16_t loc, crc = 0; |
| 265 | for (loc = base_addr; loc < addr - 2; loc++) { // addr will be last location written + 2. |
266 | for (loc = base_addr; loc < addr - 2; loc++) { // addr will be last location written + 2. |
| 266 | crc = _crc16_update(crc, pgm_read_byte(loc)); |
267 | crc = _crc16_update(crc, pgm_read_byte(loc)); |
| 267 | } |
268 | } |
| 268 | 269 | ||
| 269 | tx_msg.Data.words[0] = crc; |
270 | tx_msg.Data.words[0] = crc; |
| 270 | tx_msg.Id = CAN_ID_NMT_PGM_ACK; |
- | |
| 271 | send_msg = 1; |
271 | send_msg = 1; |
| 272 | bios_state = BIOS_NOAPP; |
272 | bios_state = BIOS_NOAPP; |
| 273 | } |
273 | } |
| 274 | } |
274 | } |
| 275 | 275 | ||