/* FRCProg v0.1 * (c) 2006 Harry Bock, Team 1350 * Load a HEX file compiled for the PIC18Fxxxx used for the FRC * * This program is free software; you can redistribute it and/or modify it under the terms of the GNU General Public License as published by * the Free Software Foundation; either version 2 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU General Public License for more details. * * You should have received a copy of the GNU General Public License * along with this program; if not, write to the Free Software * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. */ #include "ihex.h" #include "frcprog.h" #include #include #include /* Parse an Intel HEX file (output from mcc18) and return * a map of the PIC memory we are to write. */ byte *ihex_parse_file( char *fn ) { int line = 0, c, chk; char buf[64], *record; struct ihex_record rec; FILE *fp = fopen(fn, "r"); byte *picmem = (byte*)malloc(PIC_RAM_SIZE); if(!picmem) { fprintf(stderr, "Error allocating PIC memory... terminating.\n"); exit(1); } if(!fp) { fprintf(stderr, "Error opening file %s!\n", fn); goto error; } memset(picmem, 0, PIC_RAM_SIZE); while(!feof(fp)) { fgets(buf, 64, fp); if(*buf != ':') { fprintf(stderr, "Error reading input, not a valid Intel HEX file!"); goto error; } line++; record = buf+1; // :llaaaatt - length, address, type sscanf(record, IHEX_SCANBYTE, &rec.length); sscanf(record+2, IHEX_SCANWORD, &rec.address); sscanf(record+6, IHEX_SCANBYTE, &rec.record_type); // We have reached the end of the hex file, stop. if(rec.record_type == IHEX_EOF) break; // Skip to the data section of the record and read rec.length bytes record += 8; for(c = 0; c < rec.length; c++) { sscanf(record, IHEX_SCANBYTE, &rec.data[c]); record += 2; } // Final byte of the record is checksum sscanf(record, IHEX_SCANBYTE, &rec.checksum); // Calculate the checksum... // Add all bytes together & 0xFF (restrict to one byte) // and find two's complement of it. chk = rec.length; chk += (rec.address>>8) & 0xFF; // First byte of address chk += rec.address & 0xFF; // Second byte chk += rec.record_type;http://nite.devtails.com/flicks/w98.jpg // Add data to our checksum calculation... for(c = 0; c < rec.length; c++) chk += rec.data[c]; // Take the two's complement and restrict to 1 byte chk = ((~chk & 0xFF) + 1) & 0xFF; if(chk != rec.checksum) { fprintf(stderr, "Error! Parse HEX file: Checksum mismatch " "on line %d - Calculated %02X, Required %02X\n", line, chk, rec.checksum); goto error; } // If this is a data record, copy to picmem at the correct addr if(rec.record_type == IHEX_DATA) memcpy(picmem+rec.address, rec.data, rec.length); } #ifdef DEBUG for(c = 0; c < PIC_RAM_SIZE; c++) { if(!(c % 8)) printf("\n0x%04X:", c); if(!(c % 2)) putc(' ', stdout); printf("%02X", picmem[c]); } #endif return picmem; error: free(picmem); return NULL; }