mirror of
https://github.com/adrcs/ip400.git
synced 2025-04-18 18:13:44 +03:00
231 lines
6.3 KiB
C
231 lines
6.3 KiB
C
#include <stdio.h>
|
|
#include <stdlib.h>
|
|
#include <ctype.h>
|
|
#include <string.h>
|
|
#include <stdbool.h>
|
|
|
|
#include "eeptypes.h"
|
|
|
|
struct header_t header;
|
|
struct atom_t atom;
|
|
struct vendor_info_d vinf;
|
|
struct gpio_map_d gpiomap;
|
|
unsigned char* data;
|
|
|
|
int read_bin(char *in, char *outf) {
|
|
|
|
uint16_t crc;
|
|
FILE *fp, *out;
|
|
int i,j;
|
|
|
|
fp=fopen(in, "r");
|
|
if (!fp) {
|
|
printf("Error reading file %s\n", in);
|
|
return -1;
|
|
}
|
|
|
|
out=fopen(outf, "w");
|
|
if (!out) {
|
|
printf("Error writing file %s\n", outf);
|
|
return -1;
|
|
}
|
|
|
|
if (!fread(&header, sizeof(header), 1, fp)) goto err;
|
|
|
|
fprintf(out, "# ---------- Dump generated by eepdump handling format version 0x%02x ----------\n#\n", FORMAT_VERSION);
|
|
|
|
if (FORMAT_VERSION!=header.ver) fprintf(out, "# WARNING: format version mismatch!!!\n");
|
|
|
|
fprintf(out, "# --Header--\n# signature=0x%08x\n# version=0x%02x\n# reserved=%u\n# numatoms=%u\n# eeplen=%u\n# ----------\n\n\n", header.signature, header.ver, header.res, header.numatoms, header.eeplen);
|
|
|
|
|
|
for (i = 0; i<header.numatoms; i++) {
|
|
|
|
if (!fread(&atom, ATOM_SIZE-CRC_SIZE, 1, fp)) goto err;
|
|
|
|
printf("Reading atom %d...\n", i);
|
|
|
|
fprintf(out, "# Start of atom #%u of type 0x%04x and length %u\n", atom.count, atom.type, atom.dlen);
|
|
|
|
if (atom.count != i) {
|
|
printf("Error: atom count mismatch\n");
|
|
fprintf(out, "# Error: atom count mismatch\n");
|
|
}
|
|
|
|
long pos = ftell(fp);
|
|
char *atom_data = (char *) malloc(atom.dlen + ATOM_SIZE-CRC_SIZE);
|
|
memcpy(atom_data, &atom, ATOM_SIZE-CRC_SIZE);
|
|
if (!fread(atom_data+ATOM_SIZE-CRC_SIZE, atom.dlen, 1, fp)) goto err;
|
|
uint16_t calc_crc = getcrc(atom_data, atom.dlen-CRC_SIZE+ATOM_SIZE-CRC_SIZE);
|
|
fseek(fp, pos, SEEK_SET);
|
|
|
|
if (atom.type==ATOM_VENDOR_TYPE) {
|
|
//decode vendor info
|
|
|
|
if (!fread(&vinf, VENDOR_SIZE, 1, fp)) goto err;
|
|
|
|
fprintf(out, "# Vendor info\n");
|
|
fprintf(out, "product_uuid %08x-%04x-%04x-%04x-%04x%08x\n", vinf.serial_4, vinf.serial_3>>16, vinf.serial_3 & 0xffff, vinf.serial_2>>16, vinf.serial_2 & 0xffff, vinf.serial_1);
|
|
fprintf(out, "product_id 0x%04x\n", vinf.pid);
|
|
fprintf(out, "product_ver 0x%04x\n", vinf.pver);
|
|
|
|
vinf.vstr = (char *) malloc(vinf.vslen+1);
|
|
vinf.pstr = (char *) malloc(vinf.pslen+1);
|
|
|
|
if (!fread(vinf.vstr, vinf.vslen, 1, fp)) goto err;
|
|
if (!fread(vinf.pstr, vinf.pslen, 1, fp)) goto err;
|
|
//close strings
|
|
vinf.vstr[vinf.vslen] = 0;
|
|
vinf.pstr[vinf.pslen] = 0;
|
|
|
|
fprintf(out, "vendor \"%s\" # length=%u\n", vinf.vstr, vinf.vslen);
|
|
fprintf(out, "product \"%s\" # length=%u\n", vinf.pstr, vinf.pslen);
|
|
|
|
if (!fread(&crc, CRC_SIZE, 1, fp)) goto err;
|
|
|
|
} else if (atom.type==ATOM_GPIO_TYPE) {
|
|
//decode GPIO map
|
|
if (!fread(&gpiomap, GPIO_SIZE, 1, fp)) goto err;
|
|
|
|
fprintf(out, "# GPIO map info\n");
|
|
fprintf(out, "gpio_drive %d\n", gpiomap.flags & 15); //1111
|
|
fprintf(out, "gpio_slew %d\n", (gpiomap.flags & 48)>>4); //110000
|
|
fprintf(out, "gpio_hysteresis %d\n", (gpiomap.flags & 192)>>6); //11000000
|
|
fprintf(out, "back_power %d\n", gpiomap.power);
|
|
fprintf(out, "# GPIO FUNCTION PULL\n# ---- -------- ----\n");
|
|
|
|
for (j = 0; j<28; j++) {
|
|
if (gpiomap.pins[j] & (1<<7)) {
|
|
//board uses this pin
|
|
|
|
char *pull_str = "INVALID";
|
|
switch ((gpiomap.pins[j] & 96)>>5) { //1100000
|
|
case 0: pull_str = "DEFAULT";
|
|
break;
|
|
case 1: pull_str = "UP";
|
|
break;
|
|
case 2: pull_str = "DOWN";
|
|
break;
|
|
case 3: pull_str = "NONE";
|
|
break;
|
|
}
|
|
|
|
char *func_str = "INVALID";
|
|
switch ((gpiomap.pins[j] & 7)) { //111
|
|
case 0: func_str = "INPUT";
|
|
break;
|
|
case 1: func_str = "OUTPUT";
|
|
break;
|
|
case 4: func_str = "ALT0";
|
|
break;
|
|
case 5: func_str = "ALT1";
|
|
break;
|
|
case 6: func_str = "ALT2";
|
|
break;
|
|
case 7: func_str = "ALT3";
|
|
break;
|
|
case 3: func_str = "ALT4";
|
|
break;
|
|
case 2: func_str = "ALT5";
|
|
break;
|
|
}
|
|
|
|
fprintf(out, "setgpio %d %s %s\n", j, func_str, pull_str);
|
|
}
|
|
}
|
|
|
|
if (!fread(&crc, CRC_SIZE, 1, fp)) goto err;
|
|
|
|
} else if (atom.type==ATOM_DT_TYPE) {
|
|
//decode DT blob
|
|
|
|
fprintf(out, "dt_blob");
|
|
data = (char *) malloc(atom.dlen-CRC_SIZE);
|
|
if (!fread(data, atom.dlen-CRC_SIZE, 1, fp)) goto err;
|
|
|
|
for (j = 0; j<atom.dlen-CRC_SIZE; j++) {
|
|
if (j % 16 == 0) fprintf(out, "\n");
|
|
fprintf(out, "%02X ", *(data+j));
|
|
}
|
|
|
|
fprintf(out, "\n");
|
|
|
|
if (!fread(&crc, CRC_SIZE, 1, fp)) goto err;
|
|
|
|
} else if (atom.type==ATOM_CUSTOM_TYPE) {
|
|
//decode custom data
|
|
|
|
fprintf(out, "custom_data");
|
|
data = (char *) malloc(atom.dlen-CRC_SIZE);
|
|
if (!fread(data, atom.dlen-CRC_SIZE, 1, fp)) goto err;
|
|
|
|
for (j = 0; j<atom.dlen-CRC_SIZE; j++) {
|
|
if (j % 16 == 0) fprintf(out, "\n");
|
|
fprintf(out, "%02X ", *(data+j));
|
|
}
|
|
|
|
fprintf(out, "\n");
|
|
|
|
if (!fread(&crc, CRC_SIZE, 1, fp)) goto err;
|
|
|
|
|
|
} else {
|
|
printf("Error: unrecognised atom type\n");
|
|
fprintf(out, "# Error: unrecognised atom type\n");
|
|
goto err;
|
|
}
|
|
|
|
fprintf(out, "# End of atom. CRC16=0x%04x\n", crc);
|
|
|
|
if (calc_crc != crc) {
|
|
printf("Error: atom CRC16 mismatch\n");
|
|
fprintf(out, "# Error: atom CRC16 mismatch. Calculated CRC16=0x%02x", crc);
|
|
} else printf("CRC OK\n");
|
|
|
|
fprintf(out, "\n\n");
|
|
|
|
}
|
|
|
|
//Total length checks. We need header.eeplen=current_position=file_length.
|
|
long pos = ftell(fp);
|
|
fseek(fp, 0L, SEEK_END);
|
|
|
|
if (pos!=ftell(fp)) printf("Warning: Dump finished before EOF\n");
|
|
if (pos!=header.eeplen) printf("Warning: Dump finished before length specified in header\n");
|
|
if (ftell(fp)!=header.eeplen) printf("Warning: EOF does not match length specified in header\n");
|
|
|
|
printf("Done.\n");
|
|
|
|
fclose(fp);
|
|
fclose(out);
|
|
return 0;
|
|
|
|
err:
|
|
printf("Unexpected EOF or error occurred\n");
|
|
fclose(fp);
|
|
fclose(out);
|
|
return 0;
|
|
}
|
|
|
|
|
|
int main(int argc, char *argv[]) {
|
|
int ret;
|
|
int i;
|
|
|
|
if (argc<3) {
|
|
printf("Wrong input format.\n");
|
|
printf("Try 'eepdump input_file output_file'\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
ret = read_bin(argv[1], argv[2]);
|
|
if (ret) {
|
|
printf("Error reading input, aborting\n");
|
|
return 0;
|
|
}
|
|
|
|
|
|
return 0;
|
|
}
|