1
0
mirror of git://projects.qi-hardware.com/nn-usb-fpga.git synced 2025-01-09 08:00:15 +02:00
nn-usb-fpga/Software/xc3sprog/bitfile.cpp

144 lines
2.9 KiB
C++
Raw Normal View History

/* Xilinx .bit file parser
Copyright (C) 2004 Andrew Rogers
This program is free software; you can redistribute it and/or modify
it under the terms of the GNU General Public License as published by
the Free Software Foundation; either version 2 of the License, or
(at your option) any later version.
This program is distributed in the hope that it will be useful,
but WITHOUT ANY WARRANTY; without even the implied warranty of
MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
GNU General Public License for more details.
You should have received a copy of the GNU General Public License
along with this program; if not, write to the Free Software
Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA */
#include "bitfile.h"
using namespace std;
BitFile::BitFile()
{
Error=false;
logfile=stderr;
initFlip();
buffer=0;
length=0;
}
unsigned long BitFile::load(const char *fname)
{
FILE *fp=fopen(fname,"rb");
if(fp==0){
string err="Cannot open file '";
err+=fname;
err+="'";
error(err);
return 0;
}
filename=fname;
// Parse the header
char hdr[13];
fread(hdr,1,13,fp); // 13 byte header
char key;
do{
fread(&key,1,1,fp);
if(key=='a')readField(ncdFilename,fp);
if(key=='b')readField(partName,fp);
if(key=='c')readField(date,fp);
if(key=='d')readField(time,fp);
}while(key!='e'&&!feof(fp));
if(key=='e')processData(fp); // This is the data
else{
error("Unexpected end of file");
fclose(fp);
return 0;
}
fclose(fp);
return getLength();
}
void BitFile::processData(FILE *fp)
{
byte t[4];
fread(t,1,4,fp);
length=(t[0]<<24)+(t[1]<<16)+(t[2]<<8)+t[3];
if(buffer) delete [] buffer;
buffer=new byte[length];
for(int i=0; i<length&&!feof(fp); i++){
byte b;
fread(&b,1,1,fp);
buffer[i]=bitRevTable[b]; // Reverse the bit order.
}
if(feof(fp)){
error("Unexpected end of file");
length=0;
}
fread(t,1,1,fp);
if(!feof(fp))error("Ignoring extra data at end of file");
}
unsigned long BitFile::saveAsBin(const char *fname)
{
if(length<=0)return length;
FILE *fptr=fopen(fname,"wb");
if(fptr==0){
string err="Cannot open file'";
err+=fname;
err+="'";
error(err);
return 0;
}
for(int i=0; i<length; i++){
byte b=bitRevTable[buffer[i]]; // Reverse bit order
fwrite(&b,1,1,fptr);
}
fclose(fptr);
return length;
}
void BitFile::error(const string &str)
{
errorStr=str;
Error=true;
fprintf(logfile,"%s\n",str.c_str());
}
void BitFile::readField(string &field, FILE *fp)
{
byte t[2];
fread(t,1,2,fp);
unsigned short len=(t[0]<<8)+t[1];
for(int i=0; i<len; i++){
byte b;
fread(&b,1,1,fp);
field+=(char)b;
}
}
void BitFile::initFlip()
{
for(int i=0; i<256; i++){
int num=i;
int fnum=0;
for(int k=0; k<8; k++){
int bit=num&1;
num=num>>1;
fnum=(fnum<<1)+bit;
}
bitRevTable[i]=fnum;
}
}
BitFile::~BitFile()
{
if(buffer) delete [] buffer;
}