RISC-V/V203F6P6/programmer/software/main.cpp

122 lines
3.1 KiB
C++
Raw Normal View History

2025-02-03 19:18:47 +01:00
#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;
}