Subversion Repositories HomeAutomation

Rev

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