122 lines
3.1 KiB
C++
122 lines
3.1 KiB
C++
|
#include <signal.h>
|
||
|
#include <cstdio>
|
||
|
#include <sys/types.h>
|
||
|
#include <sys/stat.h>
|
||
|
#include <unistd.h>
|
||
|
#include "usart.h"
|
||
|
#include "fifo.h"
|
||
|
#include "linkprotocol.h"
|
||
|
#include "helpers.h"
|
||
|
|
||
|
static constexpr unsigned FlashBlockSize = 0x1000u;
|
||
|
volatile bool loop = false;
|
||
|
void sig_handler (int) {
|
||
|
loop = false;
|
||
|
}
|
||
|
static UsartClass usart ("/dev/serial/by-id/usb-Kizarm_Labs._Flash_Programmer_0001-if00", 9600);
|
||
|
static MemoryBase mem (0x400u * FlashBlockSize); // 4MiB flash
|
||
|
static CdcCmd cmd;
|
||
|
static LinkProtocol lnk (cmd, mem);
|
||
|
|
||
|
static void read_flash (const unsigned len) {
|
||
|
lnk.StartOperation();
|
||
|
while (loop) {
|
||
|
unsigned value;
|
||
|
char * res = cmd.GetLine(value);
|
||
|
if (value == 0u) continue;
|
||
|
lnk.ParseLine(res);
|
||
|
if (lnk.isEOF(len)) break;
|
||
|
lnk.ReadMem();
|
||
|
}
|
||
|
}
|
||
|
static void erase_blocks (const unsigned num = 1) {
|
||
|
unsigned block = 0u;
|
||
|
lnk.StartOperation();
|
||
|
while (loop) {
|
||
|
unsigned value;
|
||
|
char * res = cmd.GetLine(value);
|
||
|
if (value == 0u) continue;
|
||
|
if (block >= num) break;
|
||
|
lnk.ParseLine(res);
|
||
|
lnk.Erase (block);
|
||
|
printf("Erasing blok %d \r", block);
|
||
|
fflush(stdout);
|
||
|
block += 1u;
|
||
|
}
|
||
|
}
|
||
|
static uint8_t * open_file_for_read (const char * name, unsigned & len) {
|
||
|
struct stat prop;
|
||
|
const int r = stat (name, & prop);
|
||
|
if (r) return nullptr;
|
||
|
const unsigned flen = prop.st_size;
|
||
|
FILE * in = fopen (name, "r");
|
||
|
uint8_t * data = new uint8_t [flen];
|
||
|
const int l = fread (data, 1, flen, in);
|
||
|
printf("readen = %d bytes\n", l);
|
||
|
fclose(in);
|
||
|
len = flen;
|
||
|
return data;
|
||
|
}
|
||
|
static void read_flash_binary (const char * name) {
|
||
|
const unsigned flen = 0x10000u;
|
||
|
printf("Read data\n");
|
||
|
read_flash (flen);
|
||
|
FILE * out = fopen(name,"w");
|
||
|
int r = fwrite(mem.getData(), 1, flen, out);
|
||
|
(void) r;
|
||
|
fclose(out);
|
||
|
}
|
||
|
static void write_flash_binary (const char * name) {
|
||
|
unsigned flen = 0u;
|
||
|
uint8_t * data = open_file_for_read(name, flen);
|
||
|
if (!data) return;
|
||
|
printf("Write data\n");
|
||
|
uint32_t blocks = flen / FlashBlockSize;
|
||
|
if (flen % FlashBlockSize) blocks += 1u;
|
||
|
erase_blocks (blocks);
|
||
|
|
||
|
lnk.StartOperation();
|
||
|
lnk.WriteMem (data, flen);
|
||
|
delete [] data;
|
||
|
}
|
||
|
static void verify_flash_binary (const char * name) {
|
||
|
unsigned flen = 0u;
|
||
|
uint8_t * data = open_file_for_read(name, flen);
|
||
|
if (!data) return;
|
||
|
printf("Verify data\n");
|
||
|
read_flash (flen);
|
||
|
uint8_t * fdata = mem.getData();
|
||
|
unsigned ok = 0;
|
||
|
for (unsigned n=0u; n<flen; n++) {
|
||
|
if (fdata[n] != data[n]) {
|
||
|
printf("err at %04X - %02X != %02X\n", n, fdata[n], data[n]);
|
||
|
ok += 1u;
|
||
|
}
|
||
|
}
|
||
|
if (ok == 0u) printf("\nFlash OK\n");
|
||
|
else printf("\nTotal errors = %d\n", ok);
|
||
|
|
||
|
delete [] data;
|
||
|
}
|
||
|
|
||
|
int main(int argc, char *argv[]) {
|
||
|
if (argc < 3) {
|
||
|
printf("Usage:\r\t$ %s r|w|v file.bin\n", argv[0]);
|
||
|
return 0;
|
||
|
}
|
||
|
loop = true;
|
||
|
signal(SIGINT, sig_handler);
|
||
|
cmd += usart;
|
||
|
if (argv[1][0] == 'r') {
|
||
|
read_flash_binary (argv[2]);
|
||
|
} else if (argv[1][0] == 'w') {
|
||
|
write_flash_binary(argv[2]);
|
||
|
} else if (argv[1][0] == 'v') {
|
||
|
verify_flash_binary(argv[2]);
|
||
|
} else {
|
||
|
printf("bad parameter %s\n", argv[1]);
|
||
|
}
|
||
|
|
||
|
return 0;
|
||
|
}
|