* Copyright (C) 1999 Jonathan St-André
* Copyright (C) 1999 Hugo Villeneuve <hugo@hugovil.com>
*
- * 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., 51 Franklin St, Fifth Floor, Boston, MA 02110-1301, USA.
+ * This file is released under the GPLv2
*/
#if HAVE_CONFIG_H
# include "config.h"
#endif
-#include <unistd.h>
#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
/* Maximum of 75 digits with 32-bytes data records. */
#define HEXFILE_LINE_BUFFER_LEN 128
+static int asciihex2int_error;
+
/* Convert integer to ASCII hex string. */
void
int2asciihex(int val, char *str, int width)
{
if (width == 1)
- sprintf(str , "%.1X", (u_int8_t) val);
+ sprintf(str , "%.1X", (uint8_t) val);
else if (width == 2)
- sprintf(str , "%.2X", (u_int8_t) val);
+ sprintf(str , "%.2X", (uint8_t) val);
else if (width == 4)
- sprintf(str , "%.4X", (u_int16_t) val);
+ sprintf(str , "%.4X", (uint16_t) val);
else
sprintf(str , "Err");
}
asciihex2int(char *str)
{
int val;
+ int rc;
+
+ rc = sscanf(str, "%X", &val);
- sscanf(str, "%X", &val);
+ if (rc == 0) {
+ log_err("ASCII to hex conversion failure");
+ asciihex2int_error = true;
+ }
return val;
}
/* Convert an ascii string to an hexadecimal number. */
-unsigned int
-Ascii2Hex(char *istring, int length)
+static unsigned int
+asciihex2int_len(char *istring, int length)
{
unsigned int result = 0;
int i, ascii_code;
ascii_code &= 0xDF;
if ((ascii_code >= 0x30 && ascii_code <= 0x39) ||
- (ascii_code >= 0x41 && ascii_code <= 0x46)) {
+ (ascii_code >= 0x41 && ascii_code <= 0x46)) {
ascii_code -= 0x30;
if (ascii_code > 9)
ascii_code -= 7;
result <<= 4;
result += ascii_code;
} else {
- log_fail("Error converting ASCII string <%s> to hex"
- " (len=%d)", istring, length);
+ log_err("ASCII to hex conversion failure");
+ asciihex2int_error = true;
}
}
return result;
* false: failure
*/
int
-LoadHexFile(const char *filename)
+hexfile_load(const char *filename)
{
- int i, j, RecLength, LoadOffset, RecType, Data, Checksum;
+ int i, j, rec_len, load_offset, rec_type, data, checksum;
FILE *fp;
int status;
char line[HEXFILE_LINE_BUFFER_LEN];
int valid = false;
+ int line_num = 1;
log_debug("LoadHexFile");
*/
while (fgets(line, HEXFILE_LINE_BUFFER_LEN, fp) != NULL) {
i = 0;
- Checksum = 0;
+ checksum = 0;
if (line[i++] != ':') {
log_err("hexfile line not beginning with \":\"");
goto close_file;
}
- RecLength = Ascii2Hex(&line[i], 2);
+ rec_len = asciihex2int_len(&line[i], 2);
i += 2;
- Checksum += RecLength;
+ checksum += rec_len;
- LoadOffset = Ascii2Hex(&line[i], 4);
- Checksum += LoadOffset / 256;
- Checksum += LoadOffset % 256;
+ load_offset = asciihex2int_len(&line[i], 4);
+ checksum += load_offset / 256;
+ checksum += load_offset % 256;
i += 4;
- RecType = Ascii2Hex(&line[i], 2);
+ rec_type = asciihex2int_len(&line[i], 2);
i += 2;
- Checksum += RecType;
-
- if (RecType == 0) {
- for (j = 0; j < RecLength; j++) {
- Data = Ascii2Hex(&line[i], 2);
- memory_write8(PGM_MEM_ID,
- (unsigned int)(LoadOffset + j),
- (unsigned char)Data);
+ checksum += rec_type;
+
+ if (rec_type == 0) {
+ for (j = 0; j < rec_len; j++) {
+ data = asciihex2int_len(&line[i], 2);
+ mem_write8(PGM_MEM_ID,
+ (unsigned int) (load_offset + j),
+ (unsigned char) data);
i += 2;
- Checksum += Data;
+ checksum += data;
}
}
/* Read and add checksum value */
- Checksum += Ascii2Hex(&line[i], 2);
- Checksum &= 0x000000FF;
+ checksum += asciihex2int_len(&line[i], 2);
+ checksum &= 0x000000FF;
- /* Make sure line checksum is valid */
- if (Checksum) {
+ if (asciihex2int_error) {
+ log_err("hexfile parse error at line %d", line_num);
+ goto close_file;
+ } else if (checksum) {
log_err("hexfile checksum mismatch");
goto close_file;
}
- if (RecType == 0) {
+ if (rec_type == 0) {
log_debug("hex record: data");
- } else if (RecType == 1) {
+ } else if (rec_type == 1) {
log_debug("hex record: End Of File");
valid = true;
goto close_file;
} else {
- log_warn("hex record: Unsupported ($%02X)", RecType);
+ log_warn("hex record: Unsupported ($%02X)", rec_type);
}
+
+ line_num++;
}
close_file:
if (status != EXIT_SUCCESS)
log_fail("Error closing hex file");
- if (valid == false) {
+ if (!valid)
log_err("Error parsing hex file");
- }
return valid;
}