mirror of
git://projects.qi-hardware.com/nn-usb-fpga.git
synced 2025-01-10 01:20:16 +02:00
144 lines
2.9 KiB
C++
144 lines
2.9 KiB
C++
|
/* 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;
|
||
|
}
|