summaryrefslogtreecommitdiff
path: root/src/buffer.c
diff options
context:
space:
mode:
Diffstat (limited to 'src/buffer.c')
-rw-r--r--src/buffer.c691
1 files changed, 691 insertions, 0 deletions
diff --git a/src/buffer.c b/src/buffer.c
new file mode 100644
index 0000000..5d37e14
--- /dev/null
+++ b/src/buffer.c
@@ -0,0 +1,691 @@
+/* SP12: A serial programmer for working with Atmel AVR uCs */
+/* Copyright (C) 1997-2003 Ken Huntington, Kevin Towers, Pitronics. */
+
+/* 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. */
+
+/* Pitronics can be reached by email: sbolt@xs4all.nl */
+/* Kevin Towers can be reached by email: ktowers@omnexcontrols.com */
+/* Ken Huntington can be reached by email: kenh@compmore.net */
+
+#include <stdlib.h>
+#include <stdio.h>
+#include <string.h>
+#include <time.h>
+#include "sp12.h"
+
+
+/* Converts address or data string to number, automatically */
+/* selecting hex (0xNNN), oct (0NNN), binary (BNNN) or */
+/* dec (NNN) input. */
+
+unsigned int str2num(char *addressOrData) {
+
+ unsigned int number;
+
+ /*
+ * Determine format (hex, decimal or binary) by looking at prefix
+ * and convert data to unsigned int using base 2, 8, 10 or 16
+ */
+ if (addressOrData[1] == 'x')
+ number = (unsigned int) strtol(addressOrData, NULL, 16);
+ else if (addressOrData[0] == '0')
+ number = (unsigned int) strtol(addressOrData, NULL, 8);
+ else if (addressOrData[0] == 'B')
+ number = (unsigned int) strtol(&addressOrData[1], NULL, 2);
+ else
+ number = (unsigned int) strtol(addressOrData, NULL, 10);
+
+ return(number);
+}
+
+/* convert unsigned int to a string-representation of the */
+/* binary number (ascii `0' is 48, ascii `1' is 49) */
+
+void num2bin(unsigned char buffer, char *binary) {
+
+ int Bi;
+
+ for (Bi = 7; Bi >= 0; Bi--) {
+ binary[Bi] = (buffer & 0x01) + 48;
+ buffer = buffer >> 1;
+ }
+ binary[8] = '\0';
+}
+
+/* Reads program file in Atmel generic format (address:data) or */
+/* Intel HEX format; stores data into into flashBuf by address. */
+/* flashBuf by address. The two numbers in the generic format are */
+/* hex without `0x'. For example: 00000c:99e1 */
+/* Note: the 16-bit bufLimit is not suitable for Mega address space. */
+
+int readFlashFile(char flashPath[], unsigned int flashBuf[], long bufLimit) {
+
+ FILE *flashBufPtr;
+ char wordstring[WORDLEN];
+ long address;
+ unsigned int data;
+ char buffer[MAXLEN];
+ long offsetAddress = 0L;
+ int dataByteCount;
+ unsigned int lineAddress;
+ int recordType;
+ int idx;
+ int checksum;
+ int tmp;
+
+ if ((flashBufPtr = fopen(flashPath, "r")) == NULL) {
+ return(1);
+ } else {
+ if (fgets(wordstring, WORDLEN, flashBufPtr) != NULL) {
+ /*
+ * Try Atmel generic format (default of the Atmel assembler).
+ */
+ if (wordstring[FLASH_DATAPTR] == ':') {
+ fseek(flashBufPtr, 0, SEEK_SET);
+ while (fgets(wordstring, WORDLEN, flashBufPtr) != NULL) {
+ sscanf(wordstring, "%lx", &address);
+ if (wordstring[FLASH_DATAPTR] != ':') {
+ return(1);
+ }
+ sscanf(&wordstring[FLASH_DATAPTR + 1], "%x", &data);
+ if (address < bufLimit)
+ flashBuf[address] = data;
+ else
+ return(1);
+ }
+ fclose(flashBufPtr);
+ return(0);
+ }
+ /*
+ * Try Intel HEX format.
+ */
+ if (wordstring[0] == ':') {
+ fseek(flashBufPtr, 0, SEEK_SET);
+ while (fgets(buffer, MAXLEN, flashBufPtr) != NULL) {
+ checksum = 0;
+ sscanf(&buffer[1], "%2x", &dataByteCount);
+ checksum += dataByteCount;
+ sscanf(&buffer[3], "%4x", &lineAddress);
+ sscanf(&buffer[3], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[5], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[7], "%2x", &recordType);
+ checksum += recordType;
+ /*
+ * Record type 02 means update offset address
+ */
+ if (recordType == 2) {
+ sscanf(&buffer[9], "%4lx", &offsetAddress);
+ sscanf(&buffer[9], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[11], "%2x", &tmp);
+ checksum += tmp;
+ checksum = (unsigned char) (0x100 - (unsigned char) checksum);
+ sscanf(&buffer[13], "%2x", &tmp);
+ if (checksum != tmp)
+ return(1);
+ }
+ if (recordType == 0) {
+ for (idx = 9; idx < 9 + dataByteCount * 2; idx += 2) {
+ sscanf(&buffer[idx], "%2x", &data);
+ /*
+ * Use word addresses for the AT90 2-byte data format
+ */
+ address = lineAddress / 2;
+ address = address + (offsetAddress * 0x10) / 2;
+ if (address < bufLimit) {
+ if (lineAddress & 0x0001) /* is it an odd address? */
+ /* then set MSB of data */
+ flashBuf[address] &= (data << 8) | 0x00ff;
+ else /* else set LSB of data */
+ flashBuf[address] &= data | 0xff00;
+ } else {
+ return(1);
+ }
+ lineAddress++;
+ checksum += data;
+ }
+ checksum = (unsigned char) (0x100 - (unsigned char) checksum);
+ sscanf(&buffer[idx], "%2x", &tmp);
+ if (checksum != tmp)
+ return(1);
+ }
+ }
+ fclose(flashBufPtr);
+ return(0);
+ }
+ }
+ }
+ return(1);
+}
+
+/* Reads eeprom file in format address:data, stores data into */
+/* eepromBuf by address. Both numbers can be hexadecimal (0xC4), */
+/* decimal (196), octal (0304) or binary (B11000100). */
+
+int readEepromFile(char eepromPath[], unsigned int eepromBuf[], long bufLimit) {
+
+ FILE *eepromBufPtr;
+ char wordstring[WORDLEN];
+ long address;
+ unsigned int data;
+ char buffer[MAXLEN];
+ char *dataPtr;
+ long offsetAddress = 0L;
+ int dataByteCount;
+ unsigned int lineAddress;
+ int recordType;
+ int idx;
+ int checksum;
+ int tmp;
+
+ if ((eepromBufPtr = fopen(eepromPath, "r")) == NULL) {
+ return(1);
+ } else {
+ if (fgets(wordstring, WORDLEN, eepromBufPtr) != NULL) {
+ /*
+ * Try sp12 eeprom format.
+ */
+ if (strchr(wordstring, ':') != &wordstring[0]) {
+ fseek(eepromBufPtr, 0, SEEK_SET);
+ while (fgets(wordstring, WORDLEN, eepromBufPtr) != NULL) {
+ if ((dataPtr = strchr(wordstring, ':')) == NULL) {
+ return(1);
+ }
+ dataPtr[0] = '\0';
+ address =str2num(wordstring);
+ data = str2num(++dataPtr);
+ if (address < bufLimit)
+ eepromBuf[address] = data;
+ else
+ return(1);
+ }
+ fclose(eepromBufPtr);
+ return(0);
+ }
+ /*
+ * Try Intel HEX format.
+ */
+ if (strchr(wordstring, ':') == &wordstring[0]) {
+ fseek(eepromBufPtr, 0, SEEK_SET);
+ while (fgets(buffer, MAXLEN, eepromBufPtr) != NULL) {
+ checksum = 0;
+ sscanf(&buffer[1], "%2x", &dataByteCount);
+ checksum += dataByteCount;
+ sscanf(&buffer[3], "%4x", &lineAddress);
+ sscanf(&buffer[3], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[5], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[7], "%2x", &recordType);
+ checksum += recordType;
+ /*
+ * Record type 02 means update offset address
+ */
+ if (recordType == 2) {
+ sscanf(&buffer[9], "%4lx", &offsetAddress);
+ sscanf(&buffer[9], "%2x", &tmp);
+ checksum += tmp;
+ sscanf(&buffer[11], "%2x", &tmp);
+ checksum += tmp;
+ checksum = (unsigned char) (0x100 - (unsigned char) checksum);
+ sscanf(&buffer[13], "%2x", &tmp);
+ if (checksum != tmp)
+ return(1);
+ }
+ if (recordType == 0) {
+ address = lineAddress;
+ address = address + (offsetAddress * 0x10) / 2;
+ /*
+ * Use byte addresses for single byte eeprom data format.
+ */
+ for (idx = 9; idx < 9 + dataByteCount * 2; idx += 2) {
+ sscanf(&buffer[idx], "%2x", &data);
+ if (address < bufLimit)
+ eepromBuf[address] = data;
+ else
+ return(1);
+ address++;
+ checksum += data;
+ }
+ checksum = (unsigned char) (0x100 - (unsigned char) checksum);
+ sscanf(&buffer[idx], "%2x", &tmp);
+ if (checksum != tmp)
+ return(1);
+ }
+ }
+ fclose(eepromBufPtr);
+ return(0);
+ }
+ }
+ }
+ return(1);
+}
+
+/* Calculate checksum over buffer[]; int bufLimit is number of */
+/* elements in buffer. */
+
+unsigned int checksum(unsigned int buffer[], long bufLimit) {
+
+ long idx;
+ unsigned int chksum = 0;
+
+ /*
+ * cyclic right shift 1 of chksum + buffer element
+ */
+ for (idx = 0; idx < bufLimit; idx++) {
+ if (buffer[idx] == 0xfff)
+ buffer[idx] = 0xff;
+ chksum = ((chksum>>1) + ((chksum & 1) ?0x8000:0) + buffer[idx]) & 0xffff;
+ }
+ return(chksum);
+}
+
+/* Routines to write the flash or eeprom buffer into a file, */
+/* using Intel HEX format or as a hex dump with ascii translation. */
+
+#define BYTES_PER_LINE 16
+
+static int flash_intel_hex (FILE *filePtr, unsigned int *buffer,
+ long addr, long length) {
+
+ int line_cnt = 0; /* line byte count */
+ int line_len = 0; /* expected line length */
+ unsigned char checksum = 0;
+ unsigned char byt;
+
+ length *= 2;
+ while (length > 0) {
+ if (addr > 0xFFFF) { /* add record type 02 */
+ fprintf (filePtr, ":020000021000EC\n");
+ addr = 0x10000 - addr;
+ }
+ if (line_cnt == 0) { /* write line header */
+ line_len = (length > BYTES_PER_LINE) ? BYTES_PER_LINE : length;
+ fprintf (filePtr, ":%02X%04lX00", line_len, addr);
+ checksum = line_len;
+ checksum += addr & 0xff;
+ checksum += addr >> 8;
+ }
+
+ if (addr & 0x0001) { /* is it an odd address? */
+ byt = *buffer >> 8; /* write MSB */
+ buffer++;
+ } else {
+ byt = *buffer & 0x00ff; /* write LSB */
+ }
+ fprintf (filePtr, "%02X", byt);
+ checksum += byt;
+
+ if (++line_cnt == line_len) { /* write checksum */
+ fprintf (filePtr, "%02X\n", -checksum & 0xff);
+ line_cnt = 0;
+ }
+ addr++;
+ length--;
+ }
+ fprintf (filePtr, ":00000001FF\n"); /* write the terminator */
+ return (0);
+}
+
+static int eeprom_intel_hex (FILE *filePtr, unsigned int *buffer,
+ unsigned int addr, long length) {
+ int line_cnt = 0; /* line byte count */
+ int line_len = 0; /* expected line length */
+ unsigned char checksum = 0;
+
+ while (length > 0) {
+ if (line_cnt == 0) { /* write line header */
+ line_len = (length > BYTES_PER_LINE) ? BYTES_PER_LINE : length;
+ fprintf (filePtr, ":%02X%04X00", line_len, addr);
+ checksum = line_len;
+ checksum += addr & 0xff;
+ checksum += addr >> 8;
+ }
+ fprintf (filePtr, "%02X", *buffer);
+ checksum += *buffer;
+ if (++line_cnt == line_len) { /* write checksum */
+ fprintf (filePtr, "%02X\n", -checksum & 0xff);
+ line_cnt = 0;
+ }
+ buffer++;
+ addr++;
+ length--;
+ }
+ fprintf (filePtr, ":00000001FF\n"); /* write the terminator */
+ return (0);
+}
+
+int file_hex_ascii(FILE *filePtr, unsigned int buffer[],
+ int bufLimit, int twoByteFlag) {
+
+ unsigned long address;
+ char dataStr[MAXLEN];
+ char asciiStr[MAXLEN];
+ char lineBuf[MAXLEN];
+ unsigned char loByte, hiByte;
+ int addressPerLine = 0x10;
+
+ dataStr[0] = '\0';
+ asciiStr[0] = '\0';
+ for (address = 0; address < bufLimit; address++) {
+ if ((address > 0) && (address % addressPerLine) == 0) {
+ if ((fprintf(filePtr, "%06lx %s %s\n",
+ address - addressPerLine, dataStr, asciiStr)) == EOF)
+ return(1);
+ dataStr[0] = '\0';
+ asciiStr[0] = '\0';
+ }
+ if (twoByteFlag) {
+ addressPerLine = 0x08;
+ loByte = (unsigned char) buffer[address];
+ hiByte = (unsigned char) (buffer[address] >> 8);
+ sprintf(lineBuf, "%02x %02x ", hiByte, loByte);
+ strcat(dataStr, lineBuf);
+ if ((hiByte > 31) && (hiByte < 127))
+ sprintf(lineBuf, "%c", hiByte);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ if ((loByte > 31) && (loByte < 127))
+ sprintf(lineBuf, "%c", loByte);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ } else {
+ sprintf(lineBuf, "%02x ", buffer[address]);
+ strcat(dataStr, lineBuf);
+ if ((buffer[address] > 31) && (buffer[address] < 127))
+ sprintf(lineBuf, "%c", buffer[address]);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ }
+ }
+ if ((fprintf(filePtr, "%06lx %s %s\n",
+ address - addressPerLine, dataStr, asciiStr)) == EOF)
+ return(1);
+ fprintf(filePtr, "Checksum: %04x\n",
+ checksum(buffer, bufLimit));
+ return(0);
+}
+
+/* Writes flashBuf[] into FILE *flashBufPtr using either Intel HEX */
+/* or the `native' format. */
+/* If write to file fails, return(1), else return(0) */
+
+int fileFlashBuf(unsigned int flashBuf[], long bufLimit,
+ char flashPath[], int intel_flag, int hex_ascii_flag) {
+
+ FILE *flashBufPtr;
+ long address;
+
+ if ((flashBufPtr = fopen(flashPath, "w")) == NULL)
+ return(1);
+
+ if (hex_ascii_flag) {
+ file_hex_ascii(flashBufPtr, flashBuf, bufLimit, 1);
+ } else if (intel_flag) {
+ flash_intel_hex(flashBufPtr, flashBuf, 0, bufLimit);
+ } else {
+ for (address = 0; address < bufLimit; address++) {
+ if ((fprintf(flashBufPtr, "%06lx:%04x\n",
+ address, flashBuf[address])) == EOF)
+ return(1);
+ }
+ }
+ fclose(flashBufPtr);
+ return(0);
+}
+
+/* Writes eepromBuf[] into FILE *eepromBufPtr; */
+/* If write to file fails, return(1), else return(0) */
+
+int fileEepromBuf(unsigned int eepromBuf[], long bufLimit,
+ char eepromPath[], int intel_flag, int hex_ascii_flag) {
+
+ FILE *eepromBufPtr;
+ long address;
+ char binary[9] = "76543210";
+
+ if ((eepromBufPtr = fopen(eepromPath, "w")) == NULL)
+ return(1);
+
+ if (hex_ascii_flag) {
+ file_hex_ascii(eepromBufPtr, eepromBuf, bufLimit, 0);
+ } else if (intel_flag) {
+ eeprom_intel_hex(eepromBufPtr, eepromBuf, 0, bufLimit);
+ } else {
+ if ((fprintf(eepromBufPtr,
+ "Address: Data in hex, dec, oct, bin\n")) == EOF)
+ return(1);
+ for (address = 0; address < bufLimit; address++) {
+ num2bin((unsigned char) eepromBuf[address], binary);
+ if ((fprintf(eepromBufPtr,
+ " %#06lx: %#04x %3d %#4o %s\n",
+ address, eepromBuf[address], eepromBuf[address],
+ eepromBuf[address], binary)) == EOF)
+ return(1);
+ }
+ }
+ fclose(eepromBufPtr);
+ return(0);
+}
+
+/* Writes buffer[] to stdout as a hex dump with ascii translation */
+
+void printBuffer(unsigned int buffer[], long bufLimit, int twoByteFlag) {
+
+ long address;
+ char dataStr[MAXLEN];
+ char asciiStr[MAXLEN];
+ char lineBuf[MAXLEN];
+ unsigned char loByte, hiByte;
+ int addressPerLine = 0x10;
+
+ dataStr[0] = '\0';
+ asciiStr[0] = '\0';
+ for (address = 0; address < bufLimit; address++) {
+ if ((address > 0) && (address % addressPerLine) == 0) {
+ printf("%06lx %s %s\n", address - addressPerLine, dataStr, asciiStr);
+ dataStr[0] = '\0';
+ asciiStr[0] = '\0';
+ }
+ if (twoByteFlag) {
+ addressPerLine = 0x08;
+ loByte = (unsigned char) buffer[address];
+ hiByte = (unsigned char) (buffer[address] >> 8);
+ sprintf(lineBuf, "%02x %02x ", hiByte, loByte);
+ strcat(dataStr, lineBuf);
+ if ((hiByte > 31) && (hiByte < 127))
+ sprintf(lineBuf, "%c", hiByte);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ if ((loByte > 31) && (loByte < 127))
+ sprintf(lineBuf, "%c", loByte);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ } else {
+ sprintf(lineBuf, "%02x ", buffer[address]);
+ strcat(dataStr, lineBuf);
+ if ((buffer[address] > 31) && (buffer[address] < 127))
+ sprintf(lineBuf, "%c", buffer[address]);
+ else
+ sprintf(lineBuf, ".");
+ strcat(asciiStr, lineBuf);
+ }
+ }
+ printf("%06lx %s %s\n", address - addressPerLine, dataStr, asciiStr);
+ printf("Checksum: %04x\n", checksum(buffer, bufLimit));
+}
+
+/* Add spaces until lenght or max is reached */
+/* Try to break line if necessary */
+
+void formatStr(char *logStr, int length, int max) {
+
+ int idx;
+ int limit;
+ int idxL = 0;
+
+ limit = length;
+ for (idx = 0; idx < limit; idx++) {
+ if (idx == max) {
+ logStr[idx] = '\0';
+ break;
+ }
+ if ((++idxL > length / 2) && logStr[idx] == ' ') {
+ logStr[idx] = '\n';
+ limit = limit + idxL;
+ idxL = 0;
+ }
+ if (logStr[idx] == '\0') {
+ logStr[idx] = ' ';
+ logStr[idx + 1] = '\0';
+ }
+ }
+}
+
+/* Add a line to the log about a write command */
+
+int logWrites(char *commandStr, unsigned int address, int data,
+ char *path, unsigned int buffer[], int overlayFlag, int *error) {
+
+ FILE *logPtr;
+ time_t curTime;
+ struct tm *locTime;
+ unsigned int areaChksum = 0;
+ unsigned int *queryBuf;
+ int idx;
+ long adrsCnt;
+ char deviceName[MAXLEN];
+ char fileName[MAXLEN];
+ char *fileNamePtr;
+
+ if (log.logging != 1)
+ return(0);
+
+ formatStr(commandStr, 6, MAXLEN);
+ strcpy(deviceName, device.name);
+ if (strcmp(deviceName, "AT90(L)S2343 or Tiny22(L)") == 0)
+ strcpy(deviceName, "2343/Tiny22");
+ formatStr(deviceName, 12, MAXLEN);
+ queryBuf = malloc(FLASHBUF_UPPERLIMIT * sizeof (unsigned int));
+ if (queryBuf == NULL) {
+ printf ("ERROR: No memory available for buffer!\n");
+ return(0);
+ }
+
+ curTime = time(NULL);
+ locTime = localtime(&curTime);
+
+ if ((logPtr = fopen(log.logPath, "a")) == NULL) {
+ free(queryBuf);
+ return(1);
+ }
+ fprintf(logPtr, "%s %s ", deviceName, commandStr);
+ if (strchr(commandStr, 'f') != NULL) {
+ strcpy(fileName, path);
+ fileNamePtr = fileName;
+ idx = strlen(fileName);
+ while (idx-- > 0 && fileName[idx] != '\\' && fileName[idx] != '/')
+ fileNamePtr = &fileName[idx];
+ formatStr(fileNamePtr, 14, MAXLEN - idx);
+ fprintf(logPtr, "%s ", fileNamePtr);
+ if (log.query) {
+ if (strchr(commandStr, 'p') != NULL) {
+ readFlashArea(queryBuf, device.flashLimit);
+ areaChksum = checksum(queryBuf, device.flashLimit);
+ *error = 0;
+ for (adrsCnt = 0; adrsCnt < device.flashLimit; adrsCnt++) {
+ if (overlayFlag && buffer[adrsCnt] == 0xffff)
+ continue;
+ if (queryBuf[adrsCnt] != buffer[adrsCnt]) {
+ *error = 1;
+ break;
+ }
+ }
+ } else {
+ readEepromArea(queryBuf, device.eepromLimit);
+ areaChksum = checksum(queryBuf, device.eepromLimit);
+ *error = 0;
+ for (adrsCnt = 0; adrsCnt < device.eepromLimit; adrsCnt++) {
+ if (overlayFlag && buffer[adrsCnt] > 0xFF)
+ continue;
+ if (queryBuf[adrsCnt] != (unsigned char) buffer[adrsCnt]) {
+ *error = 1;
+ break;
+ }
+ }
+ }
+ if (*error)
+ fprintf(logPtr, "readback ERROR %s", asctime(locTime));
+ else
+ fprintf(logPtr, "checksum %04x %s", areaChksum, asctime(locTime));
+ } else {
+ fprintf(logPtr, "not queried %s", asctime(locTime));
+ }
+ } else {
+ if (strchr(commandStr, 'p') != NULL)
+ fprintf(logPtr, "%08x:%#06x ", address, data);
+ else
+ fprintf(logPtr, "%08x:%#04x ", address, data);
+ if (*error)
+ fprintf(logPtr, "readback ERROR %s", asctime(locTime));
+ else
+ fprintf(logPtr, "verified %s", asctime(locTime));
+ }
+ fclose(logPtr);
+ free(queryBuf);
+ return(0);
+}
+
+/* Add a line to the log about a lock command */
+
+int logLocks(unsigned int buffer[], char *lockBits) {
+
+ FILE *logPtr;
+ time_t curTime;
+ struct tm *locTime;
+ unsigned int areaChksum = 0;
+ char deviceName[MAXLEN];
+ char lBits[MAXLEN] = "";
+
+ if (log.logging != 1)
+ return(0);
+
+ sprintf(lBits, "%02lx", strtol(lockBits, NULL, 2));
+
+ strcpy(deviceName, device.name);
+ formatStr(deviceName, 12, MAXLEN);
+ curTime = time(NULL);
+ locTime = localtime(&curTime);
+
+ if ((logPtr = fopen(log.logPath, "a")) == NULL)
+ return(1);
+ fprintf(logPtr, "%s -L%s ", deviceName, lBits);
+ readFlashArea(buffer, device.flashLimit);
+ areaChksum = checksum(buffer, device.flashLimit);
+ fprintf(logPtr, "flash %04x ", areaChksum);
+ readEepromArea(buffer, device.eepromLimit);
+ areaChksum = checksum(buffer, device.eepromLimit);
+ fprintf(logPtr, "eeprom %04x %s", areaChksum, asctime(locTime));
+ fclose(logPtr);
+ return(0);
+}