Line 2... |
Line 2... |
//
|
//
|
// Filename: wbprogram.cpp
|
// Filename: wbprogram.cpp
|
//
|
//
|
// Project: OpenArty, an entirely open SoC based upon the Arty platform
|
// Project: OpenArty, an entirely open SoC based upon the Arty platform
|
//
|
//
|
// Purpose: Program the memory with a given '.bin' file.
|
// Purpose: Program the memory with a given '.bin' file onto the flash
|
|
// memory on a given board.
|
//
|
//
|
// Creator: Dan Gisselquist, Ph.D.
|
// Creator: Dan Gisselquist, Ph.D.
|
// Gisselquist Technology, LLC
|
// Gisselquist Technology, LLC
|
//
|
//
|
////////////////////////////////////////////////////////////////////////////////
|
////////////////////////////////////////////////////////////////////////////////
|
//
|
//
|
// Copyright (C) 2015-2016, Gisselquist Technology, LLC
|
// Copyright (C) 2015-2017, Gisselquist Technology, LLC
|
//
|
//
|
// This program is free software (firmware): you can redistribute it and/or
|
// This program is free software (firmware): you can redistribute it and/or
|
// modify it under the terms of the GNU General Public License as published
|
// modify it under the terms of the GNU General Public License as published
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// by the Free Software Foundation, either version 3 of the License, or (at
|
// your option) any later version.
|
// your option) any later version.
|
Line 22... |
Line 23... |
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
// ANY WARRANTY; without even the implied warranty of MERCHANTIBILITY or
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// FITNESS FOR A PARTICULAR PURPOSE. See the GNU General Public License
|
// for more details.
|
// for more details.
|
//
|
//
|
// You should have received a copy of the GNU General Public License along
|
// You should have received a copy of the GNU General Public License along
|
// with this program. (It's in the $(ROOT)/doc directory, run make with no
|
// with this program. (It's in the $(ROOT)/doc directory. Run make with no
|
// target there if the PDF file isn't present.) If not, see
|
// target there if the PDF file isn't present.) If not, see
|
// <http://www.gnu.org/licenses/> for a copy.
|
// <http://www.gnu.org/licenses/> for a copy.
|
//
|
//
|
// License: GPL, v3, as defined and found on www.gnu.org,
|
// License: GPL, v3, as defined and found on www.gnu.org,
|
// http://www.gnu.org/licenses/gpl.html
|
// http://www.gnu.org/licenses/gpl.html
|
Line 47... |
Line 48... |
|
|
#include "port.h"
|
#include "port.h"
|
#include "llcomms.h"
|
#include "llcomms.h"
|
#include "regdefs.h"
|
#include "regdefs.h"
|
#include "flashdrvr.h"
|
#include "flashdrvr.h"
|
|
#include "byteswap.h"
|
|
|
DEVBUS *m_fpga;
|
DEVBUS *m_fpga;
|
void closeup(int v) {
|
void closeup(int v) {
|
m_fpga->kill();
|
m_fpga->kill();
|
exit(0);
|
exit(0);
|
}
|
}
|
|
|
unsigned byteswap(unsigned x) {
|
|
unsigned r;
|
|
|
|
r = x&0x0ff; x>>=8; r<<= 8;
|
|
r |= x&0x0ff; x>>=8; r<<= 8;
|
|
r |= x&0x0ff; x>>=8; r<<= 8;
|
|
r |= x&0x0ff;
|
|
|
|
return r;
|
|
}
|
|
|
|
void usage(void) {
|
void usage(void) {
|
printf("USAGE: wbprogram [@<Address>] file.bit\n");
|
printf("USAGE: wbprogram [@<Address>] file.bit\n");
|
printf("\tYou can also use a .bin file in place of the file.bit.\n");
|
printf("\tYou can also use a .bin file in place of the file.bit.\n");
|
}
|
}
|
|
|
|
void skip_bitfile_header(FILE *fp) {
|
|
const unsigned SEARCHLN = 204, MATCHLN = 52;
|
|
const unsigned char matchstr[MATCHLN] = {
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
//
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
//
|
|
0x00, 0x00, 0x00, 0xbb,
|
|
0x11, 0x22, 0x00, 0x44,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
0xff, 0xff, 0xff, 0xff,
|
|
//
|
|
0xaa, 0x99, 0x55, 0x66 };
|
|
unsigned char buf[SEARCHLN];
|
|
|
|
rewind(fp);
|
|
fread(buf, sizeof(char), SEARCHLN, fp);
|
|
for(int start=0; start+MATCHLN<SEARCHLN; start++) {
|
|
int mloc;
|
|
|
|
// Search backwards, since the starting bytes just aren't that
|
|
// interesting.
|
|
for(mloc = MATCHLN-1; mloc >= 0; mloc--)
|
|
if (buf[start+mloc] != matchstr[mloc])
|
|
break;
|
|
if (mloc < 0) {
|
|
fseek(fp, start, SEEK_SET);
|
|
return;
|
|
}
|
|
}
|
|
|
|
fprintf(stderr, "Could not find bin-file header within bit file\n");
|
|
fclose(fp);
|
|
exit(EXIT_FAILURE);
|
|
}
|
|
|
int main(int argc, char **argv) {
|
int main(int argc, char **argv) {
|
FILE *fp;
|
FILE *fp;
|
const int BUFLN = (1<<20); // 4MB Flash
|
DEVBUS::BUSW addr = EQSPIFLASH;
|
DEVBUS::BUSW *buf = new DEVBUS::BUSW[BUFLN], v, addr = EQSPIFLASH;
|
char *buf = new char[FLASHLEN];
|
FLASHDRVR *flash;
|
FLASHDRVR *flash;
|
int argn = 1;
|
int argn = 1;
|
|
|
if ((argc > argn)&&(NULL != strstr(argv[argn],"tty")))
|
if ((argc > argn)&&(NULL != strstr(argv[argn],"tty")))
|
m_fpga = new FPGA(new TTYCOMMS(argv[argn++]));
|
m_fpga = new FPGA(new TTYCOMMS(argv[argn++]));
|
Line 95... |
Line 128... |
} catch(BUSERR b) {
|
} catch(BUSERR b) {
|
printf("VERSION: (Bus-Err)\n");
|
printf("VERSION: (Bus-Err)\n");
|
exit(-1);
|
exit(-1);
|
}
|
}
|
|
|
// SPI flash testing
|
|
// Enable the faster (vector) reads
|
|
bool vector_read = true;
|
|
unsigned sz;
|
unsigned sz;
|
bool esectors[NSECTORS];
|
|
|
|
argn = 1;
|
argn = 1;
|
if (argc <= argn) {
|
if (argc <= argn) {
|
usage();
|
usage();
|
exit(-1);
|
exit(-1);
|
Line 133... |
Line 162... |
exit(-1);
|
exit(-1);
|
}
|
}
|
|
|
fp = fopen(argv[argn], "r");
|
fp = fopen(argv[argn], "r");
|
if (strcmp(&argv[argn][strlen(argv[argn])-4],".bit")==0)
|
if (strcmp(&argv[argn][strlen(argv[argn])-4],".bit")==0)
|
fseek(fp, 0x5dl, SEEK_SET);
|
skip_bitfile_header(fp);
|
sz = fread(buf, sizeof(buf[0]), BUFLN, fp);
|
sz = fread(buf, sizeof(buf[0]), FLASHLEN, fp);
|
fclose(fp);
|
fclose(fp);
|
|
|
for(int i=0; i<sz; i++) {
|
|
buf[i] = byteswap(buf[i]);
|
|
}
|
|
|
|
try {
|
try {
|
flash->write(addr, sz, buf, true);
|
flash->write(addr, sz, buf, true);
|
} catch(BUSERR b) {
|
} catch(BUSERR b) {
|
fprintf(stderr, "BUS-ERR @0x%08x\n", b.addr);
|
fprintf(stderr, "BUS-ERR @0x%08x\n", b.addr);
|
exit(-1);
|
exit(-1);
|