fix bugs, add cyimg2elf
This commit is contained in:
parent
bed7488a9c
commit
944abc69fc
|
@ -4,3 +4,7 @@
|
||||||
fx3tool
|
fx3tool
|
||||||
*.img
|
*.img
|
||||||
*.txt
|
*.txt
|
||||||
|
fx3_images/
|
||||||
|
*.elf
|
||||||
|
cyimg2elf
|
||||||
|
elf2img*
|
||||||
|
|
14
Makefile
14
Makefile
|
@ -1,12 +1,18 @@
|
||||||
|
|
||||||
default: all
|
default: all
|
||||||
|
|
||||||
all: fx3tool
|
CFLAGS += -g -Og
|
||||||
|
CXXFLAGS += $(CFLAGS)
|
||||||
|
|
||||||
fx3tool: cyusb.h download_fx3.cpp libcyusb.cpp
|
all: fx3tool cyimg2elf
|
||||||
$(CXX) -o "$@" $^ -lusb-1.0
|
|
||||||
|
fx3tool: download_fx3.cpp libcyusb.cpp cyusb.h
|
||||||
|
$(CXX) $(CXXFLAGS) -o "$@" download_fx3.cpp libcyusb.cpp -lusb-1.0
|
||||||
|
|
||||||
|
cyimg2elf: cyimg2elf.c cyimg.h
|
||||||
|
$(CC) $(CFLAGS) -o "$@" "$<"
|
||||||
|
|
||||||
clean:
|
clean:
|
||||||
@$(RM) -v fx3tool
|
@$(RM) -v fx3tool cyimg2elf
|
||||||
|
|
||||||
.PHONY: all default clean
|
.PHONY: all default clean
|
||||||
|
|
|
@ -0,0 +1,73 @@
|
||||||
|
|
||||||
|
#ifndef CYIMG_H_
|
||||||
|
#define CYIMG_H_
|
||||||
|
|
||||||
|
#include <stddef.h>
|
||||||
|
#include <stdint.h>
|
||||||
|
|
||||||
|
//#ifdef __LITTLE_ENDIAN__
|
||||||
|
#define CYIMG_MAGIC ('C'|(((uint16_t)'Y')<<8))
|
||||||
|
//#else
|
||||||
|
//#define CYIMG_MAGIC ((((uint16_t)'C')<<8)|'Y')
|
||||||
|
//#endif
|
||||||
|
|
||||||
|
#define CYIMG_R32(d) (((uint32_t)(d)[0]<<0)|((uint32_t)(d)[1]<<8)|((uint32_t)(d)[2]<<16)|((uint32_t)(d)[3]<<24))
|
||||||
|
|
||||||
|
#define CYIMG_IMAGECTL_EXECUTABLE_MASK (1<<0)
|
||||||
|
#define CYIMG_IMAGECTL_EXECUTABLE_LSB ( 0)
|
||||||
|
|
||||||
|
#define CYIMG_IMAGECTL_I2CROMSIZE_MASK (7<<1)
|
||||||
|
#define CYIMG_IMAGECTL_I2CROMSIZE_LSB ( 1)
|
||||||
|
|
||||||
|
#define CYIMG_IMAGECTL_SPISPEED_MASK (3<<4)
|
||||||
|
#define CYIMG_IMAGECTL_SPISPEED_LSB ( 4)
|
||||||
|
|
||||||
|
#define CYIMG_IMAGETYPE_REGULAR 0xB0
|
||||||
|
#define CYIMG_IMAGETYPE_USBIDS 0xB2
|
||||||
|
|
||||||
|
struct cyimg_section {
|
||||||
|
uint32_t dLength; // in 32-bit units
|
||||||
|
uint32_t dAddress; // aligned to 32 bits
|
||||||
|
// data follows immediately after
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cyimg_hdr {
|
||||||
|
uint16_t wSignature;
|
||||||
|
|
||||||
|
uint8_t bImageCTL;
|
||||||
|
// bit 0: executable?
|
||||||
|
// bit 1..3: I2C EEPROM size
|
||||||
|
// bit 4..5: SPI speed (10/20/30/reserved MHz) OR I2C speed (100/400/1000/reserved kHz)
|
||||||
|
// bit 6..7: reserved (zero)
|
||||||
|
|
||||||
|
uint8_t bImageType;
|
||||||
|
// 0xB0: regular firmware image
|
||||||
|
// 0xB2: firmware image with VID/PID in 1st section
|
||||||
|
|
||||||
|
struct cyimg_section usb_info; // optional (see bImageType)
|
||||||
|
};
|
||||||
|
|
||||||
|
struct cyimg_footer {
|
||||||
|
struct cyimg_section entry;
|
||||||
|
uint32_t dChecksum;
|
||||||
|
};
|
||||||
|
|
||||||
|
#define CYIMG_CHECKSUM_INIT 0
|
||||||
|
|
||||||
|
static inline uint32_t cyimg_checksum_calc(uint32_t init, size_t length,
|
||||||
|
const uint8_t* data) {
|
||||||
|
uint32_t v = init;
|
||||||
|
|
||||||
|
for (size_t i = 0; i < length; ++i) v += CYIMG_R32(&data[i]);
|
||||||
|
|
||||||
|
return v;
|
||||||
|
}
|
||||||
|
|
||||||
|
// ---
|
||||||
|
|
||||||
|
#define ELF_FX3_NOTE_NAME "FX3"
|
||||||
|
#define ELF_FX3_NOTE_TYPE_IMAGECTLTYPE 1
|
||||||
|
#define ELF_FX3_NOTE_TYPE_USBVIDPID 2
|
||||||
|
|
||||||
|
#endif
|
||||||
|
|
|
@ -0,0 +1,323 @@
|
||||||
|
|
||||||
|
#include <stdbool.h>
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <string.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <elf.h>
|
||||||
|
|
||||||
|
#include "cyimg.h"
|
||||||
|
|
||||||
|
static const uint32_t i2ceep_sizes[] = {
|
||||||
|
4096,
|
||||||
|
8192,
|
||||||
|
16384,
|
||||||
|
32768,
|
||||||
|
65536, // also Atmel 128k and ST 256k
|
||||||
|
131072, // Microchip (except 24LC1026)
|
||||||
|
};
|
||||||
|
static const uint32_t i2c_speeds_khz[] = { 100, 400, 1000 };
|
||||||
|
static const uint32_t spi_speeds_mhz[] = { 10, 20, 30 };
|
||||||
|
|
||||||
|
static bool validate_cyimg(size_t size, const uint8_t* data) {
|
||||||
|
if (size < 4) return false;
|
||||||
|
|
||||||
|
uint16_t wSignature = data[0] | (((uint16_t)data[1]) << 8);
|
||||||
|
|
||||||
|
if (wSignature != CYIMG_MAGIC) return false;
|
||||||
|
|
||||||
|
if (data[3] == CYIMG_IMAGETYPE_USBIDS)
|
||||||
|
return size == 8; // nothing else to verify
|
||||||
|
|
||||||
|
if (data[3] != CYIMG_IMAGETYPE_REGULAR) return false;
|
||||||
|
|
||||||
|
size_t cpos = 4;
|
||||||
|
printf("size=0x%zx\n", size);
|
||||||
|
while (true) {
|
||||||
|
//printf("cpos=0x%zx\n", cpos);
|
||||||
|
if (cpos + 8 > size) return false;
|
||||||
|
|
||||||
|
struct cyimg_section sec;
|
||||||
|
sec.dLength = CYIMG_R32(&data[cpos])*4;
|
||||||
|
cpos += 4;
|
||||||
|
sec.dAddress = CYIMG_R32(&data[cpos]);
|
||||||
|
cpos += 4;
|
||||||
|
|
||||||
|
printf("len=0x%x addr=0x%x\n", sec.dLength, sec.dAddress);
|
||||||
|
|
||||||
|
if (sec.dAddress & 3) return false;
|
||||||
|
|
||||||
|
if (sec.dLength == 0) break;
|
||||||
|
|
||||||
|
cpos += sec.dLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
//printf("cpos+4=0x%zx size=0x%zx\n", cpos+4, size);
|
||||||
|
return true;//cpos + 4 == size; // checksum
|
||||||
|
}
|
||||||
|
static bool validate_checksum(size_t size, const uint8_t* data) {
|
||||||
|
if (size < 4) return false;
|
||||||
|
|
||||||
|
if (data[3] == CYIMG_IMAGETYPE_USBIDS)
|
||||||
|
return true; // nothing else to verify
|
||||||
|
if (data[3] != CYIMG_IMAGETYPE_REGULAR) return false;
|
||||||
|
|
||||||
|
size_t cpos = 4;
|
||||||
|
uint32_t ckcalc = CYIMG_CHECKSUM_INIT;
|
||||||
|
while (true) {
|
||||||
|
if (cpos + 8 > size) return false;
|
||||||
|
|
||||||
|
struct cyimg_section sec;
|
||||||
|
sec.dLength = CYIMG_R32(&data[cpos])*4;
|
||||||
|
cpos += 4;
|
||||||
|
sec.dAddress = CYIMG_R32(&data[cpos]);
|
||||||
|
cpos += 4;
|
||||||
|
|
||||||
|
if (sec.dLength == 0) break;
|
||||||
|
|
||||||
|
ckcalc = cyimg_checksum_calc(ckcalc, sec.dLength, &data[cpos]);
|
||||||
|
cpos += sec.dLength;
|
||||||
|
}
|
||||||
|
|
||||||
|
if (cpos + 4 != size) return false;
|
||||||
|
|
||||||
|
return ckcalc == CYIMG_R32(&data[cpos]);
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_usbids(FILE* out, size_t size, const uint8_t* data) {
|
||||||
|
size_t outsize = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr) + 2*(sizeof(Elf32_Nhdr)+4+4);
|
||||||
|
uint8_t* buf = calloc(1, outsize);
|
||||||
|
|
||||||
|
Elf32_Ehdr* ehdr = (Elf32_Ehdr*)&buf[0];
|
||||||
|
Elf32_Phdr* phdr = (Elf32_Phdr*)&ehdr[1];
|
||||||
|
Elf32_Nhdr* nhdr = (Elf32_Nhdr*)&phdr[1];
|
||||||
|
uint8_t* ndata = (uint8_t*)&nhdr[1];
|
||||||
|
Elf32_Nhdr* nhdr2 = (Elf32_Nhdr*)&ndata[8];
|
||||||
|
uint8_t* ndata2 = (uint8_t*)&nhdr2[1];
|
||||||
|
|
||||||
|
ehdr->e_ident[0] = 0x7f;
|
||||||
|
ehdr->e_ident[1] = 'E';
|
||||||
|
ehdr->e_ident[2] = 'L';
|
||||||
|
ehdr->e_ident[3] = 'F';
|
||||||
|
ehdr->e_ident[4] = ELFCLASS32;
|
||||||
|
//#ifdef __LITTLE_ENDIAN__
|
||||||
|
ehdr->e_ident[5] = ELFDATA2LSB;
|
||||||
|
//#else
|
||||||
|
// ehdr->e_ident[5] = ELFDATA2MSB;
|
||||||
|
//#endif
|
||||||
|
ehdr->e_ident[6] = EV_CURRENT;
|
||||||
|
ehdr->e_ident[7] = ELFOSABI_SYSV;
|
||||||
|
|
||||||
|
ehdr->e_type = ET_EXEC;
|
||||||
|
ehdr->e_machine = EM_ARM;
|
||||||
|
ehdr->e_version = EV_CURRENT;
|
||||||
|
ehdr->e_phoff = sizeof(Elf32_Ehdr);
|
||||||
|
ehdr->e_phentsize = sizeof(Elf32_Phdr);
|
||||||
|
ehdr->e_phnum = 1;
|
||||||
|
|
||||||
|
phdr->p_type = PT_NOTE;
|
||||||
|
phdr->p_offset = sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr);
|
||||||
|
phdr->p_vaddr = sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr);
|
||||||
|
phdr->p_paddr = sizeof(Elf32_Ehdr)+sizeof(Elf32_Phdr);
|
||||||
|
phdr->p_filesz = 2*sizeof(Elf32_Nhdr)+2*4+4+2;
|
||||||
|
phdr->p_memsz = 2*sizeof(Elf32_Nhdr)+2*4+4+2;
|
||||||
|
phdr->p_flags = PF_R;
|
||||||
|
phdr->p_align = 4;
|
||||||
|
|
||||||
|
nhdr->n_namesz = 4;
|
||||||
|
nhdr->n_descsz = 4;
|
||||||
|
nhdr->n_type = ELF_FX3_NOTE_TYPE_USBVIDPID;
|
||||||
|
|
||||||
|
ndata[0] = 'F'; ndata[1] = 'X'; ndata[2] = '3'; ndata[3] = '\0';
|
||||||
|
ndata[4] = data[4]; ndata[5] = data[5]; ndata[6] = data[6]; ndata[7] = data[7];
|
||||||
|
|
||||||
|
nhdr2->n_namesz = 4;
|
||||||
|
nhdr2->n_descsz = 2;
|
||||||
|
nhdr2->n_type = ELF_FX3_NOTE_TYPE_IMAGECTLTYPE;
|
||||||
|
|
||||||
|
ndata2[0] = 'F'; ndata2[1] = 'X'; ndata2[2] = '3'; ndata2[3] = '\0';
|
||||||
|
ndata2[4] = data[2]; ndata2[5] = data[3];
|
||||||
|
|
||||||
|
if (fwrite(buf, 1, outsize, out) != outsize) {
|
||||||
|
fprintf(stderr, "E: cannot write to output.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
static int write_regular(FILE* out, size_t size, const uint8_t* data) {
|
||||||
|
uint32_t nsections = 0,
|
||||||
|
totalsize = 0,
|
||||||
|
entrypt = 0;
|
||||||
|
|
||||||
|
uint32_t curoff = 4;
|
||||||
|
while (true) {
|
||||||
|
uint32_t len = CYIMG_R32(&data[curoff])*4;
|
||||||
|
curoff += 4;
|
||||||
|
uint32_t addr = CYIMG_R32(&data[curoff]);
|
||||||
|
curoff += 4;
|
||||||
|
if (len == 0) {
|
||||||
|
entrypt = addr;
|
||||||
|
break;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("section: addr=0x%x off=0x%x size=0x%x\n", addr, curoff, len);
|
||||||
|
totalsize += len;
|
||||||
|
curoff += len;
|
||||||
|
++nsections;
|
||||||
|
}
|
||||||
|
|
||||||
|
printf("totalsize=0x%lx nsections=0x%lx\n", totalsize, nsections);
|
||||||
|
struct { uint32_t addr, off, size; } insections[nsections];
|
||||||
|
|
||||||
|
curoff = 4;
|
||||||
|
for (size_t i = 0; i < nsections; ++i) {
|
||||||
|
uint32_t len = CYIMG_R32(&data[curoff])*4;
|
||||||
|
curoff += 4;
|
||||||
|
uint32_t addr = CYIMG_R32(&data[curoff]);
|
||||||
|
curoff += 4;
|
||||||
|
if (len == 0) break;
|
||||||
|
|
||||||
|
printf("insection %zu: addr=0x%x off=0x%x size=0x%x\n", i, addr, curoff, len);
|
||||||
|
insections[i].addr = addr;
|
||||||
|
insections[i].off = curoff;
|
||||||
|
insections[i].size = len;
|
||||||
|
|
||||||
|
curoff += len;
|
||||||
|
}
|
||||||
|
|
||||||
|
// TODO: allocate data for:
|
||||||
|
// * EHDR
|
||||||
|
// * n+1 PHDRs
|
||||||
|
// * n sections
|
||||||
|
// * 1 note for bImageCTL/bImageType
|
||||||
|
// * data
|
||||||
|
size_t outsize = sizeof(Elf32_Ehdr) + sizeof(Elf32_Phdr)*(1+nsections)
|
||||||
|
+ totalsize + (sizeof(Elf32_Nhdr)+4+2 +2);
|
||||||
|
uint8_t* buf = calloc(1, outsize);
|
||||||
|
|
||||||
|
Elf32_Ehdr* ehdr = (Elf32_Ehdr*)(buf + 0);
|
||||||
|
Elf32_Phdr* phdr = (Elf32_Phdr*)(buf + sizeof(Elf32_Ehdr));
|
||||||
|
/*uint8_t* sdata = buf + sizeof(Elf32_Ehdr) + (nsections+1)*sizeof(Elf32_Phdr);
|
||||||
|
Elf32_Nhdr* nhdr = (Elf32_Nhdr*)(sdata + totalsize);
|
||||||
|
uint8_t* ndata = sdata + totalsize + sizeof(Elf32_Nhdr);*/
|
||||||
|
Elf32_Nhdr* nhdr = (Elf32_Nhdr*)(buf + sizeof(Elf32_Ehdr) + (nsections+1)*sizeof(Elf32_Phdr));
|
||||||
|
uint8_t* ndata = buf + sizeof(Elf32_Ehdr) + (nsections+1)*sizeof(Elf32_Phdr) + sizeof(Elf32_Nhdr);
|
||||||
|
uint8_t* sdata = ndata + 8;
|
||||||
|
|
||||||
|
ehdr->e_ident[0] = 0x7f;
|
||||||
|
ehdr->e_ident[1] = 'E';
|
||||||
|
ehdr->e_ident[2] = 'L';
|
||||||
|
ehdr->e_ident[3] = 'F';
|
||||||
|
ehdr->e_ident[4] = ELFCLASS32;
|
||||||
|
//#ifdef __LITTLE_ENDIAN__
|
||||||
|
ehdr->e_ident[5] = ELFDATA2LSB;
|
||||||
|
//#else
|
||||||
|
// ehdr->e_ident[5] = ELFDATA2MSB;
|
||||||
|
//#endif
|
||||||
|
ehdr->e_ident[6] = EV_CURRENT;
|
||||||
|
ehdr->e_ident[7] = ELFOSABI_SYSV;
|
||||||
|
|
||||||
|
ehdr->e_type = ET_EXEC;
|
||||||
|
ehdr->e_machine = EM_ARM;
|
||||||
|
ehdr->e_version = EV_CURRENT;
|
||||||
|
ehdr->e_entry = entrypt;
|
||||||
|
ehdr->e_phoff = sizeof(Elf32_Ehdr);
|
||||||
|
ehdr->e_phentsize = sizeof(Elf32_Phdr);
|
||||||
|
ehdr->e_phnum = 1 + nsections;
|
||||||
|
|
||||||
|
for (size_t i = 0, coff = 0; i < nsections; ++i) {
|
||||||
|
phdr[i].p_type = PT_LOAD;
|
||||||
|
phdr[i].p_offset = coff + (size_t)sdata - (size_t)ehdr;
|
||||||
|
phdr[i].p_vaddr = insections[i].addr;
|
||||||
|
phdr[i].p_paddr = insections[i].addr;
|
||||||
|
phdr[i].p_filesz = insections[i].size;
|
||||||
|
phdr[i].p_memsz = insections[i].size;
|
||||||
|
phdr[i].p_flags = PF_R|PF_W|PF_X;
|
||||||
|
phdr[i].p_align = 4;
|
||||||
|
|
||||||
|
printf("dest=%p src=%p, size=0x%x\n", sdata+coff, data+insections[i].off, insections[i].size);
|
||||||
|
memcpy(sdata + coff, data + insections[i].off, insections[i].size);
|
||||||
|
coff += insections[i].size;
|
||||||
|
}
|
||||||
|
phdr[nsections].p_type = PT_NOTE;
|
||||||
|
phdr[nsections].p_offset = (size_t)nhdr - (size_t)ehdr;
|
||||||
|
phdr[nsections].p_vaddr = (size_t)nhdr - (size_t)ehdr;
|
||||||
|
phdr[nsections].p_paddr = (size_t)nhdr - (size_t)ehdr;
|
||||||
|
phdr[nsections].p_filesz = sizeof(Elf32_Nhdr)+4+2;
|
||||||
|
phdr[nsections].p_memsz = sizeof(Elf32_Nhdr)+4+2;
|
||||||
|
phdr[nsections].p_flags = PF_R;
|
||||||
|
phdr[nsections].p_align = 4;
|
||||||
|
|
||||||
|
nhdr->n_namesz = 4;
|
||||||
|
nhdr->n_descsz = 2;
|
||||||
|
nhdr->n_type = ELF_FX3_NOTE_TYPE_IMAGECTLTYPE;
|
||||||
|
|
||||||
|
ndata[0] = 'F'; ndata[1] = 'X'; ndata[2] = '3'; ndata[3] = '\0';
|
||||||
|
ndata[4] = data[2]; ndata[5] = data[3];
|
||||||
|
|
||||||
|
if (fwrite(buf, 1, outsize, out) != outsize) {
|
||||||
|
fprintf(stderr, "E: cannot write to output.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
if (argc != 2 && argc != 3) {
|
||||||
|
fprintf(stderr, "Usage: %s <input file.img> [<output file.elf>]\n", argv[0]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
FILE* f = fopen(argv[1], "rb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "E: cannot open file '%s'\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
struct stat st;
|
||||||
|
if (fstat(fileno(f), &st)) {
|
||||||
|
fprintf(stderr, "E: cannot stat file '%s'\n", argv[1]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
uint8_t* data = (uint8_t*)calloc(1, st.st_size);
|
||||||
|
if (fread(data, 1, st.st_size, f) != st.st_size) {
|
||||||
|
fprintf(stderr, "E: read error.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
|
||||||
|
fclose(f);
|
||||||
|
|
||||||
|
if (!validate_cyimg(st.st_size, data)) {
|
||||||
|
fprintf(stderr, "E: file does not contain a valid Cypress FX3 image.\n");
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
if (!validate_checksum(st.st_size, data)) {
|
||||||
|
fprintf(stderr, "W: invalid checksum.\n");
|
||||||
|
}
|
||||||
|
|
||||||
|
f = stdout;
|
||||||
|
if (argc == 3) {
|
||||||
|
f = fopen(argv[2], "wb");
|
||||||
|
if (!f) {
|
||||||
|
fprintf(stderr, "E: cannot open output file '%s'\n", argv[2]);
|
||||||
|
return 1;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
int r = 1;
|
||||||
|
if (data[3] == CYIMG_IMAGETYPE_USBIDS) {
|
||||||
|
r = write_usbids(f, st.st_size, data);
|
||||||
|
} else if (data[3] == CYIMG_IMAGETYPE_REGULAR) {
|
||||||
|
r = write_regular(f, st.st_size, data);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (argc == 3) fclose(f);
|
||||||
|
free(data);
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
|
@ -314,9 +314,7 @@ get_fx3_prog_handle (
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
printf("cyusb close\n");
|
|
||||||
cyusb_close ();
|
cyusb_close ();
|
||||||
printf("cyusb closeD!\n");
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
@ -324,10 +322,10 @@ get_fx3_prog_handle (
|
||||||
return -2;
|
return -2;
|
||||||
}
|
}
|
||||||
|
|
||||||
static int fx3_init_progimg(cyusb_handle* h) {
|
static int fx3_init_progimg(cyusb_handle** h) {
|
||||||
int r = 0;
|
int r = 0;
|
||||||
|
|
||||||
r = get_fx3_prog_handle(&h);
|
r = get_fx3_prog_handle(h);
|
||||||
if (r != 0) {
|
if (r != 0) {
|
||||||
fprintf (stderr, "Error: FX3 flash programmer not found\n");
|
fprintf (stderr, "Error: FX3 flash programmer not found\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -371,8 +369,11 @@ fx3_i2c_read (
|
||||||
cyusb_handle *h,
|
cyusb_handle *h,
|
||||||
uint8_t* dst,
|
uint8_t* dst,
|
||||||
int devAddr,
|
int devAddr,
|
||||||
|
// unsigned short addroff,
|
||||||
int len)
|
int len)
|
||||||
{
|
{
|
||||||
|
printf("i2c read addr=0x%x len=0x%x\n", devAddr, len);
|
||||||
|
|
||||||
int r = 0;
|
int r = 0;
|
||||||
int index = 0;
|
int index = 0;
|
||||||
unsigned short address = 0;
|
unsigned short address = 0;
|
||||||
|
@ -380,7 +381,8 @@ fx3_i2c_read (
|
||||||
|
|
||||||
while (len > 0) {
|
while (len > 0) {
|
||||||
size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len;
|
size = (len > MAX_WRITE_SIZE) ? MAX_WRITE_SIZE : len;
|
||||||
r = cyusb_control_transfer (h, 0xC0, 0xBB, devAddr, address, dst, size, VENDORCMD_TIMEOUT);
|
printf("i2crd devaddr=%d address=0x%x size=0x%x\n", devAddr, address, size);
|
||||||
|
r = cyusb_control_transfer (h, 0xC0, 0xBB, devAddr, address /*+ addroff*/, dst, size, VENDORCMD_TIMEOUT);
|
||||||
if (r != size) {
|
if (r != size) {
|
||||||
fprintf (stderr, "Error: I2C read failed\n");
|
fprintf (stderr, "Error: I2C read failed\n");
|
||||||
return -1;
|
return -1;
|
||||||
|
@ -512,6 +514,34 @@ fx3_i2cboot_download (
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
int fx3_i2c_readout(cyusb_handle* h, uint8_t* dst, int offset, int length)
|
||||||
|
{
|
||||||
|
int r = 0;
|
||||||
|
int address = 0;
|
||||||
|
int dstoff = 0;
|
||||||
|
|
||||||
|
while (length > 0) {
|
||||||
|
int size = length;
|
||||||
|
if (size > I2C_SLAVE_SIZE) size = I2C_SLAVE_SIZE;
|
||||||
|
/*if (size > I2C_SLAVE_SIZE) {
|
||||||
|
r = fx3_i2c_read(h, dst + dstoff, address, I2C_SLAVE_SIZE);
|
||||||
|
if (r) return r;
|
||||||
|
|
||||||
|
r = fx3_i2c_read(h, dst + dstoff + I2C_SLAVE_SIZE, address + 4, size - I2C_SLAVE_SIZE);
|
||||||
|
} else*/ {
|
||||||
|
r = fx3_i2c_read(h, dst + dstoff, address, size);
|
||||||
|
}
|
||||||
|
|
||||||
|
if (r) return r;
|
||||||
|
|
||||||
|
dstoff += size;
|
||||||
|
length -= size;
|
||||||
|
address++;
|
||||||
|
}
|
||||||
|
|
||||||
|
return 0;
|
||||||
|
}
|
||||||
|
|
||||||
static int
|
static int
|
||||||
fx3_spi_read (
|
fx3_spi_read (
|
||||||
cyusb_handle *h,
|
cyusb_handle *h,
|
||||||
|
@ -794,13 +824,11 @@ int main (
|
||||||
r = fx3_ram_read(h, databuf, offset, length);
|
r = fx3_ram_read(h, databuf, offset, length);
|
||||||
break;
|
break;
|
||||||
case FW_TARGET_I2C:
|
case FW_TARGET_I2C:
|
||||||
r = fx3_init_progimg(h);
|
r = fx3_init_progimg(&h);
|
||||||
printf("progimg done\n");
|
if (r == 0) r = fx3_i2c_readout(h, databuf, offset, length);
|
||||||
if (r == 0) r = fx3_i2c_read(h, databuf, offset, length);
|
|
||||||
printf("read done\n");
|
|
||||||
break;
|
break;
|
||||||
case FW_TARGET_SPI:
|
case FW_TARGET_SPI:
|
||||||
r = fx3_init_progimg(h);
|
r = fx3_init_progimg(&h);
|
||||||
if (r == 0) r = fx3_spi_read(h, databuf, offset, length);
|
if (r == 0) r = fx3_spi_read(h, databuf, offset, length);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
@ -829,7 +857,7 @@ int main (
|
||||||
|
|
||||||
switch (tgt) {
|
switch (tgt) {
|
||||||
case FW_TARGET_SPI:
|
case FW_TARGET_SPI:
|
||||||
r = fx3_init_progimg(h);
|
r = fx3_init_progimg(&h);
|
||||||
if (r == 0) r = fx3_spi_erase_sector(h, offset);
|
if (r == 0) r = fx3_spi_erase_sector(h, offset);
|
||||||
break;
|
break;
|
||||||
default:
|
default:
|
||||||
|
|
|
@ -0,0 +1,10 @@
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <stdio.h>
|
||||||
|
#include <sys/types.h>
|
||||||
|
#include <sys/stat.h>
|
||||||
|
#include <elf.h>
|
||||||
|
|
||||||
|
int main(int argc, char* argv[]) {
|
||||||
|
|
||||||
|
}
|
Loading…
Reference in New Issue