parent
ae161b4a6a
commit
d1b70f8018
@ -0,0 +1,65 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
|
||||
Copyright (c) 2001, 2002 by David Sullins
|
||||
Licencia: GPL por bitfile.c
|
||||
|
||||
|
||||
jbit:
|
||||
-----
|
||||
Esta script es un shortcut para programar un dispositivo usando el
|
||||
programa GNU JTAG con un archivo .bit. Genera y borra el SVF intermedio.
|
||||
Se puede usar una configuracion personalizada, leer jbitrc_sample.txt.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
bit2svf$ ./jbit ejemplo_prom.bit XC18V01
|
||||
|
||||
jbit - bit2svf/jtag short cut - v1.0
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna/INTI
|
||||
|
||||
Creando archivo temporario /tmp/bit2svf.tmp
|
||||
|
||||
bit2svf - SVF file generator - v1.0
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna/INTI
|
||||
|
||||
|
||||
Bit file created on 2004/08/25 at 13:43:18.
|
||||
Created from file ejemplo.ncd for Xilinx part 2s100pq208.
|
||||
Bitstream length is 97652 bytes.
|
||||
|
||||
Process finsished sucefully.
|
||||
Creado ok
|
||||
Invocando /home/jpablo/usr/bin/jtag
|
||||
Initializing Xilinx DLC5 JTAG Parallel Cable III on ppdev port /dev/parport0
|
||||
IR length: 8
|
||||
Chain length: 1
|
||||
Device Id: 00000101000000100100000010010011
|
||||
Manufacturer: Xilinx
|
||||
Part: XC18V01-SO20
|
||||
Stepping: 1
|
||||
Filename: /home/jpablo/usr//share/jtag/xilinx/xc18v01-so20/xc18v01-so20
|
||||
Warning svf: checking of TDO not supported for SIR.
|
||||
This message is only displayed once.
|
||||
Borrando temporarios..
|
||||
Que tenga un buen dia :-)
|
||||
|
||||
|
||||
|
||||
bit2svf:
|
||||
--------
|
||||
Este programa sirve para generar un archivo SVF con el cual
|
||||
utilizando el programa JTAG para linux, se puede programar una FPGA o
|
||||
una PROM.
|
||||
|
||||
Ejemplo:
|
||||
|
||||
bit2svf$ ./bit2svf ejemplo_prom.bit ejemplo_prom.svf XC18V01
|
||||
|
||||
Bit file created on 2004/08/25 at 13:43:18.
|
||||
Created from file ejemplo.ncd for Xilinx part 2s100pq208.
|
||||
Bitstream length is 97652 bytes.
|
||||
|
||||
Process finsished sucefully.
|
||||
|
||||
|
||||
|
@ -0,0 +1,41 @@
|
||||
CC=gcc
|
||||
CFLAGS=-Wall -g3 -I$(BIDIR)
|
||||
BIDIR=bitinfo-0.3
|
||||
LDFLAGS=-I$(BIDIR)
|
||||
PROYECTO=dumpbit bit2svf
|
||||
VERSION=1.3.1
|
||||
PKG=bit2svf-$(VERSION)
|
||||
|
||||
all: $(PROYECTO) $(BIDIR)/bitinfo
|
||||
|
||||
$(BIDIR)/bitfile.o:
|
||||
$(MAKE) -C $(BIDIR)
|
||||
|
||||
bit2svf: bit2svf.o $(BIDIR)/bitfile.o parts.o commands.o bitshandle.o
|
||||
|
||||
dumpbit: dumpbit.o $(BIDIR)/bitfile.o
|
||||
|
||||
debian/control: debian/packages debian/yada
|
||||
debian/yada rebuild control
|
||||
|
||||
debian/rules: debian/packages debian/yada
|
||||
debian/yada rebuild rules
|
||||
|
||||
deb: $(PROYECTO) debian/control debian/rules
|
||||
fakeroot dpkg-buildpackage -b -uc
|
||||
|
||||
tarball: clean
|
||||
cp -r ../bit2svf /tmp/$(PKG)
|
||||
-rm -rf /tmp/$(PKG)/CVS /tmp/$(PKG)/*/CVS /tmp/$(PKG)/*/*/CVS /tmp/$(PKG)/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/*/*/CVS /tmp/$(PKG)/*/*/*/*/*/*/CVS 2> /dev/null
|
||||
-rm -f /tmp/$(PKG)/.cvsignore /tmp/$(PKG)/*/.cvsignore /tmp/$(PKG)/*/*/.cvsignore /tmp/$(PKG)/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/*/*/.cvsignore /tmp/$(PKG)/*/*/*/*/*/*/.cvsignore 2> /dev/null
|
||||
-rm -f /tmp/$(PKG)/*.epr /tmp/$(PKG)/.*.dst /tmp/$(PKG)/Changelog /tmp/$(PKG)/lista 2> /dev/null
|
||||
cd /tmp ; tar zcvf $(PKG).tar.gz $(PKG)
|
||||
rm -r /tmp/$(PKG)
|
||||
mv /tmp/$(PKG).tar.gz .
|
||||
|
||||
clean:
|
||||
-rm -f *.o $(PROYECTO) .*~
|
||||
$(MAKE) -C $(BIDIR) clean
|
||||
debian/rules clean
|
||||
|
||||
|
@ -0,0 +1,52 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2001, 2002 by David Sullins [bitinfo code]
|
||||
Copyright (c) 2006 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2006 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
dumpbit:
|
||||
-------
|
||||
Dumpbit its a simple program wich takes a .bit file generated by
|
||||
Xilinx tools and dumps the binary stream in a file.
|
||||
|
||||
bit2svf:
|
||||
-------
|
||||
This program is used for generate a SVF file with the needed
|
||||
sequence for store the contents of a Xilinx .bit file inside some
|
||||
PROM or FPGA.
|
||||
|
||||
Working mode:
|
||||
A template file with instructions for generate the svf file is
|
||||
used. A different template is used for each different algorithm.
|
||||
The format specification can be found in a README file inside
|
||||
the "templates/" dir wich also has two samples.
|
||||
|
||||
bitinfo:
|
||||
-------
|
||||
This program was written by Sullins [davesullins@earthlink.net] and is
|
||||
used for read the header of the Xilinx bit files.
|
||||
Its internally used by bit2svf and dumpbit.
|
||||
The full distribution with its documentation can be found inside the
|
||||
bitinfo-3.0 directory.
|
||||
|
||||
jbit:
|
||||
----
|
||||
This script, using bit2svf, generates a temporal SVF file for the
|
||||
specified device with the specified bit file and then uses the program
|
||||
JTAG for transfering it this file. When finish it erases the temp file.
|
||||
It was created for simplify the process of programming a Xilinx device
|
||||
with GPL tools.
|
||||
|
@ -0,0 +1,55 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2001, 2002 by David Sullins [bitinfo code]
|
||||
Copyright (c) 2006 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2006 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
dumpbit:
|
||||
-------
|
||||
Dumpbit es un simple programa que toma un archivo .bit generado por
|
||||
herramientas de Xilinx y vuelca el contenido del stream binario en
|
||||
un archivo.
|
||||
|
||||
bit2svf:
|
||||
-------
|
||||
|
||||
Este programa se usa para generar un archivo SVF con la secuencia
|
||||
necesaria para grabar el contenido de un archivo .bit de xilinx en
|
||||
algun dispositivo PROM o en la misma FPGA.
|
||||
|
||||
Funcionamiento:
|
||||
Lo que se hace es utilizar un template con instrucciones para
|
||||
generar el archivo svf. Se necesita un template para cada algoritmo
|
||||
diferente que se quiera generar.
|
||||
La explicacion del formato de templates se encunetra en un
|
||||
archivo README en el directorio "templates/" que trae dos ejemplos.
|
||||
|
||||
bitinfo:
|
||||
-------
|
||||
Este es programa escrito por Dave Sullins [davesullins@earthlink.net]
|
||||
sirve para interpretar el header de los archivos bit de xilinx.
|
||||
Es usado internamente por bit2svf y dumpbit.
|
||||
La distribucion completa junto con su documentacion se encuentra en el
|
||||
directorio bitinfo-3.0.
|
||||
|
||||
jbit:
|
||||
----
|
||||
Esta script, utilizando bit2svf, genera un SVF temporal para el
|
||||
dispositivo especificado con el archivo bit y luego utiliza el programa
|
||||
JTAG para transferirle ese archivo. Al terminar borra el temporario.
|
||||
Fue creada para simplificar el proceso de programar un dispositivo Xilinx
|
||||
con un archivo bit con herramientas GPL.
|
||||
|
@ -0,0 +1,3 @@
|
||||
* Reemplazar la lectura de archivo de origen por un plugin para poder
|
||||
leer un MCS en lugar de un .bit o cualquier otro tipo de archivo.
|
||||
|
@ -0,0 +1,297 @@
|
||||
/**[txh]********************************************************************
|
||||
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
Description: Generates a SVF file from a xilinx .bit file.
|
||||
|
||||
***************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Target: Any
|
||||
Language: C
|
||||
Compiler: gcc 3.3.5 (Debian GNU/Linux)
|
||||
Text editor: SETEdit 0.5.5
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <getopt.h>
|
||||
#include "bitfile.h"
|
||||
#include "parts.h"
|
||||
#include "commands.h"
|
||||
#include "global.h"
|
||||
#include "bitshandle.h"
|
||||
|
||||
#define DEFAULT_RES "/usr/share/bit2svf/"
|
||||
|
||||
static char *theBitFile;
|
||||
static char *theSVFFile;
|
||||
static char *thePath=NULL;
|
||||
static char *theDevice;
|
||||
static long skip=-1, limit=-1;
|
||||
|
||||
static
|
||||
struct option longopts[] =
|
||||
{
|
||||
{ "help", 0, 0, 'h' },
|
||||
{ "length", 1, 0, 'l' },
|
||||
{ "path", 1, 0, 'p' },
|
||||
{ "skip", 1, 0, 's' },
|
||||
{ 0, 0, 0, 0 }
|
||||
};
|
||||
|
||||
static
|
||||
void Usage()
|
||||
{
|
||||
#define PrintHelp(a) printf(a)
|
||||
#define FlushHelp() printf("\n"); fflush(stdout)
|
||||
PrintHelp("bit2svf [options] infile.bit outfile.svf DEVICE_NAME\n\n");
|
||||
PrintHelp("Valid options are:\n");
|
||||
PrintHelp("-h, --help displays this text ;-).\n");
|
||||
PrintHelp("-l, --length=LIMIT limit the number of bits.\n");
|
||||
PrintHelp("-p, --path=PATH is the full path to the directory with DEVICES file\n");
|
||||
PrintHelp(" and the templates files to be used.\n");
|
||||
PrintHelp("-s, --skip=OFFSET skip OFFSET bits in the bitstream.\n");
|
||||
FlushHelp();
|
||||
exit(1);
|
||||
}
|
||||
|
||||
static
|
||||
void ParseCommandLine(int argc, char *argv[])
|
||||
{
|
||||
int optc;
|
||||
|
||||
while ((optc=getopt_long(argc,argv,"hl:p:s:",longopts,0))!=EOF)
|
||||
{
|
||||
switch (optc)
|
||||
{
|
||||
case 'l':
|
||||
limit=strtol(optarg,NULL,0);
|
||||
if (limit%8)
|
||||
{
|
||||
fprintf(stderr,"The length must be multiple of 8\n");
|
||||
exit(2);
|
||||
}
|
||||
limit/=8;
|
||||
break;
|
||||
|
||||
case 'p':
|
||||
thePath=optarg;
|
||||
break;
|
||||
|
||||
case 's':
|
||||
skip=strtol(optarg,NULL,0);
|
||||
if (skip%8)
|
||||
{
|
||||
fprintf(stderr,"The skip must be multiple of 8\n");
|
||||
exit(2);
|
||||
}
|
||||
skip/=8;
|
||||
break;
|
||||
|
||||
case 'h':
|
||||
default:
|
||||
Usage();
|
||||
}
|
||||
}
|
||||
if (argc-optind<3)
|
||||
{
|
||||
fprintf(stderr,"Error: Missing arguments\n\n");
|
||||
Usage();
|
||||
}
|
||||
theBitFile=argv[optind];
|
||||
theSVFFile=argv[optind+1];
|
||||
theDevice=argv[optind+2];
|
||||
}
|
||||
|
||||
|
||||
/* main function */
|
||||
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct bithead bh;
|
||||
FILE *bitfile;
|
||||
FILE *cfile;
|
||||
FILE *tplate;
|
||||
char line[1001];
|
||||
part *selected=NULL;
|
||||
char *res_path=NULL;
|
||||
char *devices=NULL;
|
||||
int isBit;
|
||||
|
||||
address=0l;
|
||||
step=0l;
|
||||
s_bytes=0l;
|
||||
s_bits=0l;
|
||||
stream_s=0l;
|
||||
cutlines=1;
|
||||
|
||||
id=NULL;
|
||||
idmask=NULL;
|
||||
bsize=NULL;
|
||||
msize=0l;
|
||||
templ=NULL;
|
||||
|
||||
fprintf(stderr,"\nbit2svf - SVF file generator - v1.3.1\n");
|
||||
fprintf(stderr,"Copyright (c) 2005 Juan Pablo D. Borgna/INTI\n");
|
||||
fprintf(stderr,"Copyright (c) 2006-2007 Salvador E. Tropea/INTI\n\n");
|
||||
|
||||
ParseCommandLine(argc,argv);
|
||||
|
||||
if ((bitfile=fopen(theBitFile,"rb"))==NULL)
|
||||
{
|
||||
perror("BITFILE");
|
||||
return 2;
|
||||
}
|
||||
|
||||
if (!strcmp(theSVFFile,"-"))
|
||||
cfile=stdout;
|
||||
else
|
||||
{
|
||||
if ((cfile=fopen(theSVFFile,"wt"))==NULL)
|
||||
{
|
||||
perror("SVFFILE");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
if (thePath)
|
||||
res_path=thePath;
|
||||
else /* If is not a command line parameter */
|
||||
if (((res_path=getenv("BIT2SVF_RES"))==NULL) || (strlen(res_path)==0))
|
||||
res_path=strdup(DEFAULT_RES); /* if couldnt get it from env, default*/
|
||||
|
||||
//asprintf(&devices,"%s/DEVICES",res_path);
|
||||
devices=(char *)malloc(strlen(res_path)+9);
|
||||
strcpy(devices,res_path);
|
||||
strcat(devices,"/");
|
||||
strcat(devices,"DEVICES");
|
||||
|
||||
if (select_part_from_file(theDevice,devices,&selected)) return 12;
|
||||
|
||||
fprintf(stderr,"Using DEVICES: %s\n",devices);
|
||||
|
||||
id=strdup(selected->id);
|
||||
idmask=strdup(selected->idmask);
|
||||
msize=selected->msize;
|
||||
bsize=selected->bsize;
|
||||
|
||||
//asprintf(&templ,"%s/%s",res_path,selected->alg_tpl);
|
||||
templ=(char *)malloc(strlen(res_path)+strlen(selected->alg_tpl)+6);
|
||||
strcpy(templ,res_path);
|
||||
strcat(templ,"/");
|
||||
strcat(templ,selected->alg_tpl);
|
||||
strcat(templ,".svft");
|
||||
|
||||
if ((tplate=fopen(templ,"rt"))==NULL)
|
||||
{
|
||||
perror("TEMPLATE");
|
||||
return 4;
|
||||
}
|
||||
fprintf(stderr,"Using template: %s\n",templ);
|
||||
|
||||
isBit=1;
|
||||
initbh(&bh);
|
||||
if (readhead(&bh, bitfile))
|
||||
{
|
||||
fprintf(stderr,"\nInvalid .bit file assuming .bin.\n");
|
||||
isBit=0;
|
||||
fseek(bitfile,0,SEEK_END);
|
||||
bh.length=ftell(bitfile);
|
||||
fseek(bitfile,0,SEEK_SET);
|
||||
}
|
||||
else
|
||||
{
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"Bit file created on %s at %s.\n", bh.date, bh.time);
|
||||
fprintf(stderr,"Created from file %s for Xilinx part %s.\n", bh.filename, bh.part);
|
||||
}
|
||||
fprintf(stderr,"Bitstream length is %d bytes.\n", bh.length);
|
||||
if (skip>=0)
|
||||
{
|
||||
if (bh.length<skip)
|
||||
{
|
||||
fprintf(stderr,"The number of bytes to skip is bigger than the current length.\n");
|
||||
return 13;
|
||||
}
|
||||
fseek(bitfile,skip,SEEK_CUR);
|
||||
bh.length-=skip;
|
||||
fprintf(stderr,"Skipping %ld bytes, new length %d.\n",skip,bh.length);
|
||||
}
|
||||
if (limit>=0)
|
||||
{
|
||||
if (bh.length<limit)
|
||||
{
|
||||
fprintf(stderr,"The specified length is bigger than the current length.\n");
|
||||
return 12;
|
||||
}
|
||||
bh.length=limit;
|
||||
fprintf(stderr,"Limiting bitstream length to %d bytes.\n",bh.length);
|
||||
}
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
stream_s=ftell(bitfile);
|
||||
s_bytes=bh.length;
|
||||
s_bits=8*s_bytes;
|
||||
|
||||
fgets(line,1001,tplate);
|
||||
|
||||
while(!feof(tplate))
|
||||
{
|
||||
|
||||
if (!strncasecmp(line,"--",2))
|
||||
{ /* block found */
|
||||
/* LITERAL */
|
||||
if (!strncasecmp(line,"--LITERAL START",15))
|
||||
if(repeat(tplate,cfile,bitfile,0)) return 6;
|
||||
/* end LITERAL */
|
||||
/* REPEAT */
|
||||
if (!strncasecmp(line,"--REPEAT START",14))
|
||||
if (repeat(tplate,cfile,bitfile,-1)) return 7;
|
||||
/* end REPEAT */
|
||||
/* REPEAT UNTIL */
|
||||
if (!strncasecmp(line,"--REPEAT UNTIL",14))
|
||||
if (repeat(tplate,cfile,bitfile,value_from(line+15))) return 8;
|
||||
/* end REPEAT UNTIL */
|
||||
}
|
||||
else if (!strncasecmp(line,"$",1))
|
||||
{
|
||||
int col=0;
|
||||
if(do_command(line,bitfile,cfile,&col)) return 9;
|
||||
}
|
||||
else if (strncasecmp(line,"//",2) && (line[0]!='\n')) /* And if its not a comment or a blank line */
|
||||
{ /* Its a template error */
|
||||
fprintf(stderr,"Invalid line outside block in template: %s\n",line);
|
||||
return 10;
|
||||
}
|
||||
|
||||
fgets(line,1001,tplate);
|
||||
}
|
||||
|
||||
fclose(tplate);
|
||||
fclose(cfile);
|
||||
fclose(bitfile);
|
||||
freebh(&bh);
|
||||
|
||||
fprintf(stderr,"Process finsished sucefully.\n");
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,101 @@
|
||||
05/23/2001
|
||||
|
||||
Bit file header specification
|
||||
|
||||
|
||||
A bit file has two sections. The first section is a variable length header.
|
||||
The second section is a fixed-length bitstream which is downloaded into the
|
||||
FPGA. The format of the bitstream can be found in the data book for the
|
||||
appropriate FPGA, but the format of the header is not anywhere that I have
|
||||
found in the Xilinx literature. This document describes the structure the
|
||||
bit file header for the XC4005XL and XC4005E FPGAs. This structure may or
|
||||
may not be appropriate for headers of bit files for other Xilinx FPGAs.
|
||||
|
||||
Preamble: unknown values
|
||||
|
||||
The bit files generated with xmake for the XC4005XL and XC4005E FPGAs all
|
||||
begin with the following sequence of 13 bytes (shown here in hexadecimal):
|
||||
00 09 0F F0 0F F0 0F F0 0F F0 00 00 01
|
||||
|
||||
Part "a": source file
|
||||
|
||||
Parts a through e follow the same general format. First the part begins
|
||||
with the ASCII letter of the section followed by a NULL (00h). For example,
|
||||
part c begins with hexadecimal 63 00, since 63 is ASCII for "c". The next
|
||||
byte is a length byte, giving the length of the string to follow plus 1.
|
||||
The length is followed by an ASCII string, and that string is followed by a
|
||||
NULL (00h). If there is no string at all in the section, then the length
|
||||
byte is 0 and there is no NULL termination.
|
||||
|
||||
Part a of the header tells the filename used to generate the bit file. For
|
||||
example, if the file "xc4005.ncd" was used to generate the bit file then the
|
||||
header will be:
|
||||
"a" 00 0B "xc4005.ncd" 00
|
||||
|
||||
Convert the quoted letters into their ASCII representation.
|
||||
|
||||
Part "b": part name
|
||||
|
||||
Part b follows the same format as part a. The string identifies the part
|
||||
and package of the target device. In my limited tests this string has
|
||||
always been "4005xlpc84" or "4005epc84".
|
||||
|
||||
Part "c": date
|
||||
|
||||
Part c follows the same format as part a. The string gives the date the bit
|
||||
file was generated, for example "2001/03/12".
|
||||
|
||||
Part "d": time
|
||||
|
||||
Part d follows the same format as part a. The string gives the time the bit
|
||||
file was generated, for example "20:43:04".
|
||||
|
||||
Part "e": unknown
|
||||
|
||||
Part e seems to follow the same format as part a. However, in my tests this
|
||||
part has always been empty. In other words, the entire part is hexadecimal
|
||||
65 00 00.
|
||||
|
||||
Final part: bitstream length
|
||||
|
||||
The final part of the header gives the length of the bitstream to follow, in
|
||||
binary. This is two bytes long for the XC4005XL and XC4005E parts, but it
|
||||
is probable that this length will be more than two bytes long for larger
|
||||
Xilinx parts.
|
||||
|
||||
For example, the XC4005XL part has a 18995 byte long bitstream. The final
|
||||
two bytes of the header are hexadecimal 4A33, which is 18995 when converted
|
||||
to decimal.
|
||||
|
||||
Immediately following the final part of the header, the bitstream begins.
|
||||
The file ends immediately after the bitstream.
|
||||
|
||||
|
||||
05/24/2001
|
||||
UPDATE:
|
||||
|
||||
I examined the bit file headers for two more Xilinx parts, a Spartan part
|
||||
and 1000 gate Virtex part. From this I determined my understanding of the
|
||||
sections was a little off. The section letters FOLLOW the sections. So the
|
||||
unknown garbage at the beginning (which was the same for all parts) is
|
||||
section a, the part name was section b, and so on. The time was section e,
|
||||
and the 00 following the 65 00 was the beginning of the length. So the
|
||||
length is actually three bytes long. This gives a maximum bitstream length
|
||||
of FFFFFFh, or 16,777,215 bytes.
|
||||
|
||||
09/10/2002
|
||||
UPDATE:
|
||||
|
||||
I got an email message from "Stephen from Australia" who set me straight on
|
||||
the format of the bit file header. He pointed me to the online FPGA FAQ,
|
||||
which gives an alternative view of how the header is laid out. Each section
|
||||
letter is a single byte. The 00 which follows the section letter is
|
||||
actually the first byte of a two-byte size. The final four bytes of the
|
||||
header make up a four-byte size. After considering the difference between
|
||||
the two specifications, I realized that even if the FAQ is wrong it wouldn't
|
||||
hurt to parse it that way since the first byte of the length would always be
|
||||
00. And it seems more aesthetically pleasing to have a four-byte bitstream
|
||||
length than a three-byte bitstream length. I have altered bitfile.c to
|
||||
reflect the change in my understanding of the format.
|
||||
|
||||
Thanks for setting me straight, Steve!
|
@ -0,0 +1,6 @@
|
||||
2002-09-10, version 0.2
|
||||
|
||||
Updated the way I parse the bitstream length according to information in the
|
||||
online FPGA FAQ. Special thanks to "Stephen from Australia" for setting me
|
||||
straight. Started using version numbers. If you have an unnumbered
|
||||
version of bitinfo, it is version 0.1 and out of date.
|
@ -0,0 +1,21 @@
|
||||
# Makefile for bitfile routines
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -c -g -Wall
|
||||
LDFLAGS =
|
||||
OBJECTS = bitinfo.o bitfile.o
|
||||
|
||||
|
||||
all: bitinfo
|
||||
|
||||
bitinfo.o: bitinfo.c bitfile.h
|
||||
${CC} ${CFLAGS} bitinfo.c -o bitinfo.o
|
||||
|
||||
bitfile.o: bitfile.c bitfile.h
|
||||
${CC} ${CFLAGS} bitfile.c -o bitfile.o
|
||||
|
||||
bitinfo: bitinfo.o bitfile.o
|
||||
${CC} ${LDFLAGS} ${OBJECTS} -o bitinfo
|
||||
|
||||
clean:
|
||||
rm -f ${OBJECTS} bitinfo
|
@ -0,0 +1,45 @@
|
||||
Bitinfo - Parse a Xilinx bit-file header
|
||||
|
||||
|
||||
Description
|
||||
|
||||
Bitinfo is a simple utility that parses the header of a Xilinx bit file
|
||||
and outputs all the information that can be obtained from that header.
|
||||
This information includes the Xilinx FPGA the bit file was created for,
|
||||
the NCD file the bit file was created from, the creation date and time,
|
||||
and the bitstream length.
|
||||
|
||||
I had to reverse-engineer the file format to figure out how to parse all
|
||||
of this information. So that someone else doesn't have to repeat my work,
|
||||
I have included my reverse-engineering notes with the source code.
|
||||
|
||||
You may find this program useful if, like me, you often end up with
|
||||
several bit files lying around, all called "xc4005.bit," and you can't
|
||||
remember which one is the one you need. The header should at least give
|
||||
you some clues about the file's contents. Another use for this program is
|
||||
to prove to a student that the bit file they have brought to lab with them
|
||||
is not the one from this week's experiment, since the timestamp is from
|
||||
three weeks ago.
|
||||
|
||||
|
||||
Compiling and using bitinfo
|
||||
|
||||
You can download the bitinfo source for free from
|
||||
http://members.naspa.net/djs/software/bitinfo.tar.gz. It is released under
|
||||
the GNU Public License. See the COPYING file for more details.
|
||||
|
||||
To compile bitinfo, first edit the Makefile if necessary. If you don't
|
||||
have gcc installed, you will need to change the first line from "CC=gcc"
|
||||
to "CC=cc" or whatever your C compiler is called. After editing the
|
||||
Makefile, type "make" and you're done. Although bitinfo was written for
|
||||
Unix, it has also been successfully compiled for Windows NT 4.0 using MS
|
||||
Visual C++.
|
||||
|
||||
To run bitinfo, just type "bitinfo < file.bit". You will probably want to
|
||||
put bitinfo in some bin directory for convenience.
|
||||
|
||||
|
||||
Bugs
|
||||
|
||||
Please report any bugs by emailing me at djs@naspa.net.
|
||||
|
@ -0,0 +1,233 @@
|
||||
/* bitfile.c
|
||||
*
|
||||
* Library routines for dealing with bit files, version 0.2
|
||||
*
|
||||
* Copyright 2001, 2002 by David Sullins
|
||||
*
|
||||
* This file is part of Bitinfo.
|
||||
*
|
||||
* Bitinfo 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, version 2 of the License.
|
||||
*
|
||||
* Bitinfo 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
|
||||
* Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* You may contact the author at djs@naspa.net.
|
||||
*/
|
||||
|
||||
#include <string.h>
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitfile.h"
|
||||
|
||||
#ifndef uchar
|
||||
#define uchar unsigned char
|
||||
#endif
|
||||
|
||||
/* first 13 bytes of a bit file */
|
||||
static uchar head13[] = {0, 9, 15, 240, 15, 240, 15, 240, 15, 240, 0, 0, 1};
|
||||
|
||||
/* initbh
|
||||
*
|
||||
* Initialize the bithead struct
|
||||
*/
|
||||
void initbh(struct bithead *bh)
|
||||
{
|
||||
bh->filename = NULL;
|
||||
bh->part = NULL;
|
||||
bh->date = NULL;
|
||||
bh->time = NULL;
|
||||
bh->length = 0;
|
||||
}
|
||||
|
||||
/* freebh
|
||||
*
|
||||
* Free up memory allocated for a bithead struct.
|
||||
*/
|
||||
void freebh(struct bithead *bh)
|
||||
{
|
||||
free(bh->filename);
|
||||
free(bh->part);
|
||||
free(bh->date);
|
||||
free(bh->time);
|
||||
initbh(bh);
|
||||
}
|
||||
|
||||
/* readhead
|
||||
*
|
||||
* Read the entire bit file header. The file pointer will be advanced to
|
||||
* point to the beginning of the bitstream, and the bitfile header struct
|
||||
* will be filled with the appropriate data.
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readhead(struct bithead *bh, FILE *f)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* get first 13 bytes */
|
||||
t = readhead13(f);
|
||||
if (t) return t;
|
||||
|
||||
/* get filename */
|
||||
t = readsecthead(NULL, f);
|
||||
if (-1 == t) return -1;
|
||||
bh->filename = malloc(t);
|
||||
t = readsection(bh->filename, t, f);
|
||||
|
||||
/* get part name */
|
||||
t = readsecthead(NULL, f);
|
||||
if (-1 == t) return -1;
|
||||
bh->part = malloc(t);
|
||||
t = readsection(bh->part, t, f);
|
||||
|
||||
/* get file creation date */
|
||||
t = readsecthead(NULL, f);
|
||||
if (-1 == t) return -1;
|
||||
bh->date = malloc(t);
|
||||
t = readsection(bh->date, t, f);
|
||||
|
||||
/* get file creation time */
|
||||
t = readsecthead(NULL, f);
|
||||
if (-1 == t) return -1;
|
||||
bh->time = malloc(t);
|
||||
t = readsection(bh->time, t, f);
|
||||
|
||||
/* get bitstream length */
|
||||
t = readlength(f);
|
||||
if (-1 == t) return -1;
|
||||
bh->length = t;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* readhead13
|
||||
*
|
||||
* Read the first 13 bytes of the bit file. Discards the 13 bytes but
|
||||
* verifies that they are correct.
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readhead13 (FILE *f)
|
||||
{
|
||||
int t;
|
||||
uchar buf[13];
|
||||
|
||||
/* read header */
|
||||
t = fread(buf, 1, 13, f);
|
||||
if (t != 13)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* verify header is correct */
|
||||
t = memcmp(buf, head13, 13);
|
||||
if (t)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* readsecthead
|
||||
*
|
||||
* Read the header of a bit file section. The section letter is placed in
|
||||
* section buffer "buf" and the length of the following section is
|
||||
* returned. If buf is NULL, the section letter is discarded.
|
||||
*
|
||||
* Return -1 if an error occurs, length of section otherwise.
|
||||
*/
|
||||
int readsecthead(char *buf, FILE *f)
|
||||
{
|
||||
int t;
|
||||
char tbuf = 0;
|
||||
char lenbuf[2];
|
||||
|
||||
/* if buf is NULL, use tbuf instead */
|
||||
if (NULL == buf)
|
||||
{
|
||||
buf = &tbuf;
|
||||
}
|
||||
|
||||
/* get section letter */
|
||||
t = fread(buf, 1, 1, f);
|
||||
if (t != 1)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* read length */
|
||||
t = fread(lenbuf, 1, 2, f);
|
||||
if (t != 2)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert 2-byte length to an int */
|
||||
return (((int)lenbuf[0]) <<8) | lenbuf[1];
|
||||
}
|
||||
|
||||
|
||||
/* readsection
|
||||
*
|
||||
* Read a section of a bit file. The section contents are placed
|
||||
* in the contents buffer "buf."
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readsection(char *buf, int length, FILE *f)
|
||||
{
|
||||
int t;
|
||||
|
||||
/* get section data */
|
||||
t = fread(buf, 1, length, f);
|
||||
if ((t != length) || (buf[length-1] != 0))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
/* readlength
|
||||
*
|
||||
* Read in the bitstream length. The section letter "e" is discarded
|
||||
* and the length is returned.
|
||||
*
|
||||
* Return -1 if an error occurs, length otherwise.
|
||||
*/
|
||||
int readlength(FILE *f)
|
||||
{
|
||||
char s = 0;
|
||||
uchar buf[4];
|
||||
int length;
|
||||
int t;
|
||||
|
||||
/* get section, make sure it's "e" */
|
||||
t = fread(&s, 1, 1, f);
|
||||
if ((t != 1) || (s != 'e'))
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* get length */
|
||||
t = fread(buf, 1, 4, f);
|
||||
if (t != 4)
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
/* convert 4-byte length to an int */
|
||||
length = (((int)buf[0]) <<24) | (((int)buf[1]) <<16)
|
||||
| (((int)buf[2]) <<8) | buf[3];
|
||||
|
||||
return length;
|
||||
}
|
@ -0,0 +1,99 @@
|
||||
/* bitfile.h
|
||||
*
|
||||
* Library routines for dealing with bit files, version 0.2
|
||||
*
|
||||
* Copyright 2001, 2002 by David Sullins
|
||||
*
|
||||
* This file is part of Bitinfo.
|
||||
*
|
||||
* Bitinfo 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, version 2 of the License.
|
||||
*
|
||||
* Bitinfo 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
|
||||
* Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* You may contact the author at djs@naspa.net.
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
|
||||
/* struct bithead
|
||||
*
|
||||
* Stores the information obtained from the bitfile header. Use initbh to
|
||||
* initialize the struct, and freebh to free memory allocated for the struct.
|
||||
*/
|
||||
struct bithead
|
||||
{
|
||||
char* filename;
|
||||
char* part;
|
||||
char* date;
|
||||
char* time;
|
||||
int length;
|
||||
};
|
||||
|
||||
/* initbh
|
||||
*
|
||||
* Initialize the bithead struct
|
||||
*/
|
||||
void initbh(struct bithead *bh);
|
||||
|
||||
/* freebh
|
||||
*
|
||||
* Free up memory allocated for a bithead struct.
|
||||
*/
|
||||
void freebh(struct bithead *bh);
|
||||
|
||||
/* readhead
|
||||
*
|
||||
* Read the entire bit file header. The file pointer will be advanced to
|
||||
* point to the beginning of the bitstream, and the bitfile header struct
|
||||
* will be filled with the appropriate data.
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readhead(struct bithead *bh, FILE *f);
|
||||
|
||||
/* readhead13
|
||||
*
|
||||
* Read the first 13 bytes of the bit file. Discards the 13 bytes but
|
||||
* verifies that they are correct.
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readhead13 (FILE *f);
|
||||
|
||||
/* readsecthead
|
||||
*
|
||||
* Read the header of a bit file section. The section letter is placed in
|
||||
* section buffer "buf" and the length of the following section is
|
||||
* returned. If buf is NULL, the section letter is discarded.
|
||||
*
|
||||
* Return -1 if an error occurs, length of section otherwise.
|
||||
*/
|
||||
int readsecthead(char *buf, FILE *f);
|
||||
|
||||
/* readsection
|
||||
*
|
||||
* Read a section of a bit file. The section contents are placed
|
||||
* in the contents buffer "buf."
|
||||
*
|
||||
* Return -1 if an error occurs, 0 otherwise.
|
||||
*/
|
||||
int readsection(char *buf, int length, FILE *f);
|
||||
|
||||
/* readlength
|
||||
*
|
||||
* Read in the bitstream length. The section letter "e" is discarded
|
||||
* and the length is returned.
|
||||
*
|
||||
* Return -1 if an error occurs, length otherwise.
|
||||
*/
|
||||
int readlength(FILE *f);
|
||||
|
@ -0,0 +1,57 @@
|
||||
/* bitinfo.c
|
||||
*
|
||||
* Main function to parse Xilinx bit file header, version 0.2.
|
||||
*
|
||||
* Copyright 2001, 2002 by David Sullins
|
||||
*
|
||||
* This file is part of Bitinfo.
|
||||
*
|
||||
* Bitinfo 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, version 2 of the License.
|
||||
*
|
||||
* Bitinfo 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
|
||||
* Bitinfo; if not, write to the Free Software Foundation, Inc., 59 Temple
|
||||
* Place, Suite 330, Boston, MA 02111-1307 USA
|
||||
*
|
||||
* You may contact the author at djs@naspa.net.
|
||||
*/
|
||||
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitfile.h"
|
||||
|
||||
/* read a bit file from stdin */
|
||||
int main(void)
|
||||
{
|
||||
int t;
|
||||
struct bithead bh;
|
||||
|
||||
initbh(&bh);
|
||||
|
||||
/* read header */
|
||||
t = readhead(&bh, stdin);
|
||||
if (t)
|
||||
{
|
||||
printf("Invalid bit file header.\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* output header info */
|
||||
printf("\n");
|
||||
printf("Bit file created on %s at %s.\n", bh.date, bh.time);
|
||||
printf("Created from file %s for Xilinx part %s.\n", bh.filename,
|
||||
bh.part);
|
||||
printf("Bitstream length is %d bytes.\n", bh.length);
|
||||
printf("\n");
|
||||
|
||||
freebh(&bh);
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,144 @@
|
||||
/**[txh]********************************************************************
|
||||
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
Description: Low level functions to output hexadecimal bitstreams.
|
||||
|
||||
***************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Target: Any
|
||||
Language: C
|
||||
Compiler: gcc 3.3.5 (Debian GNU/Linux)
|
||||
Text editor: SETEdit 0.5.5
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "global.h"
|
||||
#include "bitshandle.h"
|
||||
|
||||
/* This function returns the inverted bits of its argument */
|
||||
unsigned char
|
||||
inv_byte(unsigned char b)
|
||||
{
|
||||
int i;
|
||||
unsigned char t=0;
|
||||
|
||||
for (i=0;i<7;i++)
|
||||
{
|
||||
t|= (b & 0x01);
|
||||
t = t << 1;
|
||||
b = b >> 1;
|
||||
}
|
||||
t|=b & 0x01;
|
||||
return t;
|
||||
}
|
||||
|
||||
/* This function is used to generate a string with the hex value of the
|
||||
inverted bits of from */
|
||||
void
|
||||
pbi(char *to, char *from,long nbytes)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char t[]="ZZ";
|
||||
|
||||
if (to==NULL) return;
|
||||
|
||||
j=nbytes*2;
|
||||
|
||||
for (i=0;i<nbytes;i++)
|
||||
{
|
||||
sprintf(t,"%02x",inv_byte(from[i]));
|
||||
j-=2;
|
||||
to[j]=t[0];
|
||||
to[j+1]=t[1];
|
||||
}
|
||||
}
|
||||
|
||||
/* This function is used to generate a string with the hex value of the
|
||||
bits of from */
|
||||
void
|
||||
pb(char *to, char *from,long nbytes)
|
||||
{
|
||||
int i;
|
||||
int j;
|
||||
char t[]="ZZ";
|
||||
|
||||
if (to==NULL) return;
|
||||
|
||||
j=0;
|
||||
|
||||
for (i=0;i<nbytes;i++)
|
||||
{
|
||||
sprintf(t,"%02x",from[i]);
|
||||
j+=2;
|
||||
to[j]=t[0];
|
||||
to[j+1]=t[1];
|
||||
}
|
||||
}
|
||||
|
||||
/*this function writes bytes to a file with a max nuber of
|
||||
chars per line */ /* it should not be here */
|
||||
int
|
||||
cutputs(char *string, FILE *fp, long block, int *col)
|
||||
{
|
||||
long remaining;
|
||||
long wrote=0l;
|
||||
int c=*col;
|
||||
|
||||
remaining=strlen(string);
|
||||
if (!cutlines)
|
||||
{
|
||||
fwrite(string,1,remaining,fp);
|
||||
col+=remaining;
|
||||
return 0;
|
||||
}
|
||||
if (remaining<block)
|
||||
block=remaining;
|
||||
|
||||
while (remaining)
|
||||
{
|
||||
long to_write=block-c;
|
||||
if (to_write<0) to_write=0;
|
||||
if (to_write & 1) to_write++;
|
||||
wrote=fwrite(string,1,to_write,fp);
|
||||
if (wrote!=to_write)
|
||||
{
|
||||
perror("CUTPUTS");
|
||||
return 1;
|
||||
}
|
||||
c+=wrote;
|
||||
string+=wrote;
|
||||
remaining-=wrote;
|
||||
if (remaining)
|
||||
{
|
||||
fputs("\n",fp);
|
||||
c=0;
|
||||
if (remaining<block)
|
||||
block=remaining;
|
||||
}
|
||||
}
|
||||
*col=c;
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
unsigned char inv_byte(unsigned char b);
|
||||
void pbi(char *to, char *from,long nbytes);
|
||||
void pb(char *to, char *from,long nbytes);
|
||||
int cutputs(char *string, FILE *fp, long block, int *col);
|
||||
|
@ -0,0 +1,556 @@
|
||||
/**[txh]********************************************************************
|
||||
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
Description: Commands parser and executor.
|
||||
|
||||
***************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Target: Any
|
||||
Language: C
|
||||
Compiler: gcc 3.3.5 (Debian GNU/Linux)
|
||||
Text editor: SETEdit 0.5.5
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include "global.h"
|
||||
#include "commands.h"
|
||||
#include "bitshandle.h"
|
||||
|
||||
#define MAX_WIDTH 246
|
||||
|
||||
long
|
||||
value_from(char *varname)
|
||||
{
|
||||
if (!strncasecmp("BSIZEB2",varname,7))
|
||||
return strtol(bsize,NULL,0)/4;
|
||||
if (!strncasecmp("BSIZEB",varname,6))
|
||||
return strtol(bsize,NULL,0)/8;
|
||||
if (!strncasecmp("BSIZE",varname,5))
|
||||
return strtol(bsize,NULL,0);
|
||||
if (!strncasecmp("MSIZE",varname,5))
|
||||
return msize;
|
||||
return strtol(varname,NULL,0);
|
||||
}
|
||||
|
||||
void
|
||||
fill(FILE *fp, long c, long t, int *col)
|
||||
{
|
||||
char b[4]="ZZ";
|
||||
sprintf(b,"%02x",(unsigned int)c);
|
||||
int co=*col;
|
||||
|
||||
for (;t>0;t--)
|
||||
{
|
||||
co+=fprintf(fp,"%s",b);
|
||||
if (co>=MAX_WIDTH)
|
||||
{
|
||||
co=0;
|
||||
fprintf(fp,"\n");
|
||||
}
|
||||
}
|
||||
*col=co;
|
||||
}
|
||||
|
||||
/* This function executes a $COMMAND$ */
|
||||
int
|
||||
do_command(char *cmd, FILE *dfp, FILE *ofp, int *col)
|
||||
{
|
||||
char *temp;
|
||||
char *dbuffer;
|
||||
long nbytes=0l;
|
||||
long readed=0l;
|
||||
long value=0l;
|
||||
long times=0l;
|
||||
int padded=0;
|
||||
char *args_pos_s=NULL;
|
||||
char *args_pos_e=NULL;
|
||||
char *separator=NULL;
|
||||
char args[100]; /* I dont think i need more than 100 bytes for
|
||||
passing args... */
|
||||
|
||||
/* DATA and DATA_INV command */
|
||||
|
||||
if (strstr(cmd,"DATA"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if( !args_pos_s || !args_pos_e)
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $DATA_INV(ndatabytes)$\n");
|
||||
return 1;
|
||||
}
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te command */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
if ((nbytes=value_from(args))==0) /* Bad specification of number of bytes */
|
||||
{
|
||||
fprintf(stderr,"Bad specification of ndatabytes in $DATA_INV(ndatabytes)$\n");
|
||||
return 2;
|
||||
}
|
||||
if ((nbytes=value_from(args))==-1) /* Want to process the whole stream */
|
||||
{
|
||||
nbytes=s_bytes;
|
||||
}
|
||||
if ((temp=(char *)malloc(nbytes*2+1))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot asign %li bytes in memory needed for $DATA_INV(ndatabytes)$\n",nbytes*2+1);
|
||||
return 3;
|
||||
}
|
||||
if ((dbuffer=(char *)malloc(nbytes))==NULL)
|
||||
{
|
||||
free(temp);
|
||||
fprintf(stderr,"Cannot asign %li bytes in memory needed for $DATA_INV(ndatabytes)$\n",nbytes);
|
||||
return 3;
|
||||
}
|
||||
if ((readed=fread(dbuffer,1,nbytes,dfp))!=nbytes)
|
||||
{
|
||||
if (padded)
|
||||
{
|
||||
free(dbuffer);
|
||||
free(temp);
|
||||
fprintf(stderr,"Cannot read %li databytes for $DATA_INV(ndatabytes)$ from bitfile\n",nbytes);
|
||||
return 3;
|
||||
}
|
||||
padded=1;
|
||||
memset(dbuffer+readed,0xff,nbytes-readed);
|
||||
}
|
||||
|
||||
if (strstr(cmd,"DATA_INV"))
|
||||
pbi(temp,dbuffer,nbytes); /* Want to inver the bits*/
|
||||
else
|
||||
pb(temp,dbuffer,nbytes); /* Want to use the bits*/
|
||||
|
||||
|
||||
temp[nbytes*2]='\0';
|
||||
|
||||
if (cutputs(temp,ofp,MAX_WIDTH,col))
|
||||
{
|
||||
fprintf(stderr,"Could not write $DATA to file.\n");
|
||||
return 4;
|
||||
}
|
||||
|
||||
|
||||
free(temp);
|
||||
free(dbuffer);
|
||||
return 0;
|
||||
}
|
||||
/* end DATA and DATA_INV command */
|
||||
|
||||
/* ADDRESS command */
|
||||
if (strstr(cmd,"ADDRESS"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $ADDRESS(DIR)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
if (msize<=0x10000)
|
||||
*col+=fprintf(ofp,"%04x",(unsigned int)address);
|
||||
else
|
||||
*col+=fprintf(ofp,"%06x",(unsigned int)address);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
address=value;
|
||||
return 0;
|
||||
}
|
||||
/* end ADDRESS command */
|
||||
|
||||
/* SET: CUTLINES command */
|
||||
if (strstr(cmd,"CUTLINES"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $CUTLINES(ON)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%04x",(unsigned int)cutlines);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
cutlines=value;
|
||||
return 0;
|
||||
}
|
||||
/* end CUTLINES command */
|
||||
|
||||
/* STEP command */
|
||||
if (strstr(cmd,"STEP"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $STEP(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%04x",(unsigned int)step);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
step=value;
|
||||
return 0;
|
||||
}
|
||||
/* end STEP command */
|
||||
|
||||
/* REWIND command */
|
||||
if (strstr(cmd,"REWIND"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if(args_pos_s || args_pos_e )
|
||||
{
|
||||
fprintf(stderr,"No arguments needed by $REWIND$\n");
|
||||
return 1;
|
||||
}
|
||||
fseek(dfp,stream_s,0);
|
||||
return 0;
|
||||
}
|
||||
/* end REWIND command */
|
||||
|
||||
/* SBITS command */
|
||||
if (strstr(cmd,"SBITS"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $SBITS(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%d",(unsigned int)s_bits);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
s_bits=value;
|
||||
return 0;
|
||||
}
|
||||
/* end SBITS command */
|
||||
|
||||
/* SBYTES command */
|
||||
if (strstr(cmd,"SBYTES"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $SBYTES(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%d",(unsigned int)s_bytes);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy the argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
s_bytes=value;
|
||||
return 0;
|
||||
}
|
||||
/* end SBYTES command */
|
||||
|
||||
/* FILL command */
|
||||
if (strstr(cmd,"FILL"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
separator=strchr(cmd,',');
|
||||
if(!args_pos_s || !args_pos_e || !separator)
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $FILL(VAL,TIMES)$\n");
|
||||
return 1;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,4); /* Copy the character */
|
||||
args[4]='\0'; /* Put the null terminator */
|
||||
value=value_from(args);
|
||||
memcpy(args,separator+1,(size_t)(args_pos_e-separator)); /* Copy the times */
|
||||
times=value_from(args);
|
||||
if(times==-1) times=s_bytes;
|
||||
fill(ofp,value,times,col);
|
||||
return 0;
|
||||
}
|
||||
/* end FILL command */
|
||||
|
||||
/* IDMASK command */
|
||||
if (strstr(cmd,"IDMASK"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $IDMASK(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%s",idmask);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
if (id) free(id);
|
||||
if((id=(char *)malloc(strlen(args)))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot asign memory needed for $IDMASK$\n");
|
||||
return 3;
|
||||
}
|
||||
strcpy(id,args);
|
||||
return 0;
|
||||
}
|
||||
/* end IDMASK command */
|
||||
|
||||
|
||||
/* ID command */
|
||||
if (strstr(cmd,"ID"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $ID(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%s",id);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
if (id) free(id);
|
||||
if((id=(char *)malloc(strlen(args)))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot asign memory needed for $ID$\n");
|
||||
return 3;
|
||||
}
|
||||
strcpy(id,args);
|
||||
return 0;
|
||||
}
|
||||
/* end ID command */
|
||||
|
||||
/* BSIZE2 command */
|
||||
if (strstr(cmd,"BSIZE2"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if (args_pos_s || args_pos_e)
|
||||
{
|
||||
fprintf(stderr,"$BSIZE2$ is read only\n");
|
||||
return 1;
|
||||
}
|
||||
*col+=fprintf(ofp,"%ld",strtol(bsize,NULL,0)*2);
|
||||
return 0;
|
||||
}
|
||||
/* end BSIZE2 command */
|
||||
|
||||
/* BSIZE command */
|
||||
if (strstr(cmd,"BSIZE"))
|
||||
{
|
||||
/* get the args inside the () */
|
||||
args_pos_s=strchr(cmd,'(');
|
||||
args_pos_e=strchr(cmd,')');
|
||||
if((!args_pos_s && args_pos_e )|| (!args_pos_e && args_pos_s))
|
||||
{
|
||||
fprintf(stderr,"Bad argument specification in $BSIZE(VAL)$\n");
|
||||
return 1;
|
||||
}
|
||||
if (!args_pos_s && !args_pos_e)
|
||||
{ /* Want to use the value */
|
||||
*col+=fprintf(ofp,"%s",bsize);
|
||||
return 0;
|
||||
}
|
||||
/* Want to SET the value */
|
||||
memcpy(args,args_pos_s+1,(size_t)(args_pos_e-args_pos_s)); /* Copy te argument */
|
||||
args[args_pos_e-args_pos_s-1]='\0'; /* Put the null terminator */
|
||||
if (id) free(id);
|
||||
if((id=(char *)malloc(strlen(args)))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot asign memory needed for $BSIZE$\n");
|
||||
return 3;
|
||||
}
|
||||
strcpy(bsize,args);
|
||||
return 0;
|
||||
}
|
||||
/* end BSIZE command */
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit)
|
||||
{
|
||||
char line[2001];
|
||||
char *cmd_pos_s=NULL;
|
||||
char *cmd_pos_e=NULL;
|
||||
char cmd[30];
|
||||
long entry_point;
|
||||
long end_address=limit; /*+step; SET: Why?*/
|
||||
|
||||
/* Sanity check */
|
||||
if (limit>0 && address>=end_address)
|
||||
{
|
||||
/* SET: Not an error, the PROMs have some "fillers", when we use the full
|
||||
memory the fillers must be skipped */
|
||||
fprintf(stderr,"WARNING: REPEAT UNTIL 0x%lX but current address is 0x%lX\n",
|
||||
limit,address);
|
||||
if (fgets(line,2001,ifp)==NULL) return 1;
|
||||
do
|
||||
{
|
||||
if (!strncasecmp(line,"--END",5))
|
||||
break;
|
||||
if (fgets(line,2001,ifp)==NULL) return 1; /* get a new line to parse */
|
||||
}
|
||||
while(1);
|
||||
return 0;
|
||||
}
|
||||
|
||||
entry_point=ftell(ifp);
|
||||
|
||||
if (fgets(line,2001,ifp)==NULL) return 1;
|
||||
|
||||
do
|
||||
{
|
||||
int col=0;
|
||||
cmd_pos_e=NULL; /* Ending position of command, also used as flag for a command found or not */
|
||||
|
||||
if (!strncasecmp(line,"--END",5))
|
||||
{
|
||||
address+=step;
|
||||
/* Repeat condition */
|
||||
/* SET: XCF02S can produce address>end_address */
|
||||
if ( (limit==0) || ((limit <0) && feof(dfp)) || ((limit >0) && (address>=end_address)))
|
||||
break;
|
||||
if (ftell(dfp)-stream_s>=s_bytes)
|
||||
{
|
||||
fprintf(stderr,"INFO: Bitstream limit reached\n");
|
||||
//fprintf(stderr,"limit: %ld address %ld end_address %ld\n",limit,address,end_address);
|
||||
break;
|
||||
}
|
||||
/*Sanity check*/
|
||||
if ( (0 < limit) && (end_address < address))
|
||||
{
|
||||
fprintf(stderr,"ERROR: REPEAT UNTIL 0x%lX but current address is 0x%lX (2)\n",limit,address);
|
||||
return 24;
|
||||
}
|
||||
fseek(ifp,entry_point,0);
|
||||
if (fgets(line,2001,ifp)==NULL)
|
||||
return 1; /* get a new line to parse */
|
||||
continue;
|
||||
}
|
||||
|
||||
while((cmd_pos_s=strchr(line,'$'))) /* $ character found in line */
|
||||
{
|
||||
|
||||
if (cmd_pos_e)
|
||||
{ /* There was another command on this line before */
|
||||
/* Write intermedia bytes */
|
||||
int size=cmd_pos_s-cmd_pos_e-1;
|
||||
if (fwrite(cmd_pos_e+1,1,size,ofp)!=cmd_pos_s-cmd_pos_e-1)
|
||||
{
|
||||
fprintf(stderr,"There was an error writing to svf file.\n");
|
||||
return 2;
|
||||
}
|
||||
col+=size;
|
||||
}
|
||||
else
|
||||
{ /* write from begining of line to the starting $ char to output file */
|
||||
size_t size=cmd_pos_s-line;
|
||||
if (fwrite(line,1,size,ofp)!=(size_t)(cmd_pos_s-line))
|
||||
{
|
||||
fprintf(stderr,"There was an error writing to svf file.\n");
|
||||
return 2;
|
||||
}
|
||||
col+=size;
|
||||
}
|
||||
|
||||
/* clear the starting '$' simbol so i can search the next */
|
||||
*cmd_pos_s='_';
|
||||
if ((cmd_pos_e=strchr(line,'$'))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Parse error: Cant find ending '$' while parsing command.\n");
|
||||
return 3;
|
||||
}
|
||||
*cmd_pos_e='_'; /* clear the ending '$' simbol so i can search the next */
|
||||
memcpy(cmd,cmd_pos_s+1,(size_t)(cmd_pos_e-cmd_pos_s-1)); /* Copy the command */
|
||||
cmd[cmd_pos_e-cmd_pos_s-1]='\0'; /* Put the null terminator */
|
||||
if (do_command(cmd,dfp,ofp,&col))
|
||||
return 3;
|
||||
}
|
||||
/* No more commands */
|
||||
if (cmd_pos_e)
|
||||
{
|
||||
if (fputs(cmd_pos_e+1,ofp)==EOF) return 2; /* Write remainig bytes */
|
||||
}
|
||||
else
|
||||
{
|
||||
/* There was no command */
|
||||
if (fputs(line,ofp)==EOF) return 2; /* Write all the line */
|
||||
}
|
||||
|
||||
if (fgets(line,2001,ifp)==NULL) return 1; /* get a new line to parse */
|
||||
}
|
||||
while (1);
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,5 @@
|
||||
long value_from(char *varname);
|
||||
void fill(FILE *fp, long c, long t, int *col);
|
||||
int do_command(char *cmd, FILE *dfp, FILE *ofp, int *col);
|
||||
int repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit);
|
||||
|
@ -0,0 +1,76 @@
|
||||
bit2svf (1.3.1-1) stable; urgency=low
|
||||
|
||||
* Agregado: XCF08P y XC4VLX25.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Fri, 21 Dec 2007 12:10:31 -0300
|
||||
|
||||
bit2svf (1.3.0-1) stable; urgency=low
|
||||
|
||||
* Agregado: Soporte para memorias en cascada.
|
||||
* Agregado: XCF01S y XCF04S.
|
||||
* Corregido: Temporal no borrado si se definía TEMP.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Fri, 23 Mar 2007 15:35:29 -0300
|
||||
|
||||
bit2svf (1.2.2-1) stable; urgency=low
|
||||
|
||||
* Corregido: mktemp incluye un retorno de carro y eso molesta a
|
||||
algunos shells.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Thu, 15 Feb 2007 16:28:13 -0300
|
||||
|
||||
bit2svf (1.2.1-1) stable; urgency=low
|
||||
|
||||
* Corregido: creación de archivos temporarios.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Tue, 13 Feb 2007 08:52:40 -0300
|
||||
|
||||
bit2svf (1.2.0-2) stable; urgency=low
|
||||
|
||||
* Nuevo jbit.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Mon, 18 Dec 2006 15:53:04 -0300
|
||||
|
||||
bit2svf (1.2.0-1) stable; urgency=low
|
||||
|
||||
* Nueva versión de los templates que usan el algoritmo del Impact 8.2.x.
|
||||
* Agregado soporte para PROMs XCF02S y Spartan 3.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Thu, 2 Nov 2006 09:39:04 -0300
|
||||
|
||||
bit2svf (1.1.0-1) stable; urgency=low
|
||||
|
||||
* Nueva versión que usa templates de algoritmos.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Mon, 20 Mar 2006 14:46:08 -0300
|
||||
|
||||
bit2svf (1.0.0-5) stable; urgency=low
|
||||
|
||||
* Agregado documentación inglés.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Fri, 30 Sep 2005 11:23:08 -0300
|
||||
|
||||
bit2svf (1.0.0-4) stable; urgency=low
|
||||
|
||||
* Agregado ~/.jbitrc
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Wed, 18 May 2005 13:31:18 -0300
|
||||
|
||||
bit2svf (1.0.0-3) stable; urgency=low
|
||||
|
||||
* Agregados al jbit.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Fri, 22 Apr 2005 16:51:06 -0300
|
||||
|
||||
bit2svf (1.0.0-2) stable; urgency=low
|
||||
|
||||
* Agregado el script jbit.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Mon, 18 Apr 2005 16:51:06 -0300
|
||||
|
||||
bit2svf (1.0.0-1) stable; urgency=low
|
||||
|
||||
* Initial Debian version.
|
||||
|
||||
-- Salvador E. Tropea <set@ieee.org> Tue, 15 Apr 2005 16:32:37 -0300
|
||||
|
@ -0,0 +1,12 @@
|
||||
Source: bit2svf
|
||||
Maintainer: SET <set@ieee.org>
|
||||
Section: contrib/electronics
|
||||
Priority: optional
|
||||
Standards-Version: 3.5
|
||||
|
||||
Package: bit2svf
|
||||
Architecture: i386
|
||||
Depends: jtag
|
||||
Description: Conversor de .BIT a SVF
|
||||
Este programa sirve para generar un archivo SVF con el cual utilizando
|
||||
el programa JTAG para linux, se puede programar una FPGA o una PROM.
|
@ -0,0 +1,40 @@
|
||||
# debian/packages for bit2svf
|
||||
# Written by Charles Briscoe-Smith, May 1999. Public Domain.
|
||||
# Customised for bit2svf by Salvador E. Tropea
|
||||
|
||||
Source: bit2svf
|
||||
Section: contrib/electronics
|
||||
Priority: optional
|
||||
Maintainer: SET <set@ieee.org>
|
||||
Packager: SET <set@ieee.org>
|
||||
Standards-Version: 3.5
|
||||
Description: Conversor de .BIT a SVF
|
||||
Packaged-For: INTI
|
||||
Copyright: GPL
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
|
||||
Copyright (c) 2001, 2002 by David Sullins
|
||||
Major-Changes:
|
||||
Creado.
|
||||
Build: sh
|
||||
echo "Hecho!"
|
||||
Clean: sh
|
||||
echo "Nada para borrar!"
|
||||
|
||||
Package: bit2svf
|
||||
Depends: jtag
|
||||
Architecture: i386
|
||||
Description: Conversor de .BIT a SVF
|
||||
Este programa sirve para generar un archivo SVF con el cual utilizando
|
||||
el programa JTAG para linux, se puede programar una FPGA o una PROM.
|
||||
Install: sh
|
||||
yada install -bin bit2svf
|
||||
yada install -bin dumpbit
|
||||
yada install -bin -unstripped jbit
|
||||
yada install -into /usr/share/bit2svf/ templates/*.svft
|
||||
yada install -into /usr/share/bit2svf/ templates/DEVICES
|
||||
yada install -doc README.es
|
||||
yada install -doc README.en
|
||||
yada install -doc -subdir templates templates/README.es
|
||||
yada install -doc -subdir templates templates/README.en
|
||||
|
@ -0,0 +1,128 @@
|
||||
#! /usr/bin/make -f
|
||||
# Generated automatically from debian/packages
|
||||
# by yada v0.9, of Tue, 07 Dec 1999
|
||||
|
||||
buildarch := $(shell dpkg --print-architecture)
|
||||
|
||||
ifneq "$(buildarch)" "i386"
|
||||
buildarch := any
|
||||
endif
|
||||
|
||||
.PHONY: default
|
||||
default:
|
||||
@echo "Specify a target:"; \
|
||||
echo " build compile the package"; \
|
||||
echo " binary make all binary packages"; \
|
||||
echo " binary-arch make all architecture-dependent binary packages"; \
|
||||
echo " binary-indep make all architecture-independent binary packages"; \
|
||||
echo " clean clean up the source package"; \
|
||||
echo; \
|
||||
echo " install-tree compile the package and create the install trees"; \
|
||||
echo " clean-install-tree clean up only under debian/"; \
|
||||
echo
|
||||
|
||||
# Build the package and prepare the install tree
|
||||
|
||||
.PHONY: build-only build
|
||||
build-only: debian/build-stamp
|
||||
build: build-only
|
||||
|
||||
# Make sure these rules and the control file are up-to-date
|
||||
|
||||
.PHONY: rules control
|
||||
rules: debian/rules
|
||||
debian/rules: debian/yada debian/packages
|
||||
chmod +x debian/yada
|
||||
debian/yada rebuild rules
|
||||
|
||||
control: debian/control
|
||||
debian/control: debian/yada debian/packages
|
||||
chmod +x debian/yada
|
||||
debian/yada rebuild control
|
||||
|
||||
debian/build-stamp:
|
||||
@[ -f debian/yada -a -f debian/rules ]
|
||||
@umask 022 && (\
|
||||
echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
|
||||
echo -E 'echo "Hecho!"') | /bin/sh
|
||||
touch debian/build-stamp
|
||||
|
||||
.PHONY: install-tree
|
||||
install-tree: install-tree-$(buildarch)
|
||||
install-tree-i386: \
|
||||
debian/tmp-bit2svf/DEBIAN/control
|
||||
install-tree-any:
|
||||
|
||||
debian/tmp-bit2svf/DEBIAN/control: debian/build-stamp debian/control
|
||||
rm -rf debian/tmp-bit2svf
|
||||
umask 022 && install -d debian/tmp-bit2svf/DEBIAN
|
||||
chmod +x debian/yada
|
||||
install -d debian/tmp-bit2svf/usr/share/doc/bit2svf
|
||||
umask 022; debian/yada generate copyright \
|
||||
>debian/tmp-bit2svf/usr/share/doc/bit2svf/copyright
|
||||
install -m 644 -p debian/changelog \
|
||||
debian/tmp-bit2svf/usr/share/doc/bit2svf/changelog
|
||||
@umask 022 && export PACKAGE="bit2svf" \
|
||||
&& export ROOT="$$(pwd)/debian/tmp-bit2svf" \
|
||||
&& export CONTROL="$$(pwd)/debian/tmp-bit2svf/DEBIAN" && (\
|
||||
echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
|
||||
echo -E 'yada install -bin bit2svf';\
|
||||
echo -E 'yada install -bin dumpbit';\
|
||||
echo -E 'yada install -bin -unstripped jbit';\
|
||||
echo -E 'yada install -into /usr/share/bit2svf/ templates/*.svft';\
|
||||
echo -E 'yada install -into /usr/share/bit2svf/ templates/DEVICES';\
|
||||
echo -E 'yada install -doc README.es';\
|
||||
echo -E 'yada install -doc README.en';\
|
||||
echo -E 'yada install -doc -subdir templates templates/README.es';\
|
||||
echo -E 'yada install -doc -subdir templates templates/README.en') | /bin/sh
|
||||
debian/yada compress bit2svf
|
||||
find debian/tmp-bit2svf -type f -print \
|
||||
| sed -n 's/^debian\/tmp-bit2svf\(\/etc\/.*\)$$/\1/p' \
|
||||
> debian/tmp-bit2svf/DEBIAN/conffiles
|
||||
if test ! -s debian/tmp-bit2svf/DEBIAN/conffiles; then rm -f debian/tmp-bit2svf/DEBIAN/conffiles; fi
|
||||
debian/yada generate maintscripts bit2svf
|
||||
umask 022 && dpkg-gencontrol -isp -pbit2svf -Pdebian/tmp-bit2svf
|
||||
|
||||
# Build package files
|
||||
|
||||
.PHONY: binary binary-arch binary-indep
|
||||
binary: binary-arch binary-indep
|
||||
binary-arch: binary-arch-$(buildarch)
|
||||
|
||||
.PHONY: binary-arch-i386
|
||||
binary-arch-i386: \
|
||||
binary-package-bit2svf
|
||||
.PHONY: binary-arch-any
|
||||
binary-arch-any:
|
||||
binary-indep:
|
||||
|
||||
.PHONY: binary-package-bit2svf
|
||||
binary-package-bit2svf: check-root debian/tmp-bit2svf/DEBIAN/control
|
||||
@[ -f debian/yada -a -f debian/rules ]
|
||||
chown -R 0.0 debian/tmp-bit2svf
|
||||
chmod -R u=rwX,go=rX debian/tmp-bit2svf
|
||||
@if [ -d debian/tmp-bit2svf/usr/doc/bit2svf ]; then \
|
||||
echo "*** Yada warning: /usr/doc/bit2svf should be /usr/share/doc/bit2svf";\
|
||||
fi
|
||||
dpkg-deb --build debian/tmp-bit2svf ..
|
||||
|
||||
.PHONY: check-root
|
||||
check-root:
|
||||
@[ `id -u` = 0 ] || (echo "You must be root to do this!"; false)
|
||||
|
||||
# Clean up afterwards
|
||||
|
||||
.PHONY: clean clean-install-tree clean-build
|
||||
clean: clean-install-tree clean-build debian/control debian/rules
|
||||
|
||||
clean-build:
|
||||
@[ -f debian/yada -a -f debian/rules ]
|
||||
rm -f debian/build-stamp debian/depends-stamp
|
||||
@umask 022 && (\
|
||||
echo -E 'eval "yada () { perl $$(pwd)/debian/yada \"\$$@\"; }"; set -e; set -v';\
|
||||
echo -E 'echo "Nada para borrar!"') | /bin/sh
|
||||
|
||||
clean-install-tree: debian/rules
|
||||
@[ -f debian/yada -a -f debian/rules ]
|
||||
rm -f debian/install-tree-stamp
|
||||
rm -rf debian/tmp* debian/files* debian/substvars
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,93 @@
|
||||
/**[txh]********************************************************************
|
||||
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
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; version 2.
|
||||
|
||||
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
|
||||
|
||||
Description: Dumps the contents of a xilinx bit file in stdout.
|
||||
|
||||
***************************************************************************/
|
||||
/*****************************************************************************
|
||||
|
||||
Target: Any
|
||||
Language: C
|
||||
Compiler: gcc 3.3.5 (Debian GNU/Linux)
|
||||
Text editor: SETEdit 0.5.5
|
||||
|
||||
*****************************************************************************/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <stdlib.h>
|
||||
#include "bitfile.h"
|
||||
|
||||
#define BSIZE 1048576 /* 1k */
|
||||
|
||||
|
||||
/* read a bit file from stdin */
|
||||
int main(int argc, char *argv[])
|
||||
{
|
||||
struct bithead bh;
|
||||
FILE *bitfile, *outfile;
|
||||
int remaining,readed;
|
||||
char buff[BSIZE];
|
||||
|
||||
fprintf(stderr,"\ndumpbit - bit file stream dumper - v1.0\n");
|
||||
fprintf(stderr,"Copyright (c) 2005 Juan Pablo D. Borgna/INTI\n\n");
|
||||
|
||||
if (argc==1 || argc>3)
|
||||
{
|
||||
fprintf(stderr,"Insufficient args %s filename.bit filename\n",argv[0]);
|
||||
return 1;
|
||||
}
|
||||
|
||||
if ((bitfile=fopen(argv[1],"rb"))==NULL)
|
||||
{
|
||||
perror("BITFILE");
|
||||
return 2;
|
||||
}
|
||||
|
||||
if ((outfile=fopen(argv[2],"wb"))==NULL)
|
||||
{
|
||||
perror("OUTFILE");
|
||||
return 3;
|
||||
}
|
||||
|
||||
initbh(&bh);
|
||||
if (readhead(&bh, bitfile))
|
||||
{
|
||||
fprintf(stderr,"Invalid bit file header.\n");
|
||||
return 3;
|
||||
}
|
||||
|
||||
fprintf(stderr,"\n");
|
||||
fprintf(stderr,"Bit file created on %s at %s.\n", bh.date, bh.time);
|
||||
fprintf(stderr,"Created from file %s for Xilinx part %s.\n", bh.filename, bh.part);
|
||||
fprintf(stderr,"Bitstream length is %d bytes.\n", bh.length);
|
||||
fprintf(stderr,"\n");
|
||||
|
||||
remaining=bh.length;
|
||||
|
||||
while(remaining)
|
||||
{
|
||||
readed=fread(buff,1,BSIZE,bitfile);
|
||||
fwrite(buff,readed,1,outfile);
|
||||
remaining-=readed;
|
||||
}
|
||||
|
||||
fclose(bitfile);
|
||||
freebh(&bh);
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,16 @@
|
||||
/* Globaly used variables */
|
||||
|
||||
long address;
|
||||
long step;
|
||||
long s_bytes;
|
||||
long s_bits;
|
||||
long stream_s;
|
||||
unsigned cutlines;
|
||||
|
||||
char *id;
|
||||
char *idmask;
|
||||
char *bsize;
|
||||
long msize;
|
||||
|
||||
|
||||
char *templ;
|
@ -0,0 +1,232 @@
|
||||
#!/usr/bin/perl
|
||||
#
|
||||
# Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti.gov.ar>
|
||||
# Copyright (c) 2006-2007 Instituto Nacional de Tecnología Industrial
|
||||
#
|
||||
# Based on code:
|
||||
# Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
#
|
||||
# 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; version 2.
|
||||
#
|
||||
# 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
|
||||
#
|
||||
# Este script invoca a bit2svf y jtag para programar el contenido de
|
||||
# un archivo bit en un dispositivo Xilinx.
|
||||
#
|
||||
# Basado en el script original de Juan Pablo D. Borgna
|
||||
#
|
||||
#
|
||||
|
||||
use Getopt::Long;
|
||||
use File::Basename;
|
||||
|
||||
print "jbit - bit2svf/jtag short cut - v2.1\n";
|
||||
print "Copyright (c) 2006-2007 Salvador E. Tropea/INTI\n\n";
|
||||
|
||||
GetOptions(
|
||||
'skip=s' => \$skip,
|
||||
'length=s' => \$len,
|
||||
'help' => \&help);
|
||||
|
||||
if (scalar(@ARGV)!=2)
|
||||
{
|
||||
print "You must specify two arguments\n\n";
|
||||
help();
|
||||
}
|
||||
|
||||
$bitfile=@ARGV[0];
|
||||
|
||||
# Seteos por defecto
|
||||
$jtag="/usr/bin/jtag";
|
||||
$bit2svf="/usr/bin/bit2svf";
|
||||
$svft=@ARGV[1];
|
||||
$temp=`mktemp -t bit2svf.XXXXXX`;
|
||||
chomp($temp);
|
||||
$temp_r=`mktemp -t jbit.XXXXXX`;
|
||||
chomp($temp_r);
|
||||
|
||||
$device="ppdev";
|
||||
$location="/dev/parport0";
|
||||
$cable_type="DLC5";
|
||||
|
||||
if ($skip)
|
||||
{
|
||||
$skip=$1*(1<<20) if ($skip=~/(\d+)M/i);
|
||||
$skip=$1*(1<<10) if ($skip=~/(\d+)k/i);
|
||||
$skip="--skip=$skip";
|
||||
}
|
||||
if ($len)
|
||||
{
|
||||
$len=$1*(1<<20) if ($len=~/(\d+)M/i);
|
||||
$len=$1*(1<<10) if ($len=~/(\d+)k/i);
|
||||
$len="--length=$len";
|
||||
}
|
||||
|
||||
# Leer seteos de ~/.jbitrc
|
||||
$jbitrc=$ENV{'HOME'}.'/.jbitrc';
|
||||
if (-e $jbitrc)
|
||||
{
|
||||
print "Configuration from $jbitrc:\n";
|
||||
open(FIL,"<$jbitrc") or die "Error opening $jbitrc";
|
||||
while ($a=<FIL>)
|
||||
{
|
||||
unless ($a=~/^\#/ or $a=~/^\s*$/)
|
||||
{
|
||||
if ($a=~/^(\S+)\s*=\s*\"?([^\"\n]*)\"?$/)
|
||||
{
|
||||
$var=uc($1);
|
||||
$val=$2;
|
||||
if ($val=~/^\$(\d)$/)
|
||||
{
|
||||
$val=$ARGV[$1-1];
|
||||
}
|
||||
print "$var -> \"$val\"\n";
|
||||
if ($var eq 'JTAG')
|
||||
{
|
||||
$jtag=$val;
|
||||
}
|
||||
elsif ($var eq 'BIT2SVF')
|
||||
{
|
||||
$bit2svf=$val;
|
||||
}
|
||||
elsif ($var eq 'SVFT')
|
||||
{
|
||||
$svft=$val;
|
||||
}
|
||||
elsif ($var eq 'TEMP')
|
||||
{
|
||||
#$temp=$val;
|
||||
print "TEMP is obsolete!!!\n";
|
||||
}
|
||||
elsif ($var eq 'DEVICE')
|
||||
{
|
||||
$device=$val;
|
||||
}
|
||||
elsif ($var eq 'LOCATION')
|
||||
{
|
||||
$location=$val;
|
||||
}
|
||||
elsif ($var eq 'CABLE_TYPE')
|
||||
{
|
||||
$cable_type=$val;
|
||||
}
|
||||
elsif ($var eq 'PARTNUM')
|
||||
{
|
||||
$partnum=$val;
|
||||
print "PARTNUM is obsolete!!!\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Unknown variable $var";
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
die "Error parsing $jbitrc:\n$a";
|
||||
}
|
||||
}
|
||||
}
|
||||
close(FIL);
|
||||
print "\n";
|
||||
}
|
||||
else
|
||||
{
|
||||
print "No personal configuration '$jbitrc'\n";
|
||||
}
|
||||
|
||||
# Compuebo la existencia de todo lo necesario
|
||||
die "Can't find JTAG in $jtag" unless -e $jtag;
|
||||
die "Can't find bit2svf in $bit2svf" unless -e $bit2svf;
|
||||
die "Missing file: $bitfile" unless -e $bitfile;
|
||||
|
||||
# Creo el .svf
|
||||
print "Creating temporary file $temp ...\n<--------- $bit2svf $skip $len $bitfile $temp $svft\n";
|
||||
die "Error creating temporary file $temp"
|
||||
if system("$bit2svf $skip $len $bitfile $temp $svft");
|
||||
print "<--------- end of bit2svf\n\n";
|
||||
|
||||
# Buscar que posición tiene en la cadena
|
||||
print "Analyzing JTAG chain using $jtag ...\n";
|
||||
open(FIL,"|$jtag > $temp_r") or die;
|
||||
print FIL "cable $device $location $cable_type\n";
|
||||
print FIL "detect\n";
|
||||
print FIL "quit\n";
|
||||
close FIL;
|
||||
$ndev=0;
|
||||
$devs=0;
|
||||
$partnum=-1;
|
||||
open(FIL,"<$temp_r") or die;
|
||||
while ($a=<FIL>)
|
||||
{
|
||||
if ($a=~/Chain length: (\d+)/)
|
||||
{
|
||||
$devs=$1;
|
||||
print "Devices in the chain: $devs\n";
|
||||
}
|
||||
elsif ($a=~/Part:\s+(\S+)$/)
|
||||
{
|
||||
$dev=uc($1);
|
||||
print "$ndev: $dev ";
|
||||
if ($svft eq $dev)
|
||||
{
|
||||
print "<--";
|
||||
$partnum=$ndev;
|
||||
}
|
||||
print "\n";
|
||||
$ndev++;
|
||||
}
|
||||
}
|
||||
close(FIL);
|
||||
die "Can't find any device in the chain, consult $temp_r"
|
||||
unless $devs;
|
||||
die "Can't find $svft in the chain" unless $partnum!=-1;
|
||||
print "Device number in the chain: $partnum\n\n";
|
||||
|
||||
# Ejecutarlo
|
||||
print "Transferring $temp using $jtag ...\n<--------- jtag\n";
|
||||
open(FIL,"|$jtag") or die;
|
||||
print FIL "cable $device $location $cable_type\n";
|
||||
print FIL "detect\n";
|
||||
print FIL "part $partnum\n";
|
||||
print FIL "svf $temp\n";
|
||||
print FIL "quit\n";
|
||||
close FIL;
|
||||
print "<--------- fin de jtag\n\n";
|
||||
|
||||
# Clean-up
|
||||
print "Cleaning temporary files ... ($temp $temp_r)\n";
|
||||
`rm -f $temp $temp_r`;
|
||||
print "Have a nice day :-)\n";
|
||||
|
||||
|
||||
sub help
|
||||
{
|
||||
my $me=basename($0);
|
||||
|
||||
print <<END;
|
||||
$me is a program to configure Xilinx devices using JTAG.
|
||||
|
||||
Usage:
|
||||
jbit [OPTIONS] file.bit DEVICE
|
||||
|
||||
Options:
|
||||
--skip=value Skip bits the bitstream
|
||||
--length=value Limit the bitstream length
|
||||
--help This text
|
||||
|
||||
file.bit is the file containing the bitstream.
|
||||
DEVICE is the name of the device to configure.
|
||||
|
||||
END
|
||||
exit 1;
|
||||
}
|
@ -0,0 +1,21 @@
|
||||
#
|
||||
# Ejemplo de configuracion personalizada
|
||||
# Custom config sample
|
||||
# ~/.jbitrc
|
||||
#
|
||||
|
||||
#Paths de archivos necesarios
|
||||
#Needed files path
|
||||
|
||||
JTAG=/usr/bin/jtag
|
||||
BIT2SVF=/usr/bin/bit2svf
|
||||
SVFT="$2"
|
||||
TEMP=/tmp/bit2svf.tmp
|
||||
|
||||
|
||||
#Conexion y configuracion de la cadena
|
||||
#Chain conection and configuration
|
||||
|
||||
DEVICE="ppdev"
|
||||
LOCATION="/dev/parport0"
|
||||
CABLE_TYPE="DLC5"
|
@ -0,0 +1,119 @@
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "parts.h"
|
||||
|
||||
/*
|
||||
part known[] = {
|
||||
{"XC18V01","f5034093","0ffeffff","alg_18V",0x3FC0},
|
||||
{"XC2S100","f0614093","0fffffff","alg_VIRTEX",0l},
|
||||
{NULL,NULL,NULL,NULL,0l}
|
||||
};
|
||||
*/
|
||||
#define TOKDELIM " \t/,;.\n"
|
||||
|
||||
part *
|
||||
text_to_part(char *text)
|
||||
{
|
||||
part temp, *ret;
|
||||
char *token;
|
||||
|
||||
token=strtok(text,TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.name=strdup(token);
|
||||
|
||||
token=strtok(NULL,TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.id=strdup(token);
|
||||
|
||||
token=strtok(NULL,TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.idmask=strdup(token);
|
||||
|
||||
token=strtok(NULL, TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.alg_tpl=strdup(token);
|
||||
|
||||
token=strtok(NULL, TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.bsize=strdup(token);
|
||||
|
||||
token=strtok(NULL,TOKDELIM);
|
||||
if (token==NULL) return NULL;
|
||||
temp.msize=strtol(token,NULL,0);
|
||||
|
||||
|
||||
if((ret=(part *)malloc(sizeof(part)))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Cannot asign memory needed for a part\n");
|
||||
return NULL;
|
||||
}
|
||||
*ret=temp;
|
||||
return ret;
|
||||
}
|
||||
|
||||
|
||||
int
|
||||
select_part_from_file(char *name, char *file, part **ret)
|
||||
{
|
||||
char buff[1000];
|
||||
FILE *fp;
|
||||
|
||||
if((fp=fopen(file,"rt"))==NULL)
|
||||
{
|
||||
fprintf(stderr,"Unable to open devices file %s.\n",file);
|
||||
return 1;
|
||||
}
|
||||
|
||||
fgets(buff,1000,fp);
|
||||
|
||||
while(!feof(fp))
|
||||
{
|
||||
if (strncasecmp(buff,"//",2) && (buff[0]!='\n')) /*If its not a comment*/
|
||||
{ /* or a blank line ...*/
|
||||
*ret=text_to_part(buff);
|
||||
if (*ret==NULL)
|
||||
fprintf(stderr,"Invalid line inside device file: %s\n",buff);
|
||||
else if (!strcasecmp(name,(*ret)->name))
|
||||
{ /* FOUND! */
|
||||
fclose(fp);
|
||||
return 0;
|
||||
}
|
||||
}
|
||||
fgets(buff,1000,fp);
|
||||
}
|
||||
|
||||
*ret=NULL;
|
||||
fprintf(stderr,"Device not found inside device file: %s\n",name);
|
||||
fclose(fp);
|
||||
return 1;
|
||||
}
|
||||
|
||||
/*
|
||||
int
|
||||
select_part_by_name(char *name, part **ret)
|
||||
{
|
||||
int found=0;
|
||||
part *r;
|
||||
|
||||
r=known;
|
||||
|
||||
while (r->name && !found)
|
||||
{
|
||||
if (!strcasecmp(r->name,name))
|
||||
found=1;
|
||||
else
|
||||
r++;
|
||||
}
|
||||
|
||||
if (!found)
|
||||
{
|
||||
fprintf(stderr,"Device not found %s\n",name);
|
||||
return 1;
|
||||
}
|
||||
|
||||
*ret=r;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
*/
|
@ -0,0 +1,19 @@
|
||||
#include <stdio.h>
|
||||
|
||||
typedef struct part_
|
||||
{
|
||||
char *name;
|
||||
char *id;
|
||||
char *idmask;
|
||||
char *alg_tpl;
|
||||
char *bsize;
|
||||
long msize;
|
||||
} part;
|
||||
|
||||
|
||||
|
||||
/* Some headers */
|
||||
int select_part_by_name(char *name, part **ret);
|
||||
part *text_to_part(char *text);
|
||||
int select_part_from_file(char *name, char *file, part **ret);
|
||||
|
@ -0,0 +1,103 @@
|
||||
!_TAG_FILE_FORMAT 2 /extended format; --format=1 will not append ;" to lines/
|
||||
!_TAG_FILE_SORTED 1 /0=unsorted, 1=sorted, 2=foldcase/
|
||||
!_TAG_PROGRAM_AUTHOR Darren Hiebert /dhiebert@users.sourceforge.net/
|
||||
!_TAG_PROGRAM_NAME Exuberant Ctags //
|
||||
!_TAG_PROGRAM_URL http://ctags.sourceforge.net /official site/
|
||||
!_TAG_PROGRAM_VERSION 5.5.4 //
|
||||
Architecture debian/yada /^Architecture: any$/;" kind:l language:Perl
|
||||
BIDIR Makefile /^BIDIR=bitinfo-0.3$/;" kind:m language:Make
|
||||
BSIZE dumpbit.c 36;" kind:d language:C file:
|
||||
Build debian/yada /^Build: sh$/;" kind:l language:Perl
|
||||
CC Makefile /^CC=gcc$/;" kind:m language:Make
|
||||
CC bitinfo-0.3/Makefile /^CC = gcc$/;" kind:m language:Make
|
||||
CFLAGS Makefile /^CFLAGS=-Wall -g3 -I$(BIDIR)$/;" kind:m language:Make
|
||||
CFLAGS bitinfo-0.3/Makefile /^CFLAGS = -c -g -Wall$/;" kind:m language:Make
|
||||
Clean debian/yada /^Clean: sh$/;" kind:l language:Perl
|
||||
Copyright debian/yada /^Copyright: GPL$/;" kind:l language:Perl
|
||||
DEFAULT_RES bit2svf.c 41;" kind:d language:C file:
|
||||
Depends debian/yada /^Depends: [\/usr\/bin\/*]$/;" kind:l language:Perl
|
||||
Description debian/yada /^Description: Some binary package$/;" kind:l language:Perl
|
||||
Description debian/yada /^Description: Some package$/;" kind:l language:Perl
|
||||
Install debian/yada /^Install: sh$/;" kind:l language:Perl
|
||||
LDFLAGS Makefile /^LDFLAGS=-I$(BIDIR)$/;" kind:m language:Make
|
||||
LDFLAGS bitinfo-0.3/Makefile /^LDFLAGS = $/;" kind:m language:Make
|
||||
Maintainer debian/yada /^Maintainer: Mr. Nobody <nobody\\@root.org>$/;" kind:l language:Perl
|
||||
Notably debian/yada /^Notably:$/;" kind:l language:Perl
|
||||
OBJECTS bitinfo-0.3/Makefile /^OBJECTS = bitinfo.o bitfile.o$/;" kind:m language:Make
|
||||
PKG Makefile /^PKG=bit2svf-$(VERSION)$/;" kind:m language:Make
|
||||
PROYECTO Makefile /^PROYECTO=dumpbit bit2svf$/;" kind:m language:Make
|
||||
Package debian/yada /^Package: $pkg$/;" kind:l language:Perl
|
||||
Packager debian/yada /^Packager: T. Raven <nevermore\\@poe.net>$/;" kind:l language:Perl
|
||||
Priority debian/yada /^Priority: unknown$/;" kind:l language:Perl
|
||||
Section debian/yada /^Section: unknown$/;" kind:l language:Perl
|
||||
Source debian/yada /^Source: $pkg$/;" kind:l language:Perl
|
||||
TOKDELIM parts.c 12;" kind:d language:C file:
|
||||
Usage debian/yada /^Usage: yada action [args...]$/;" kind:l language:Perl
|
||||
VERSION Makefile /^VERSION=1.1.0$/;" kind:m language:Make
|
||||
address global.h /^long address;$/;" kind:v language:C++
|
||||
alg_tpl parts.h /^ char *alg_tpl;$/;" kind:m language:C++ struct:part_
|
||||
append debian/yada /^sub append {$/;" kind:s language:Perl
|
||||
binary debian/yada /^binary: binary-arch binary-indep$/;" kind:l language:Perl
|
||||
bithead bitinfo-0.3/bitfile.h /^struct bithead$/;" kind:s language:C++
|
||||
bsize global.h /^char *bsize;$/;" kind:v language:C++
|
||||
bsize parts.h /^ char *bsize;$/;" kind:m language:C++ struct:part_
|
||||
choke debian/yada /^sub choke {$/;" kind:s language:Perl
|
||||
chokepoint debian/yada /^ sub chokepoint {$/;" kind:s language:Perl
|
||||
control debian/yada /^control: debian\/control$/;" kind:l language:Perl
|
||||
cutputs bitshandle.c /^cutputs(char *string, FILE *fp, long block, int *col)$/;" kind:f language:C
|
||||
date bitinfo-0.3/bitfile.h /^ char* date;$/;" kind:m language:C++ struct:bithead
|
||||
default debian/yada /^default:$/;" kind:l language:Perl
|
||||
depends debian/yada /^depends: debian\/depends-stamp$/;" kind:l language:Perl
|
||||
do_command commands.c /^do_command(char *cmd, FILE *dfp, FILE *ofp, int *col)$/;" kind:f language:C
|
||||
filename bitinfo-0.3/bitfile.h /^ char* filename;$/;" kind:m language:C++ struct:bithead
|
||||
fill commands.c /^fill(FILE *fp, long c, long t)$/;" kind:f language:C
|
||||
freebh bitinfo-0.3/bitfile.c /^void freebh(struct bithead *bh)$/;" kind:f language:C
|
||||
gasp debian/yada /^ sub gasp {$/;" kind:s language:Perl
|
||||
getpara debian/yada /^sub getpara {$/;" kind:s language:Perl
|
||||
getvars debian/yada /^sub getvars {$/;" kind:s language:Perl
|
||||
head13 bitinfo-0.3/bitfile.c /^static uchar head13[] = {0, 9, 15, 240, 15, 240, 15, 240, 15, 240, 0, 0, 1};$/;" kind:v language:C file:
|
||||
id global.h /^char *id;$/;" kind:v language:C++
|
||||
id parts.h /^ char *id;$/;" kind:m language:C++ struct:part_
|
||||
idmask global.h /^char *idmask;$/;" kind:v language:C++
|
||||
idmask parts.h /^ char *idmask;$/;" kind:m language:C++ struct:part_
|
||||
initbh bitinfo-0.3/bitfile.c /^void initbh(struct bithead *bh)$/;" kind:f language:C
|
||||
inv_byte bitshandle.c /^inv_byte(unsigned char b)$/;" kind:f language:C
|
||||
length bitinfo-0.3/bitfile.h /^ int length;$/;" kind:m language:C++ struct:bithead
|
||||
main bit2svf.c /^int main(int argc, char *argv[])$/;" kind:f language:C
|
||||
main bitinfo-0.3/bitinfo.c /^int main(void)$/;" kind:f language:C
|
||||
main dumpbit.c /^int main(int argc, char *argv[])$/;" kind:f language:C
|
||||
makescript debian/yada /^sub makescript {$/;" kind:s language:Perl
|
||||
msize global.h /^long msize;$/;" kind:v language:C++
|
||||
msize parts.h /^ long msize;$/;" kind:m language:C++ struct:part_
|
||||
name parts.h /^ char *name;$/;" kind:m language:C++ struct:part_
|
||||
normalise debian/yada /^sub normalise {$/;" kind:s language:Perl
|
||||
parsebinarypara debian/yada /^sub parsebinarypara {$/;" kind:s language:Perl
|
||||
parsesourcepara debian/yada /^sub parsesourcepara {$/;" kind:s language:Perl
|
||||
part bitinfo-0.3/bitfile.h /^ char* part;$/;" kind:m language:C++ struct:bithead
|
||||
part parts.h /^ } part;$/;" kind:t language:C++
|
||||
part_ parts.h /^typedef struct part_$/;" kind:s language:C++
|
||||
patch debian/yada /^patch: debian\/patch-stamp$/;" kind:l language:Perl
|
||||
pb bitshandle.c /^pb(char *to, char *from,long nbytes)$/;" kind:f language:C
|
||||
pbi bitshandle.c /^pbi(char *to, char *from,long nbytes)$/;" kind:f language:C
|
||||
printkey debian/yada /^sub printkey {$/;" kind:s language:Perl
|
||||
printkeys debian/yada /^sub printkeys {$/;" kind:s language:Perl
|
||||
readhead bitinfo-0.3/bitfile.c /^int readhead(struct bithead *bh, FILE *f)$/;" kind:f language:C
|
||||
readhead13 bitinfo-0.3/bitfile.c /^int readhead13 (FILE *f)$/;" kind:f language:C
|
||||
readlength bitinfo-0.3/bitfile.c /^int readlength(FILE *f)$/;" kind:f language:C
|
||||
readpackages debian/yada /^sub readpackages {$/;" kind:s language:Perl
|
||||
readsecthead bitinfo-0.3/bitfile.c /^int readsecthead(char *buf, FILE *f)$/;" kind:f language:C
|
||||
readsection bitinfo-0.3/bitfile.c /^int readsection(char *buf, int length, FILE *f)$/;" kind:f language:C
|
||||
repeat commands.c /^repeat (FILE *ifp, FILE *ofp, FILE *dfp,long limit)$/;" kind:f language:C
|
||||
rules debian/yada /^rules: debian\/rules$/;" kind:l language:Perl
|
||||
run debian/yada /^sub run {$/;" kind:s language:Perl
|
||||
s_bits global.h /^long s_bits;$/;" kind:v language:C++
|
||||
s_bytes global.h /^long s_bytes;$/;" kind:v language:C++
|
||||
select_part_from_file parts.c /^select_part_from_file(char *name, char *file, part **ret)$/;" kind:f language:C
|
||||
step global.h /^long step;$/;" kind:v language:C++
|
||||
stream_s global.h /^long stream_s;$/;" kind:v language:C++
|
||||
templ global.h /^char *templ;$/;" kind:v language:C++
|
||||
text_to_part parts.c /^text_to_part(char *text)$/;" kind:f language:C
|
||||
time bitinfo-0.3/bitfile.h /^ char* time;$/;" kind:m language:C++ struct:bithead
|
||||
uchar bitinfo-0.3/bitfile.c 31;" kind:d language:C file:
|
||||
unpatch debian/yada /^unpatch:$/;" kind:l language:Perl
|
||||
value_from commands.c /^value_from(char *varname)$/;" kind:f language:C
|
@ -0,0 +1,42 @@
|
||||
//One device per line
|
||||
//NAME | ID | IDMASK | ALG_TPL | BSIZE | MSIZE (last mem pos)
|
||||
// XC18V memories
|
||||
XC18V256 , f5022093, 0ffeffff, alg_18V , 2048 , 0x1000
|
||||
XC18V512 , f5023093, 0ffeffff, alg_18V , 2048 , 0x2000
|
||||
XC18V01 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
|
||||
XC18V01-SO20 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
|
||||
XC18V02 , f5025093, 0ffeffff, alg_18V , 4096 , 0x4000
|
||||
XC18V04 , f5026093, 0ffeffff, alg_18V , 4096 , 0x8000
|
||||
|
||||
// XCF memories
|
||||
XCF01S , f5044093, 0ffeffff, alg_XCF , 2048 , 0x4000
|
||||
XCF02S , f5045093, 0ffeffff, alg_XCF , 4096 , 0x4000
|
||||
XCF04S , f5046093, 0ffeffff, alg_XCF , 4096 , 0x8000
|
||||
|
||||
// XCFxxP memories
|
||||
XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
|
||||
|
||||
// Spartan II family (5 bits IR)
|
||||
XC2S15 , f0608093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S30 , f060c093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S50 , f0610093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S100 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S100-PQ208 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S150 , f0618093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S200 , f061c093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
|
||||
// Spartan 3 family (6 bits IR)
|
||||
XC3S50 , f140D093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S200 , f1414093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S400 , f141C093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S1000, f1428093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S1500, f1434093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S2000, f1440093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S4000, f1448093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S5000, f1450093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
|
||||
// Virtex 4 family (10 bits IR)
|
||||
XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
|
||||
|
||||
//EOF
|
||||
|
@ -0,0 +1,112 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
Commands and blocks:
|
||||
The template files have block commands and operation
|
||||
commands. The block commands start with two substract
|
||||
signs "--" and the operation are betwin dollar signs "$".
|
||||
The block commands mark the excecution of a block and the
|
||||
end of the block must be identifyed with the instruction
|
||||
"--END".
|
||||
|
||||
Internal variables:
|
||||
The next internal variables are provided wich can be used
|
||||
indicating their name betwin dollars signs "$" or modified
|
||||
if a value is assigned using parentesis signs.
|
||||
Ex.: $ADDRESS(0x00)$ asigns this variable the value 0x0000.
|
||||
|
||||
$ADDRESS$ :
|
||||
Accumulator useful at the time of incrementing a memory address.
|
||||
|
||||
$STEP$ :
|
||||
Value on wich $ADDRESS$ variable will be incremented.
|
||||
|
||||
$BSIZEB$ :
|
||||
Amount of bytes of the bitstream file.
|
||||
|
||||
$BSIZEB2$ :
|
||||
2 * amount of bytes of the bitstream file.
|
||||
|
||||
$BSIZE$ :
|
||||
Amount of bits of the bitstream file.
|
||||
Note: BSIZE an STEP are related. BSIZE is the size of the cache
|
||||
used to store the data before flashing the device. Each memory
|
||||
address contains some bits that's a word, the STEP is the size of
|
||||
the cache in words. So BSIZE=STEP*word_size.
|
||||
For the XC18V: 32*64=2048 o 32*128=4096.
|
||||
|
||||
$MSIZE$ :
|
||||
Taken from the msize field from the device definition in the
|
||||
DEVICES file.
|
||||
It contains the last memory position of a device with memory.
|
||||
|
||||
$ID$ :
|
||||
Taken from the id field from the device definition in the DEVICES
|
||||
file.
|
||||
It contains the IDCODE of the selected device.
|
||||
|
||||
$IDMASK$ :
|
||||
Taken from the idmask field from the device definition in the
|
||||
DEVICE file.
|
||||
It contains the mask wich be used in the comprobation of the IDCODE
|
||||
|
||||
|
||||
Block commands:
|
||||
|
||||
--LITERAL START :
|
||||
It indicate that in the output file must be copied the content
|
||||
of this block until the end is found "as is".
|
||||
If an operational command is found inside it is excecuted.
|
||||
|
||||
--REPEAT START :
|
||||
|
||||
It indicate that this block will be repeated until the end of
|
||||
the bitfile is reached.
|
||||
This block must have inside some operational command wich
|
||||
reads information from the input bitfile, if not, the end of
|
||||
this will never be reached and the progran will keep
|
||||
repeating this block until there is no more disk space.
|
||||
With each block iteration the variable $ADDRESS$ is
|
||||
incremented by $STEP$.
|
||||
|
||||
--REPEAT UNTIL value :
|
||||
It indicates that this block will be repeated until the
|
||||
variable $ADDRESS$ reach the value passed as parameter.
|
||||
With each block iteration the variable $ADDRESS$ is
|
||||
incremented by $STEP$.
|
||||
The value passwd as parameter must be $STEP$ multiplo,
|
||||
or the exit condition will never be reached and the
|
||||
program will keep repeating this block until there is
|
||||
no more disk space.
|
||||
Instead of value you can use a variable:
|
||||
Ej.: --REPEAT UNTIL MSIZE
|
||||
|
||||
|
||||
--END :
|
||||
It indicates the end of a LITERAL, REPEAT or REPEAT UNTIL block.
|
||||
|
||||
|
||||
Opeation commands:
|
||||
The operation commands may recive as an argment the name of
|
||||
a variable instead of a constant:
|
||||
Ej.: $FILL(0xFF,BSIZE)$
|
||||
|
||||
$DATA(ndatabytes)$ :
|
||||
Writes in the output file a ndatabytes amount of bytes
|
||||
from the input bitfile expressed in hex.
|
||||
|
||||
$DATA_INV(ndatabytes)$ :
|
||||
Writes in the output fila a ndatabytes amount of bytes
|
||||
from the input bitfile inverting the order, expressed
|
||||
in hex.
|
||||
|
||||
$FILL(VAL,TIMES)$ :
|
||||
Writes TIMES times the value VAL expressed in hex in the
|
||||
output file.
|
||||
|
||||
$REWIND$ :
|
||||
Rewinds the bitfile to the first stream byte so it can be used in a
|
||||
new block.
|
||||
|
||||
|
@ -0,0 +1,237 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
Comandos y bloques:
|
||||
Los archivos de template tienen comandos de bloque y
|
||||
comandos de operacion. Los comandos de bloque comienzan con
|
||||
dos signos menos "--" y los de operacion van encerrados entre
|
||||
signos pesos "$". Los comandos de bloque indican la ejecucion
|
||||
de un bloque y el fin de bloque debe ser indicado con la
|
||||
instruccion "--END".
|
||||
|
||||
|
||||
Variables internas:
|
||||
Se proporcionan las siguientes variables internas que pueden
|
||||
ser utilizadas invocando su nombre entre signos pesos "$" o
|
||||
modificados si ademas se les asigna un valor entre
|
||||
parentesis. Ej. $ADDRESS(0x0000)$ le asignara a esta variable
|
||||
el valor 0x0000.
|
||||
|
||||
$ADDRESS$ :
|
||||
Acumulador que es util al momento de incrementar la direccion de una
|
||||
memoria, por ejemplo.
|
||||
|
||||
$STEP$ :
|
||||
Valor con el cual se incrementara la variable $ADDRESS$.
|
||||
|
||||
$SBYTES$ :
|
||||
Cantidad de bytes que posee el bitstream del bitfile.
|
||||
|
||||
$SBITES$ :
|
||||
Cantidad de bits que posee el bitstream del bitfile.
|
||||
|
||||
$MSIZE$ :
|
||||
Obtenido del campo msize de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Expresa la ultima posicion de memoria de un dispositivo con memoria.
|
||||
|
||||
$ID$ :
|
||||
Obtenido del campo id de la definicion del dispositivo en el archivo
|
||||
DEVICES.
|
||||
Expresa el IDCODE del dispositivo actual.
|
||||
|
||||
$IDMASK$ :
|
||||
Obtenido del campo idmask de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Expresa la mascara que se usara en la comprobacion del IDCODE.
|
||||
|
||||
$BSIZE$ :
|
||||
Obtenido del campo BSIZE de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Es el "block size" (cantidad de bits) a transferir expresando
|
||||
en bits.
|
||||
Nota: El valor BSIZE y el valor STEP no son cosas separadas.
|
||||
BSIZE es el tamaño en bits de la cache que tiene el dispositivo
|
||||
para almacenar los datos antes de transferirlos a la flash.
|
||||
Cada dirección de memoria direcciona una cantidad de bits (64
|
||||
o 128 es lo común), el STEP es el número de posiciones de memoria
|
||||
que entran en la cache, luego BSIZE=STEP*bits_por_dirección.
|
||||
Esto es en las XC18V: 32*64=2048 o 32*128=4096.
|
||||
|
||||
$BSIZEB$ :
|
||||
Obtenido del campo BSIZE de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Es el "block size" (cantidad de bits) a transferir expresando
|
||||
en bytes.
|
||||
|
||||
$BSIZEB2$ :
|
||||
$BSIZEB$ multiplicado por 2.
|
||||
|
||||
Comandos de bloque:
|
||||
|
||||
|
||||
--LITERAL START :
|
||||
Indica que se debe copiar en el archivo de salida el contenido
|
||||
de este bloque y hasta el final del mismo tal y como esta.
|
||||
Si se encuentra un comando de operacion entre medio este es
|
||||
ejecutado.
|
||||
|
||||
--REPEAT START :
|
||||
Indica que se repetira de principio a fin el contenido de este
|
||||
bloque mientras que haya informacion que leer en el bitfile
|
||||
de entrada.
|
||||
Este comando de bloque debe tener en su interior algun comando
|
||||
de operacion que lea informacion del bitfile de entrada, si no
|
||||
este nunca llegara a su fin y el programa se quedara
|
||||
repitiendo el bloque hasta agotar el espacio en disco.
|
||||
Con cada iteracion del bloque se incrementa la variable
|
||||
$ADDRESS$ en $STEP$.
|
||||
|
||||
--REPEAT UNTIL valor :
|
||||
Indica que se repetira de principio a fin el contenido de
|
||||
este bloque hasta que la variable $ADDRESS$ tome el valor
|
||||
pasado como parametro. Con cada iteracion del bloque se
|
||||
incrementara la variable $ADDRESS$ en $STEP$.
|
||||
El valor pasado como parametro debe ser multiplo de
|
||||
$STEP$, si no la condicion de salida del bloque nunca se
|
||||
conseguira y el programa se quedara repitiendo el bloque
|
||||
hasta agotar el espacio en disco.
|
||||
En lugar de valor se puede utilizar una variable:
|
||||
Ej.: --REPEAT UNTIL MSIZE
|
||||
|
||||
|
||||
--END :
|
||||
Indica el final de un bloque LITERAL, REPEAT o REPEAT UNTIL.
|
||||
|
||||
|
||||
Comandos de operacion:
|
||||
Los comandos de operacion pueden recibir como argumento
|
||||
el nombre de una variable en lugar de una constante:
|
||||
Ej.: $FILL(0xFF,BSIZE)$
|
||||
|
||||
$DATA(ndatabytes)$ :
|
||||
Escribe en el archivo de salida una cantidad ndatabytes de
|
||||
bytes del bitfile de entrada expresados en hexadecimal.
|
||||
|
||||
$DATA_INV(ndatabytes)$ :
|
||||
Escribe en el archivo de salida una cantidad ndatabytes
|
||||
de bytes del bitfile de entrada, invirtiendo el orden
|
||||
de los bits del bloque, expresados en hexadecimal.
|
||||
|
||||
$FILL(VAL,TIMES)$ :
|
||||
Escribe TIMES veces el valor VAL expresado en hexadecimal en
|
||||
el archivo de salida.
|
||||
|
||||
$REWIND$ :
|
||||
Vuelve a poner el archivo de bits en la posicion del primer byte del
|
||||
stream para poder realizar otra pasada completa con un comando de
|
||||
bloque.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Como crear un template para una FPGA:
|
||||
-------------------------------------
|
||||
|
||||
Autor: Salvador E. Tropea
|
||||
|
||||
A) Crear un .SVF válido para esa FPGA:
|
||||
|
||||
1) Obtener un .bit para la FPGA en cuestión.
|
||||
2) Abrir el impact:
|
||||
$ . /usr/local/ISEWb/settings.sh
|
||||
$ impact
|
||||
3) Elegir "I want to (*) Create a new project", Ok. (Darle un nombre si se
|
||||
quiere).
|
||||
4) Elegir "(*) Prepare a boundary-scan file [SVF]", Finish.
|
||||
5) Elegir un nombre para el SVF.
|
||||
6) Elegir el .bit.
|
||||
7) Presionar el botón derecho sobre la FPGA y elegir "Program", Ok.
|
||||
8) Salir del impact
|
||||
|
||||
Automáticamente es:
|
||||
|
||||
setPreference -pref AutoSignature:FALSE
|
||||
setPreference -pref KeepSVF:FALSE
|
||||
setPreference -pref ConcurrentMode:FALSE
|
||||
setPreference -pref UseHighz:FALSE
|
||||
setPreference -pref UserLevel:NOVICE
|
||||
setPreference -pref svfUseTime:FALSE
|
||||
setMode -bs
|
||||
setMode -bs
|
||||
setCable -port svf -file "salida.svf"
|
||||
addDevice -p 1 -file "archivo.bit"
|
||||
Program -p 1 -s -defaultVersion 0
|
||||
|
||||
B) Crear un nuevo template (ej: alg_Virtex_4.svft)
|
||||
|
||||
1) Abrir un template que ya exista para usarlo de guía.
|
||||
2) Borrar "FREQUENCY 1E6 HZ;"
|
||||
3) Reemplazar: $ID$ y $IDMASK$ en la parte que dice "Loading device with
|
||||
'idcode' instruction.". (f167c093)
|
||||
4) Reemplazar la megalínea del bitstream por:
|
||||
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
|
||||
|
||||
C) Probar su funcionamiento
|
||||
|
||||
1) Colocar el nuevo template en /usr/share/bit2svf/
|
||||
2) Editar /usr/share/bit2svf/DEVICES agregando el ID de la FPGA y el algoritmo
|
||||
a usar:
|
||||
|
||||
// Virtex 4 family (10 bits IR)
|
||||
XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
|
||||
|
||||
3) Probar el template:
|
||||
|
||||
$ bit2svf display_test_lx25.bit v4-b2s.svf XC4VLX25
|
||||
|
||||
Esto genera v4-b2s.svf que debería ser practicamente idéntico al generado por
|
||||
impact.
|
||||
Nota: En este caso observé que el impact agrega 32 bits en 0 extra al
|
||||
bitstream. Esto no parece ser indispensable y sospecho que sirve para
|
||||
"limpiar/vaciar" la cadena.
|
||||
4) Si todo fue OK se puede probar con el dispositivo:
|
||||
|
||||
$ jbit display_test_lx25.bit XC4VLX25
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Como crear un template para una PROM:
|
||||
-------------------------------------
|
||||
|
||||
Autor: Salvador E. Tropea
|
||||
|
||||
A) Crear un archivo de PROM válido.
|
||||
|
||||
1) Obtener un .bit para la FPGA en cuestión.
|
||||
2) Abrir el impact:
|
||||
$ . /usr/local/ISEWb/settings.sh
|
||||
$ impact
|
||||
3) Elegir "I want to (*) Prepare a ROM file", Ok. (Darle un nombre si se
|
||||
quiere).
|
||||
4) Elegir "I want to target a (*) Xilinx PROM", "PROM File name" darle un
|
||||
nombre. Next. (Ojo con el path).
|
||||
5) Elegir la PROM y Add, luego Next.
|
||||
6) Agregar el .bit
|
||||
7) Elegir "Generate File ..." dentro de las acciones disponibles (la única).
|
||||
8) Esto genera un .MCS con el contenido para la PROM.
|
||||
|
||||
B) Crear un .SVF válido para esa PROM. Esto es similar a la FPGA, la única
|
||||
diferencia es que le especificamos el .MCS en lugar de un .bit. En este caso
|
||||
nos preguntará cual es el dispositivo haciendo un guess de cual se trata. Esto
|
||||
es porque el .mcs es un bitstream crudo y no dice para que dispositivo se
|
||||
hizo.
|
||||
Durante este proceso se pueden elegir opciones como si la PROM se conecta en
|
||||
paralelo y si se incluye verificación. Además hay que elegir que primero la
|
||||
borre.
|
||||
|
||||
B) Crear un nuevo template o usar uno ya hecho. Esto es como con la FPGA.
|
||||
|
||||
C) Probar su funcionamiento. Esto es más o menos lo mismo que con la FPGA. La
|
||||
principal diferencia con las PROMs es que acá es necesario configurar su tamaño
|
||||
y el tamaño de la caché o página donde se guardarán temporalmente los datos:
|
||||
|
||||
// XCFxxP memories
|
||||
XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
|
||||
|
@ -0,0 +1,42 @@
|
||||
//One device per line
|
||||
//NAME | ID | IDMASK | ALG_TPL | BSIZE | MSIZE
|
||||
// XC18V memories
|
||||
XC18V256 , f5022093, 0ffeffff, alg_18V , 2048 , 0x1000
|
||||
XC18V512 , f5023093, 0ffeffff, alg_18V , 2048 , 0x2000
|
||||
XC18V01 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
|
||||
XC18V01-SO20 , f5024093, 0ffeffff, alg_18V , 2048 , 0x4000
|
||||
XC18V02 , f5025093, 0ffeffff, alg_18V , 4096 , 0x4000
|
||||
XC18V04 , f5026093, 0ffeffff, alg_18V , 4096 , 0x8000
|
||||
|
||||
// XCF memories
|
||||
XCF01S , f5044093, 0ffeffff, alg_XCF , 2048 , 0x4000
|
||||
XCF02S , f5045093, 0ffeffff, alg_XCF , 4096 , 0x4000
|
||||
XCF04S , f5046093, 0ffeffff, alg_XCF , 4096 , 0x8000
|
||||
|
||||
// XCFxxP memories
|
||||
XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
|
||||
|
||||
// Spartan II family (5 bits IR)
|
||||
XC2S15 , f0608093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S30 , f060c093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S50 , f0610093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S100 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S100-PQ208 , f0614093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S150 , f0618093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
XC2S200 , f061c093, 0fffffff, alg_Spartan_II, VOID , 0l
|
||||
|
||||
// Spartan 3 family (6 bits IR)
|
||||
XC3S50 , f140D093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S200 , f1414093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S400 , f141C093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S1000, f1428093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S1500, f1434093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S2000, f1440093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S4000, f1448093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
XC3S5000, f1450093, 0fffffff, alg_Spartan_3, VOID , 0l
|
||||
|
||||
// Virtex 4 family (10 bits IR)
|
||||
XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
|
||||
|
||||
//EOF
|
||||
|
@ -0,0 +1,115 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
Commands and blocks:
|
||||
The template files have block commands and operation
|
||||
commands. The block commands start with two substract
|
||||
signs "--" and the operation are betwin dollar signs "$".
|
||||
The block commands mark the excecution of a block and the
|
||||
end of the block must be identifyed with the instruction
|
||||
"--END".
|
||||
|
||||
Internal variables:
|
||||
The next internal variables are provided wich can be used
|
||||
indicating their name betwin dollars signs "$" or modified
|
||||
if a value is assigned using parentesis signs.
|
||||
Ex.: $ADDRESS(0x00)$ asigns this variable the value 0x0000.
|
||||
|
||||
$ADDRESS$ :
|
||||
Accumulator useful at the time of incrementing a memory address.
|
||||
|
||||
$STEP$ :
|
||||
Value on wich $ADDRESS$ variable will be incremented.
|
||||
|
||||
$BSIZEB$ :
|
||||
Amount of bytes of the bitstream file.
|
||||
|
||||
$BSIZEB2$ :
|
||||
2 * amount of bytes of the bitstream file.
|
||||
|
||||
$BSIZE$ :
|
||||
Amount of bits of the bitstream file.
|
||||
Note: BSIZE an STEP are related. BSIZE is the size of the cache
|
||||
used to store the data before flashing the device. Each memory
|
||||
address contains some bits that's a word, the STEP is the size of
|
||||
the cache in words. So BSIZE=STEP*word_size.
|
||||
For the XC18V: 32*64=2048 o 32*128=4096.
|
||||
|
||||
$MSIZE$ :
|
||||
Taken from the msize field from the device definition in the
|
||||
DEVICES file.
|
||||
It contains the last memory position of a device with memory.
|
||||
|
||||
$ID$ :
|
||||
Taken from the id field from the device definition in the DEVICES
|
||||
file.
|
||||
It contains the IDCODE of the selected device.
|
||||
|
||||
$IDMASK$ :
|
||||
Taken from the idmask field from the device definition in the
|
||||
DEVICE file.
|
||||
It contains the mask wich be used in the comprobation of the IDCODE
|
||||
|
||||
|
||||
Block commands:
|
||||
|
||||
--LITERAL START :
|
||||
It indicate that in the output file must be copied the content
|
||||
of this block until the end is found "as is".
|
||||
If an operational command is found inside it is excecuted.
|
||||
|
||||
--REPEAT START :
|
||||
|
||||
It indicate that this block will be repeated until the end of
|
||||
the bitfile is reached.
|
||||
This block must have inside some operational command wich
|
||||
reads information from the input bitfile, if not, the end of
|
||||
this will never be reached and the progran will keep
|
||||
repeating this block until there is no more disk space.
|
||||
With each block iteration the variable $ADDRESS$ is
|
||||
incremented by $STEP$.
|
||||
|
||||
--REPEAT UNTIL value :
|
||||
It indicates that this block will be repeated until the
|
||||
variable $ADDRESS$ reach the value passed as parameter.
|
||||
With each block iteration the variable $ADDRESS$ is
|
||||
incremented by $STEP$.
|
||||
The value passwd as parameter must be $STEP$ multiplo,
|
||||
or the exit condition will never be reached and the
|
||||
program will keep repeating this block until there is
|
||||
no more disk space.
|
||||
Instead of value you can use a variable:
|
||||
Ej.: --REPEAT UNTIL MSIZE
|
||||
|
||||
|
||||
--END :
|
||||
It indicates the end of a LITERAL, REPEAT or REPEAT UNTIL block.
|
||||
|
||||
|
||||
Opeation commands:
|
||||
The operation commands may recive as an argment the name of
|
||||
a variable instead of a constant:
|
||||
Ej.: $FILL(0xFF,BSIZE)$
|
||||
|
||||
$DATA(ndatabytes)$ :
|
||||
Writes in the output file a ndatabytes amount of bytes
|
||||
from the input bitfile expressed in hex.
|
||||
|
||||
$DATA_INV(ndatabytes)$ :
|
||||
Writes in the output fila a ndatabytes amount of bytes
|
||||
from the input bitfile inverting the order, expressed
|
||||
in hex.
|
||||
|
||||
$FILL(VAL,TIMES)$ :
|
||||
Writes TIMES times the value VAL expressed in hex in the
|
||||
output file.
|
||||
|
||||
$REWIND$ :
|
||||
Rewinds the bitfile to the first stream byte so it can be used in a
|
||||
new block.
|
||||
|
||||
$CUTLINES(n):
|
||||
Using 0 stops cutting long lines, 1 starts cutting again.
|
||||
Other values: reserved.
|
||||
|
@ -0,0 +1,241 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2006-2007 Salvador E. Tropea <salvador en inti gov ar>
|
||||
Copyright (c) 2005-2007 Instituto Nacional de Tecnología Industrial
|
||||
|
||||
Comandos y bloques:
|
||||
Los archivos de template tienen comandos de bloque y
|
||||
comandos de operacion. Los comandos de bloque comienzan con
|
||||
dos signos menos "--" y los de operacion van encerrados entre
|
||||
signos pesos "$". Los comandos de bloque indican la ejecucion
|
||||
de un bloque y el fin de bloque debe ser indicado con la
|
||||
instruccion "--END".
|
||||
|
||||
|
||||
Variables internas:
|
||||
Se proporcionan las siguientes variables internas que pueden
|
||||
ser utilizadas invocando su nombre entre signos pesos "$" o
|
||||
modificados si ademas se les asigna un valor entre
|
||||
parentesis. Ej. $ADDRESS(0x0000)$ le asignara a esta variable
|
||||
el valor 0x0000.
|
||||
|
||||
$ADDRESS$ :
|
||||
Acumulador que es util al momento de incrementar la direccion de una
|
||||
memoria, por ejemplo.
|
||||
|
||||
$STEP$ :
|
||||
Valor con el cual se incrementara la variable $ADDRESS$.
|
||||
|
||||
$SBYTES$ :
|
||||
Cantidad de bytes que posee el bitstream del bitfile.
|
||||
|
||||
$SBITES$ :
|
||||
Cantidad de bits que posee el bitstream del bitfile.
|
||||
|
||||
$MSIZE$ :
|
||||
Obtenido del campo msize de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Expresa la ultima posicion de memoria de un dispositivo con memoria.
|
||||
|
||||
$ID$ :
|
||||
Obtenido del campo id de la definicion del dispositivo en el archivo
|
||||
DEVICES.
|
||||
Expresa el IDCODE del dispositivo actual.
|
||||
|
||||
$IDMASK$ :
|
||||
Obtenido del campo idmask de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Expresa la mascara que se usara en la comprobacion del IDCODE.
|
||||
|
||||
$BSIZE$ :
|
||||
Obtenido del campo BSIZE de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Es el "block size" (cantidad de bits) a transferir expresando
|
||||
en bits.
|
||||
Nota: El valor BSIZE y el valor STEP no son cosas separadas.
|
||||
BSIZE es el tamaño en bits de la cache que tiene el dispositivo
|
||||
para almacenar los datos antes de transferirlos a la flash.
|
||||
Cada dirección de memoria direcciona una cantidad de bits (64
|
||||
o 128 es lo común), el STEP es el número de posiciones de memoria
|
||||
que entran en la cache, luego BSIZE=STEP*bits_por_dirección.
|
||||
Esto es en las XC18V: 32*64=2048 o 32*128=4096.
|
||||
|
||||
$BSIZEB$ :
|
||||
Obtenido del campo BSIZE de la definicion del dispositivo en el
|
||||
archivo DEVICES.
|
||||
Es el "block size" (cantidad de bits) a transferir expresando
|
||||
en bytes.
|
||||
|
||||
$BSIZEB2$ :
|
||||
$BSIZEB$ multiplicado por 2.
|
||||
|
||||
Comandos de bloque:
|
||||
|
||||
|
||||
--LITERAL START :
|
||||
Indica que se debe copiar en el archivo de salida el contenido
|
||||
de este bloque y hasta el final del mismo tal y como esta.
|
||||
Si se encuentra un comando de operacion entre medio este es
|
||||
ejecutado.
|
||||
|
||||
--REPEAT START :
|
||||
Indica que se repetira de principio a fin el contenido de este
|
||||
bloque mientras que haya informacion que leer en el bitfile
|
||||
de entrada.
|
||||
Este comando de bloque debe tener en su interior algun comando
|
||||
de operacion que lea informacion del bitfile de entrada, si no
|
||||
este nunca llegara a su fin y el programa se quedara
|
||||
repitiendo el bloque hasta agotar el espacio en disco.
|
||||
Con cada iteracion del bloque se incrementa la variable
|
||||
$ADDRESS$ en $STEP$.
|
||||
|
||||
--REPEAT UNTIL valor :
|
||||
Indica que se repetira de principio a fin el contenido de
|
||||
este bloque hasta que la variable $ADDRESS$ tome el valor
|
||||
pasado como parametro. Con cada iteracion del bloque se
|
||||
incrementara la variable $ADDRESS$ en $STEP$.
|
||||
El valor pasado como parametro debe ser multiplo de
|
||||
$STEP$, si no la condicion de salida del bloque nunca se
|
||||
conseguira y el programa se quedara repitiendo el bloque
|
||||
hasta agotar el espacio en disco.
|
||||
En lugar de valor se puede utilizar una variable:
|
||||
Ej.: --REPEAT UNTIL MSIZE
|
||||
|
||||
|
||||
--END :
|
||||
Indica el final de un bloque LITERAL, REPEAT o REPEAT UNTIL.
|
||||
|
||||
|
||||
Comandos de operacion:
|
||||
Los comandos de operacion pueden recibir como argumento
|
||||
el nombre de una variable en lugar de una constante:
|
||||
Ej.: $FILL(0xFF,BSIZE)$
|
||||
|
||||
$DATA(ndatabytes)$ :
|
||||
Escribe en el archivo de salida una cantidad ndatabytes de
|
||||
bytes del bitfile de entrada expresados en hexadecimal.
|
||||
|
||||
$DATA_INV(ndatabytes)$ :
|
||||
Escribe en el archivo de salida una cantidad ndatabytes
|
||||
de bytes del bitfile de entrada, invirtiendo el orden
|
||||
de los bits del bloque, expresados en hexadecimal.
|
||||
|
||||
$FILL(VAL,TIMES)$ :
|
||||
Escribe TIMES veces el valor VAL expresado en hexadecimal en
|
||||
el archivo de salida.
|
||||
|
||||
$REWIND$ :
|
||||
Vuelve a poner el archivo de bits en la posicion del primer byte del
|
||||
stream para poder realizar otra pasada completa con un comando de
|
||||
bloque.
|
||||
|
||||
$CUTLINES(n):
|
||||
Con 0 deja de cortar las líneas largas, con 1 vuelve a cortarlas.
|
||||
Otros valores: reservados.
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Como crear un template para una FPGA:
|
||||
-------------------------------------
|
||||
|
||||
Autor: Salvador E. Tropea
|
||||
|
||||
A) Crear un .SVF válido para esa FPGA:
|
||||
|
||||
1) Obtener un .bit para la FPGA en cuestión.
|
||||
2) Abrir el impact:
|
||||
$ . /usr/local/ISEWb/settings.sh
|
||||
$ impact
|
||||
3) Elegir "I want to (*) Create a new project", Ok. (Darle un nombre si se
|
||||
quiere).
|
||||
4) Elegir "(*) Prepare a boundary-scan file [SVF]", Finish.
|
||||
5) Elegir un nombre para el SVF.
|
||||
6) Elegir el .bit.
|
||||
7) Presionar el botón derecho sobre la FPGA y elegir "Program", Ok.
|
||||
8) Salir del impact
|
||||
|
||||
Automáticamente es:
|
||||
|
||||
setPreference -pref AutoSignature:FALSE
|
||||
setPreference -pref KeepSVF:FALSE
|
||||
setPreference -pref ConcurrentMode:FALSE
|
||||
setPreference -pref UseHighz:FALSE
|
||||
setPreference -pref UserLevel:NOVICE
|
||||
setPreference -pref svfUseTime:FALSE
|
||||
setMode -bs
|
||||
setMode -bs
|
||||
setCable -port svf -file "salida.svf"
|
||||
addDevice -p 1 -file "archivo.bit"
|
||||
Program -p 1 -s -defaultVersion 0
|
||||
|
||||
B) Crear un nuevo template (ej: alg_Virtex_4.svft)
|
||||
|
||||
1) Abrir un template que ya exista para usarlo de guía.
|
||||
2) Borrar "FREQUENCY 1E6 HZ;"
|
||||
3) Reemplazar: $ID$ y $IDMASK$ en la parte que dice "Loading device with
|
||||
'idcode' instruction.". (f167c093)
|
||||
4) Reemplazar la megalínea del bitstream por:
|
||||
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
|
||||
|
||||
C) Probar su funcionamiento
|
||||
|
||||
1) Colocar el nuevo template en /usr/share/bit2svf/
|
||||
2) Editar /usr/share/bit2svf/DEVICES agregando el ID de la FPGA y el algoritmo
|
||||
a usar:
|
||||
|
||||
// Virtex 4 family (10 bits IR)
|
||||
XC4VLX25, f167c093, 0fffffff, alg_Virtex_4, VOID, 0l
|
||||
|
||||
3) Probar el template:
|
||||
|
||||
$ bit2svf display_test_lx25.bit v4-b2s.svf XC4VLX25
|
||||
|
||||
Esto genera v4-b2s.svf que debería ser practicamente idéntico al generado por
|
||||
impact.
|
||||
Nota: En este caso observé que el impact agrega 32 bits en 0 extra al
|
||||
bitstream. Esto no parece ser indispensable y sospecho que sirve para
|
||||
"limpiar/vaciar" la cadena.
|
||||
4) Si todo fue OK se puede probar con el dispositivo:
|
||||
|
||||
$ jbit display_test_lx25.bit XC4VLX25
|
||||
|
||||
|
||||
-------------------------------------------------------------------------------
|
||||
|
||||
Como crear un template para una PROM:
|
||||
-------------------------------------
|
||||
|
||||
Autor: Salvador E. Tropea
|
||||
|
||||
A) Crear un archivo de PROM válido.
|
||||
|
||||
1) Obtener un .bit para la FPGA en cuestión.
|
||||
2) Abrir el impact:
|
||||
$ . /usr/local/ISEWb/settings.sh
|
||||
$ impact
|
||||
3) Elegir "I want to (*) Prepare a ROM file", Ok. (Darle un nombre si se
|
||||
quiere).
|
||||
4) Elegir "I want to target a (*) Xilinx PROM", "PROM File name" darle un
|
||||
nombre. Next. (Ojo con el path).
|
||||
5) Elegir la PROM y Add, luego Next.
|
||||
6) Agregar el .bit
|
||||
7) Elegir "Generate File ..." dentro de las acciones disponibles (la única).
|
||||
8) Esto genera un .MCS con el contenido para la PROM.
|
||||
|
||||
B) Crear un .SVF válido para esa PROM. Esto es similar a la FPGA, la única
|
||||
diferencia es que le especificamos el .MCS en lugar de un .bit. En este caso
|
||||
nos preguntará cual es el dispositivo haciendo un guess de cual se trata. Esto
|
||||
es porque el .mcs es un bitstream crudo y no dice para que dispositivo se
|
||||
hizo.
|
||||
Durante este proceso se pueden elegir opciones como si la PROM se conecta en
|
||||
paralelo y si se incluye verificación. Además hay que elegir que primero la
|
||||
borre.
|
||||
|
||||
B) Crear un nuevo template o usar uno ya hecho. Esto es como con la FPGA.
|
||||
|
||||
C) Probar su funcionamiento. Esto es más o menos lo mismo que con la FPGA. La
|
||||
principal diferencia con las PROMs es que acá es necesario configurar su tamaño
|
||||
y el tamaño de la caché o página donde se guardarán temporalmente los datos:
|
||||
|
||||
// XCFxxP memories
|
||||
XCF08P , f5057093, 0fffffff, alg_XCFP ,8192 , 0x100000
|
||||
|
@ -0,0 +1,192 @@
|
||||
//Info: Sample template for programming XILINX XC18V01 PROMS
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (fe) SMASK (ff) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (03) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
// Loading device with 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI (0001) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with 'ferase' instruction.
|
||||
SIR 8 TDI (ec) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 15000000 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
--END
|
||||
|
||||
$ADDRESS(0x0000)$
|
||||
$STEP(0x0020)$
|
||||
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'fdata0' instruction.
|
||||
SIR 8 TDI (ed) ;
|
||||
SDR $BSIZE$ TDI ($DATA_INV(BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fpgm' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (ea) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 14000 TCK;
|
||||
--END
|
||||
|
||||
--LITERAL START
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI (0001) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with 'serase' instruction.
|
||||
SIR 8 TDI (0a) ;
|
||||
RUNTEST 37000 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) ;
|
||||
--END
|
||||
|
||||
$REWIND$
|
||||
$ADDRESS(0x0000)$
|
||||
$STEP(0x0040)$
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fvfy0' instruction.
|
||||
SIR 8 TDI (ef) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR $BSIZE2$ TDI ($FILL(0x00,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($DATA_INV(BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
|
||||
--END
|
||||
|
||||
|
||||
--REPEAT UNTIL MSIZE
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fvfy0' instruction.
|
||||
SIR 8 TDI (ef) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR $BSIZE2$ TDI ($FILL(0xFF,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($FILL(0xFF,BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
|
||||
--END
|
||||
|
||||
--LITERAL START
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) ;
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) TDO (00) MASK (00) ;
|
||||
SDR 16 TDI (4000) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fdata3' instruction.
|
||||
SIR 8 TDI (f3) TDO (00) ;
|
||||
SDR 6 TDI (1f) SMASK (3f) TDO (00) MASK (00) ;
|
||||
// Loading device with a 'fpgm' instruction.
|
||||
SIR 8 TDI (ea) TDO (00) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 14000 TCK;
|
||||
// Loading device with a 'fvfy3' instruction.
|
||||
SIR 8 TDI (e2) TDO (00) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR 6 TDI (1f) TDO (1f) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
// Loading device with a 'config' instruction.
|
||||
SIR 8 TDI (ee) TDO (00) ;
|
||||
RUNTEST 50 TCK;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 8 TDI (ff) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 8 TDI (ff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,83 @@
|
||||
//Info: Sample template for programming XILINX Spartan 3 FPGA
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 6 TDI (09) SMASK (3f) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 6 TDI (09) ;
|
||||
SDR 32 TDI (00000000) TDO ($ID$) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 6 TDI (3f) ;
|
||||
// Loading device with a `jprogram` instruction.
|
||||
SIR 6 TDI (0b) ;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a `bypass` instruction.
|
||||
SIR 6 TDI (3f) ;
|
||||
RUNTEST 14000 TCK;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 6 TDI (05) ;
|
||||
SDR 192 TDI (0000000000000000e00000008001000c66aa9955ffffffff) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffff) ;
|
||||
// Loading device with a `jshutdown` instruction.
|
||||
SIR 6 TDI (0d) ;
|
||||
RUNTEST 12 TCK;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 6 TDI (05) ;
|
||||
SDR 64 TDI (0000000000000000) SMASK (ffffffffffffffff) ;
|
||||
SIR 6 TDI (05) TDO (00) MASK (00) ;
|
||||
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 6 TDI (0c) ;
|
||||
RUNTEST 12 TCK;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 6 TDI (3f) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 6 TDI (3f) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 6 TDI (0c) ;
|
||||
RUNTEST 12 TCK;
|
||||
//Checking done pin status.
|
||||
//Loading device with 'Bypass' instruction.
|
||||
SIR 6 TDI (3f) TDO (21) MASK (20) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 6 TDI (3f) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,95 @@
|
||||
//Info: Sample template for programming XILINX SpartanII FPGA
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 5 TDI (09) SMASK (1f) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 5 TDI (09) ;
|
||||
SDR 32 TDI (00000000) TDO ($ID$) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 5 TDI (1f) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 5 TDI (05) ;
|
||||
SDR 288 TDI (00000000e00000008001000ca00000008001000cbcfd05008004800c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 5 TDI (0c) ;
|
||||
SDR 13 TDI (0000) SMASK (1fff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 5 TDI (05) ;
|
||||
SDR 352 TDI (00000000e00000008001000ca00000008001000cfffc05008004800c100000008001000c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 5 TDI (0c) ;
|
||||
SDR 13 TDI (0000) SMASK (1fff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 5 TDI (05) ;
|
||||
SDR 288 TDI (00000000e00000008001000ca00000008001000cb4fd05008004800c66aa995500000000) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 5 TDI (0c) ;
|
||||
SDR 13 TDI (0000) SMASK (1fff) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 5 TDI (05) ;
|
||||
|
||||
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
|
||||
|
||||
STATE RESET;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 5 TDI (0c) ;
|
||||
SDR 13 TDI (0000) SMASK (1fff) ;
|
||||
STATE RESET;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 5 TDI (1f) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 5 TDI (1f) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
STATE RESET;
|
||||
//Checking done pin status.
|
||||
//Loading device with 'Bypass' instruction.
|
||||
SIR 5 TDI (1f) TDO (05) MASK (04) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 5 TDI (1f) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,111 @@
|
||||
//Info: Sample template for programming XILINX Virtex 4 FPGA
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 10 TDI (03c9) SMASK (03ff) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 10 TDI (03c9) ;
|
||||
SDR 32 TDI (00000000) TDO ($ID$) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 10 TDI (03ff) ;
|
||||
// Loading device with a `ISC_ENABLE` instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 10 TDI (03d0) ;
|
||||
SDR 5 TDI (15) SMASK (1f) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 12 TCK;
|
||||
// Loading device with a `ISC_PROGRAM_SECURITY` instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 10 TDI (03d2) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 9 TCK;
|
||||
// Loading device with a `ISC_DISABLE` instruction.
|
||||
SIR 10 TDI (03d7) ;
|
||||
RUNTEST 12 TCK;
|
||||
// Loading device with a `jprogram` instruction.
|
||||
SIR 10 TDI (03cb) ;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a `bypass` instruction.
|
||||
SIR 10 TDI (03ff) ;
|
||||
RUNTEST 21000 TCK;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 10 TDI (03c5) ;
|
||||
RUNTEST 100000 TCK;
|
||||
// Check init_complete in ircapture.
|
||||
//Loading device with 'Bypass' instruction.
|
||||
SIR 10 TDI (03ff) TDO (0010) MASK (0010) ;
|
||||
// Loading device with a `jprogram` instruction.
|
||||
SIR 10 TDI (03cb) ;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a `bypass` instruction.
|
||||
SIR 10 TDI (03ff) ;
|
||||
RUNTEST 21000 TCK;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 10 TDI (03c5) ;
|
||||
RUNTEST 100000 TCK;
|
||||
// Check init_complete in ircapture.
|
||||
//Loading device with 'Bypass' instruction.
|
||||
SIR 10 TDI (03ff) TDO (0010) ;
|
||||
STATE RESET;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 10 TDI (03c5) TDO (0000) MASK (0000) ;
|
||||
SDR $SBITS$ TDI ($DATA_INV(-1)$) SMASK ($FILL(0xFF,-1)$);
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 10 TDI (03cc) ;
|
||||
RUNTEST 12 TCK;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 10 TDI (03ff) ;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 10 TDI (03ff) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
// Loading device with a `jstart` instruction.
|
||||
SIR 10 TDI (03cc) ;
|
||||
RUNTEST 12 TCK;
|
||||
// Loading device with a `cfg_in` instruction.
|
||||
SIR 10 TDI (03c5) ;
|
||||
SDR 224 TDI (0000000000000000200000008001000c0000000466aa9955ffffffff) SMASK (ffffffffffffffffffffffffffffffffffffffffffffffffffffffff) ;
|
||||
//Checking done pin status.
|
||||
//Loading device with 'Bypass' instruction.
|
||||
SIR 10 TDI (03ff) TDO (0021) MASK (0020) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 10 TDI (03ff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,190 @@
|
||||
//Info: Sample template for programming XILINX XCFxx PROMS
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (fe) SMASK (ff) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (07) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
// Loading device with 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI (0001) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with 'ferase' instruction.
|
||||
SIR 8 TDI (ec) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 15000000 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
--END
|
||||
|
||||
$ADDRESS(0x0000)$
|
||||
$STEP(0x0020)$
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'fdata0' instruction.
|
||||
SIR 8 TDI (ed) ;
|
||||
SDR $BSIZE$ TDI ($DATA_INV(BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fpgm' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (ea) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 14000 TCK;
|
||||
--END
|
||||
|
||||
--LITERAL START
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI (0001) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with 'serase' instruction.
|
||||
SIR 8 TDI (0a) ;
|
||||
RUNTEST 37000 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) ;
|
||||
--END
|
||||
|
||||
$REWIND$
|
||||
$ADDRESS(0x0000)$
|
||||
$STEP(0x0040)$
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fvfy0' instruction.
|
||||
SIR 8 TDI (ef) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR $BSIZE2$ TDI ($FILL(0x00,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($DATA_INV(BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
|
||||
--END
|
||||
|
||||
--REPEAT UNTIL MSIZE
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) ;
|
||||
SDR 16 TDI ($ADDRESS$) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fvfy0' instruction.
|
||||
SIR 8 TDI (ef) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR $BSIZE2$ TDI ($FILL(0xFF,BSIZEB2)$) SMASK ($FILL(0xFF,BSIZEB2)$) TDO ($FILL(0xFF,BSIZEB2)$) MASK ($FILL(0xFF,BSIZEB2)$) ;
|
||||
--END
|
||||
|
||||
--LITERAL START
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) ;
|
||||
// Loading device with a 'faddr' instruction.
|
||||
SIR 8 TDI (eb) TDO (00) MASK (00) ;
|
||||
SDR 16 TDI (8000) SMASK (ffff) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 1 TCK;
|
||||
// Loading device with a 'fdata3' instruction.
|
||||
SIR 8 TDI (f3) TDO (00) ;
|
||||
SDR 3 TDI (07) SMASK (07) TDO (00) MASK (00) ;
|
||||
// Loading device with a 'fpgm' instruction.
|
||||
SIR 8 TDI (ea) TDO (00) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 14000 TCK;
|
||||
// Loading device with a 'fvfy3' instruction.
|
||||
SIR 8 TDI (e2) TDO (00) ;
|
||||
RUNTEST 1 TCK;
|
||||
RUNTEST 50 TCK;
|
||||
SDR 3 TDI (07) TDO (07) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
SDR 6 TDI (34) SMASK (3f) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 8 TDI (f0) ;
|
||||
RUNTEST 110000 TCK;
|
||||
// Loading device with a 'config' instruction.
|
||||
SIR 8 TDI (ee) TDO (00) ;
|
||||
RUNTEST 50 TCK;
|
||||
//Loading device with 'bypass' instruction.
|
||||
SIR 8 TDI (ff) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 8 TDI (ff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,208 @@
|
||||
//Info: Sample template for programming XILINX XCFxxP PROMS
|
||||
//Info: Created with output from Impact
|
||||
|
||||
--LITERAL START
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) SMASK (ffff) ;
|
||||
SDR 8 TDI (03) SMASK (ff) ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 16 TDI (00fe) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO ($ID$) MASK ($IDMASK$) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (d0) SMASK (ff) ;
|
||||
// Loading device with a 'XSC_UNLOCK' instruction.
|
||||
SIR 16 TDI (aa55) ;
|
||||
SDR 24 TDI (00003f) SMASK (ffffff) ;
|
||||
// Loading device witha 'ISC_ERASE' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 16 TDI (00ec) ;
|
||||
SDR 24 TDI (00003f) ;
|
||||
ENDIR IDLE;
|
||||
RUNTEST 140000000 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 16 TDI (00f0) ;
|
||||
RUNTEST 50 TCK;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (d0) SMASK (ff) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) ;
|
||||
// Loading device with 'XSC_DATA_BTC' instruction.
|
||||
SIR 16 TDI (00f2) ;
|
||||
SDR 32 TDI (ffffffe0) SMASK (ffffffff) TDO (00000000) MASK (00000000) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 120 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
STATE RESET;
|
||||
// Loading devices with 'ispen' or 'bypass' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (d0) SMASK (ff) ;
|
||||
--END
|
||||
|
||||
$CUTLINES(0)$
|
||||
|
||||
--LITERAL START
|
||||
// Loading device with a 'ISC_DATA_SHIFT' instruction.
|
||||
SIR 16 TDI (00ed) ;
|
||||
SDR 256 TDI ($DATA_INV(32)$) SMASK ($FILL(0xFF,32)$) ;
|
||||
// Loading device with a 'ISC_ADDRESS_SHIFT' instruction.
|
||||
SIR 16 TDI (00eb) ;
|
||||
SDR 24 TDI (000000) SMASK (ffffff) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 1000 TCK;
|
||||
// Loading device with a 'ISC_DATA_SHIFT' instruction.
|
||||
SIR 16 TDI (00ed) ;
|
||||
SDR 256 TDI ($DATA_INV(32)$) SMASK ($FILL(0xFF,32)$) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 1000 TCK;
|
||||
--END
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'ISC_DATA_SHIFT' instruction.
|
||||
SIR 16 TDI (00ed) ;
|
||||
SDR 256 TDI ($DATA_INV(32)$) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 1000 TCK;
|
||||
--END
|
||||
|
||||
$CUTLINES(1)$
|
||||
|
||||
--LITERAL START
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) SMASK (ff) ;
|
||||
// Loading device with a 'XSC_DATA_SUCR' instruction.
|
||||
SIR 16 TDI (000e) ;
|
||||
SDR 16 TDI (fffc) SMASK (ffff) TDO (0000) MASK (0000) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 60 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) SMASK (ff) ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) ;
|
||||
// Loading device witha 'XSC_DATA_CCB' instruction.
|
||||
SIR 16 TDI (000c) ;
|
||||
SDR 16 TDI (fff9) SMASK (ffff) TDO (0000) MASK (0000) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 60 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 16 TDI (00f0) ;
|
||||
RUNTEST 50 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) SMASK (ff) ;
|
||||
// Loading device with 'XSC_DATA_DONE' instruction.
|
||||
SIR 16 TDI (0009) ;
|
||||
SDR 8 TDI (ce) TDO (00) MASK (00) ;
|
||||
// Loading device with a 'ISC_PROGRAM' instruction.
|
||||
SIR 16 TDI (00ea) ;
|
||||
RUNTEST 60 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) ;
|
||||
--END
|
||||
|
||||
$REWIND$
|
||||
$ADDRESS(0x0000)$
|
||||
$STEP(0x0400)$
|
||||
|
||||
--REPEAT START
|
||||
// Loading device with a 'ISC_ADDRESS_SHIFT' instruction.
|
||||
SIR 16 TDI (00eb) ;
|
||||
SDR 24 TDI ($ADDRESS$) SMASK (ffffff) ;
|
||||
// Loading device with a 'XSC_READ' instruction.
|
||||
SIR 16 TDI (00ef) ;
|
||||
RUNTEST 15 TCK;
|
||||
SDR $BSIZE$ TDI ($FILL(0x00,BSIZEB)$) SMASK ($FILL(0xFF,BSIZEB)$) TDO ($DATA_INV(BSIZEB)$) MASK ($FILL(0xFF,BSIZEB)$) ;
|
||||
--END
|
||||
|
||||
--LITERAL START
|
||||
// Check Device status.
|
||||
SIR 16 TDI (00e3) ;
|
||||
SDR 8 TDI (00) SMASK (ff) TDO (36) MASK (7f) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 16 TDI (00f0) ;
|
||||
RUNTEST 50 TCK;
|
||||
//Loading device with 'ispen' instruction.
|
||||
SIR 16 TDI (00e8) ;
|
||||
SDR 8 TDI (03) ;
|
||||
//Loading device with 'conld' instruction.
|
||||
SIR 16 TDI (00f0) ;
|
||||
RUNTEST 50 TCK;
|
||||
// Loading device with a 'config' instruction.
|
||||
SIR 16 TDI (00ee) TDO (0000) MASK (0000) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 16 TDI (ffff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
||||
--END
|
@ -0,0 +1,63 @@
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna <jpborgna en inti gov ar>
|
||||
Copyright (c) 2005 Instituto Nacional de Tecnología Industrial
|
||||
Copyright (c) 2001, 2002 by David Sullins
|
||||
Licese: GPL por bitfile.c
|
||||
|
||||
|
||||
jbit:
|
||||
-----
|
||||
This script is a shortcut for programming a device using the GNU JTAG
|
||||
program with a .bit file. It generates and deletes the intermediate SVF
|
||||
file. It can read a personal config, refer to jbitrc_sample.txt.
|
||||
|
||||
Sample:
|
||||
|
||||
bit2svf$ ./jbit ejemplo_prom.bit XC18V01
|
||||
|
||||
jbit - bit2svf/jtag short cut - v1.0
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna/INTI
|
||||
|
||||
Creando archivo temporario /tmp/bit2svf.tmp
|
||||
|
||||
bit2svf - SVF file generator - v1.0
|
||||
Copyright (c) 2005 Juan Pablo D. Borgna/INTI
|
||||
|
||||
|
||||
Bit file created on 2004/08/25 at 13:43:18.
|
||||
Created from file ejemplo.ncd for Xilinx part 2s100pq208.
|
||||
Bitstream length is 97652 bytes.
|
||||
|
||||
Process finsished sucefully.
|
||||
Creado ok
|
||||
Invocando /home/jpablo/usr/bin/jtag
|
||||
Initializing Xilinx DLC5 JTAG Parallel Cable III on ppdev port /dev/parport0
|
||||
IR length: 8
|
||||
Chain length: 1
|
||||
Device Id: 00000101000000100100000010010011
|
||||
Manufacturer: Xilinx
|
||||
Part: XC18V01-SO20
|
||||
Stepping: 1
|
||||
Filename: /home/jpablo/usr//share/jtag/xilinx/xc18v01-so20/xc18v01-so20
|
||||
Warning svf: checking of TDO not supported for SIR.
|
||||
This message is only displayed once.
|
||||
Borrando temporarios..
|
||||
Que tenga un buen dia :-)
|
||||
|
||||
|
||||
|
||||
bit2svf:
|
||||
--------
|
||||
This program generates a SVF file wich using the program JTAG it is
|
||||
possible to program a FPGA or PROM.
|
||||
|
||||
Sample:
|
||||
|
||||
bit2svf$ ./bit2svf ejemplo_prom.bit ejemplo_prom.svf XC18V01
|
||||
|
||||
Bit file created on 2004/08/25 at 13:43:18.
|
||||
Created from file ejemplo.ncd for Xilinx part 2s100pq208.
|
||||
Bitstream length is 97652 bytes.
|
||||
|
||||
Process finsished sucefully.
|
||||
|
||||
|
@ -0,0 +1,18 @@
|
||||
|
||||
Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
|
||||
Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
@ -0,0 +1,83 @@
|
||||
# Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
#
|
||||
# Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
#AR = ppc_6xx-ar
|
||||
#RANLIB = ppc_6xx-ranlib
|
||||
#CC = ppc_6xx-gcc
|
||||
#CFLAGS += -DXSVFTOOL_RLMS_VLINE
|
||||
|
||||
AR = ar
|
||||
RANLIB = ranlib
|
||||
CC = gcc
|
||||
|
||||
CFLAGS += -Wall -Os -ggdb -MD
|
||||
#CFLAGS += -Wextra -Wno-unused-parameter -Werror
|
||||
|
||||
help:
|
||||
@echo ""
|
||||
@echo "Usage:"
|
||||
@echo ""
|
||||
@echo " $(MAKE) libxsvf.a"
|
||||
@echo " .... build only the library"
|
||||
@echo ""
|
||||
@echo " $(MAKE) xsvftool-gpio"
|
||||
@echo " .... build the library and xsvftool-gpio"
|
||||
@echo ""
|
||||
@echo " $(MAKE) xsvftool-ft232h"
|
||||
@echo " .... build the library and xsvftool-ft232h"
|
||||
@echo ""
|
||||
@echo " $(MAKE) xsvftool-xpcu"
|
||||
@echo " .... build the library and xsvftool-xpcu"
|
||||
@echo ""
|
||||
@echo " $(MAKE) all"
|
||||
@echo " .... build the library and all examples"
|
||||
@echo ""
|
||||
@echo " $(MAKE) install"
|
||||
@echo " .... install everything in /usr/local/"
|
||||
@echo ""
|
||||
|
||||
all: libxsvf.a xsvftool-gpio xsvftool-ft232h xsvftool-xpcu
|
||||
|
||||
install: all
|
||||
install -Dt /usr/local/bin/ xsvftool-gpio xsvftool-ft232h xsvftool-xpcu
|
||||
install -Dt /usr/local/include/ -m 644 libxsvf.h
|
||||
install -Dt /usr/local/lib/ -m 644 libxsvf.a
|
||||
|
||||
libxsvf.a: tap.o statename.o memname.o svf.o xsvf.o scan.o play.o
|
||||
rm -f libxsvf.a
|
||||
$(AR) qc $@ $^
|
||||
$(RANLIB) $@
|
||||
|
||||
xsvftool-gpio: libxsvf.a xsvftool-gpio.o
|
||||
|
||||
xsvftool-ft232h: LDLIBS+=-lftdi -lm
|
||||
xsvftool-ft232h: LDFLAGS+=-pthread
|
||||
xsvftool-ft232h.o: CFLAGS+=-pthread
|
||||
xsvftool-ft232h: libxsvf.a xsvftool-ft232h.o
|
||||
|
||||
xsvftool-xpcu: libxsvf.a xsvftool-xpcu.src/*.c xsvftool-xpcu.src/*.h \
|
||||
xsvftool-xpcu.src/*.v xsvftool-xpcu.src/*.ucf
|
||||
$(MAKE) -C xsvftool-xpcu.src
|
||||
cp xsvftool-xpcu.src/xsvftool-xpcu xsvftool-xpcu
|
||||
|
||||
clean:
|
||||
$(MAKE) -C xsvftool-xpcu.src clean
|
||||
rm -f xsvftool-gpio xsvftool-ft232h xsvftool-xpcu
|
||||
rm -f libxsvf.a *.o *.d
|
||||
|
||||
-include *.d
|
||||
|
@ -0,0 +1,365 @@
|
||||
|
||||
Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
******************************************************************
|
||||
|
||||
Please check the subversion repository for updates:
|
||||
http://svn.clifford.at/libxsvf/trunk/
|
||||
|
||||
You also might want to have a look at the project homepage:
|
||||
http://www.clifford.at/libxsvf/
|
||||
|
||||
In papers and reports, please refer to Lib(X)SVF as follows: "Clifford Wolf,
|
||||
Lib(X)SVF: A library for implementing SVF and XSVF JTAG players.
|
||||
http://www.clifford.at/libxsvf/", e.g. using the following BibTeX code:
|
||||
|
||||
@MISC{LibXSVF,
|
||||
author = {Clifford Wolf},
|
||||
title = {Lib(X)SVF: A library for implementing SVF and XSVF JTAG players},
|
||||
howpublished = "\url{http://www.clifford.at/libxsvf/}"
|
||||
}
|
||||
|
||||
Please send bug reports and fixes to <clifford@clifford.at>.
|
||||
|
||||
|
||||
Copyright and Disclaimer
|
||||
------------------------
|
||||
|
||||
Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
|
||||
Permission to use, copy, modify, and/or distribute this software for any
|
||||
purpose with or without fee is hereby granted, provided that the above
|
||||
copyright notice and this permission notice appear in all copies.
|
||||
|
||||
THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
|
||||
|
||||
Introduction
|
||||
------------
|
||||
|
||||
JTAG (IEEE 1149.1, aka "Boundary Scan", [1], [2]) is a standard IC
|
||||
testing, debugging and programming port.
|
||||
|
||||
SVF (Serial Vector Format, [3], [4]) is a file format for storing the
|
||||
patterns that should be sent to the JTAG interface, as well as the
|
||||
expected response. It is used as an exchange format between programms
|
||||
that generate the JTAG input/output patterns and devices that can
|
||||
physically talk to a JTAG interface.
|
||||
|
||||
XSVF (Xilinx Serial Vector Format, [5]) is a binary variant of the SVF
|
||||
file format, optimized but not limited to programming Xilinx FPGA and
|
||||
CPLD devices.
|
||||
|
||||
Often one wants to use an embedded host processor or microcontroller
|
||||
to access the JTAG interface on an embedded device instead of using
|
||||
an external JTAG probe. This library can be used to implement such a
|
||||
solution. In addition to playing SVF and XSVF files this library is
|
||||
also capable of scanning the devices in the JTAG chain.
|
||||
|
||||
Lib(X)SVF is free software licensed under the ISC license (a licence
|
||||
that is functionally equivalent to the 2-clause BSD license).
|
||||
|
||||
[1] http://en.wikipedia.org/wiki/JTAG
|
||||
[2] http://www.fpga4fun.com/JTAG.html
|
||||
[3] http://en.wikipedia.org/wiki/Serial_Vector_Format
|
||||
[4] http://www.asset-intertech.com/support/svf.pdf
|
||||
[5] http://www.xilinx.com/bvdocs/appnotes/xapp503.pdf
|
||||
|
||||
|
||||
Limitations and non-standard extensions
|
||||
---------------------------------------
|
||||
|
||||
The SVF commands 'PIO' and 'PIOMAP' are unsupported. Any use of this
|
||||
commands in an SVF input file is reported as error.
|
||||
|
||||
The SVF 'RUNTEST' command is implemented in a limited manner: The
|
||||
'MAXIMUM' time parameter is ignored. Combining 'SCK' with a time
|
||||
parameter results in first executing the specified number of clock
|
||||
pulses followed by a delay of the specified timespan, instead of
|
||||
performing the clock cycles and the delay in parallel.
|
||||
|
||||
The SVF commands 'HDR', 'HIR', 'SDR', 'SIR', 'TDR' and 'TIR' support
|
||||
an additional non-standard 'RMASK' parameter. This is a mask for the
|
||||
TDO bits, simmilar to the standard 'MASK' parameter. All TDO bits
|
||||
marked using a '1' in 'RMASK' are reported back to the host application
|
||||
using the the ret_tdo() callback function. This can be used to read
|
||||
data (such as device serial numbers) using JTAG by providing SVF
|
||||
templates.
|
||||
|
||||
|
||||
Using and Porting
|
||||
-----------------
|
||||
|
||||
The library itself is written in plain C and does not depend on any
|
||||
library calls or headers, not even from the standard C library. So it
|
||||
can be ported easily even to restricted environment, such as embedded
|
||||
systems.
|
||||
|
||||
So far the libary has only been tested on 32 bit hosts. Using it on
|
||||
16 bit processors might not be possible without performing some minor
|
||||
fixes in the code.
|
||||
|
||||
The program 'xsvftool-gpio' (see xsvftool-gpio.c) is a good example
|
||||
of how to use the library. Please have a look at this program first.
|
||||
|
||||
Note: See 'Host accessor macros' below for an alternative way of
|
||||
integrating libxsvf into your host environment.
|
||||
|
||||
The host application must provide an libxsvf_host struct as defined
|
||||
in libxsvf.h. This struct contains some function pointers that must
|
||||
be set to implementations of the following functions:
|
||||
|
||||
int setup(struct libxsvf_host *h);
|
||||
|
||||
This function is called by libxsvf to setup/initialize the
|
||||
jtag interface. It is executed before any other libxsvf_host
|
||||
callback function is called.
|
||||
|
||||
This function should return 0 when setting up the jtag
|
||||
interface went fine and -1 on an error.
|
||||
|
||||
int shutdown(struct libxsvf_host *h);
|
||||
|
||||
This function is called by libxsvf to shutdown the jtag
|
||||
interface. No other libxsvf_host callback function will
|
||||
be called after this function has been executed.
|
||||
|
||||
This function should return 0 when shutting down the jtag
|
||||
interface went fine and -1 on an error.
|
||||
|
||||
void udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
|
||||
|
||||
A function that delays execution for at least the specified
|
||||
number of microseconds.
|
||||
|
||||
When the 'num_tck' argument is not 0 also the specified number tck
|
||||
clock cycles (i.e. 1-0-1 transitions) must be generated with TMS set
|
||||
to the value specified in the 'tms' argument.
|
||||
|
||||
A simple implementation may perform the delay and the clock cycles
|
||||
after another instead of parallel. This only has an impact on the
|
||||
runtime of the player, not on its functionality.
|
||||
|
||||
int getbyte(struct libxsvf_host *h);
|
||||
|
||||
A function that returns the next byte from the input file
|
||||
or -1 on end of file.
|
||||
|
||||
int sync(struct libxsvf_host *h);
|
||||
|
||||
This function is only needed when writing bindings for an asynchronous
|
||||
hardware interface (see 'Using libxsvf with asynchronous interfaces' below).
|
||||
|
||||
This function is optional and the function pointer may be set to a NULL
|
||||
pointer on implementations using the simple synchronous interface.
|
||||
|
||||
void pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
|
||||
|
||||
This is the main JTAG I/O callback function.
|
||||
It must perform the following tasks:
|
||||
|
||||
* Set the tms line to the value specified in the 'tms' argument.
|
||||
|
||||
* Set the tdi line to the value specified in the 'tdi' argument.
|
||||
This argument may be '-1' to indicate that the value of the tdi
|
||||
line is not important. In this case the tdi line may be set to
|
||||
any value or may be left unchanged.
|
||||
|
||||
* Create a negative pulse (1-0-1) on the JTAG TCK line.
|
||||
|
||||
* Check the tdo line against the should-be value specified in
|
||||
the 'tdo' argument. This argument may be '-1' to indicate that
|
||||
the value of the tdo line doesn't need to be checked.
|
||||
|
||||
* Store the current tdo value if the 'rmask' value is set to '1'.
|
||||
This step may be ignored if the RMASK feature (see "Limitations
|
||||
and non-standard extensions" above) is not used.
|
||||
|
||||
The function must return the current value of the tdo line, or -1 on
|
||||
a TDO-mismatch-error.
|
||||
|
||||
A simple implementation of this function would look like this:
|
||||
|
||||
--snip--
|
||||
int my_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync) {
|
||||
int line_tdo;
|
||||
setPort(TMS, tms);
|
||||
if (tdi >= 0)
|
||||
setPort(TDI, tdi);
|
||||
setPort(TCK, 0);
|
||||
setPort(TCK, 1);
|
||||
line_tdo = getPort(TDO);
|
||||
return tdo < 0 || line_tdo == tdo ? line_tdo : -1;
|
||||
}
|
||||
--snap--
|
||||
|
||||
The 'sync' argument can safely be ignored unless you are writing
|
||||
bindings for an asynchronous hardware interface (see 'Using libxsvf
|
||||
with asynchronous interfaces' below).
|
||||
|
||||
void pulse_sck(struct libxsvf_host *h);
|
||||
|
||||
A function to create a pulse on the JTAG SCK line.
|
||||
|
||||
This function is optional and the function pointer may
|
||||
be set to a NULL pointer on implementations without an
|
||||
SCK line. In this cases an SVF 'RUNTEST n SCK' command
|
||||
has no effect.
|
||||
|
||||
void set_trst(struct libxsvf_host *h, int v);
|
||||
|
||||
A function to set the JTAG TRST line to the specified
|
||||
value:
|
||||
1 ... drive the line high
|
||||
0 ... drive the line low
|
||||
-1 ... do not drive the line (high impedance)
|
||||
-2 ... got SVF 'TRST ABSENT' command
|
||||
|
||||
This function is optional and the function pointer may
|
||||
be set to a NULL pointer on implementations without an
|
||||
TRST line. In this cases an SVF 'TRST' command has no
|
||||
effect.
|
||||
|
||||
int set_frequency(struct libxsvf_host *h, int v);
|
||||
|
||||
A function to set the JTAG CLK frequency to the specified
|
||||
value in Hz. This function should return 0 when setting
|
||||
the frequency was successful and -1 on error.
|
||||
|
||||
This function pointer is optional (may be set to NULL).
|
||||
In this case an SVF FREQUENCY command always results in
|
||||
an error.
|
||||
|
||||
void report_tapstate(struct libxsvf_host *h);
|
||||
|
||||
This function is called whenever the state of the TAP
|
||||
state machine has changed. The TAP state can be read
|
||||
using the h->tap_state enum.
|
||||
|
||||
This function pointer is optional (may be set to NULL)
|
||||
and is for debugging purposes only.
|
||||
|
||||
void report_device(struct libxsvf_host *h, unsigned long idcode);
|
||||
|
||||
This function is called in scan mode for each device found
|
||||
in the JTAG chain.
|
||||
|
||||
This function pointer is optional (may be set to NULL)
|
||||
and is only called in the SCAN mode.
|
||||
|
||||
void report_status(struct libxsvf_host *h, const char *message);
|
||||
|
||||
This function is called each time before an SVF or XSVF
|
||||
command is executed.
|
||||
|
||||
This function pointer is optional (may be set to NULL)
|
||||
and is for debugging purposes only.
|
||||
|
||||
void report_error(struct libxsvf_host *h, const char *file, int line, const char *message);
|
||||
|
||||
This function is called whenever an error is detected
|
||||
in libxsvf. It is not optional and should provide a
|
||||
way to notify a user about the error.
|
||||
|
||||
void *realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which);
|
||||
|
||||
This function must provide a way to allocate dynamic
|
||||
memory. In cases where there is a standard c library
|
||||
it may be a simple wrapper for the realloc() function.
|
||||
|
||||
The xsvftool-gpio command line option '-r' can be used to
|
||||
auto-generate a realloc function for static buffers, based
|
||||
on the requirements from an example svf or xsvf file.
|
||||
Example given:
|
||||
|
||||
./xsvftool-gpio -r my_host_realloc -s demo.svf
|
||||
|
||||
(Re-)allocation may fail. In this cases a NULL pointer
|
||||
must be returned. The library then generates an error,
|
||||
frees all resources and returns.
|
||||
|
||||
After such a struct is prepared, the function libxsvf_play()
|
||||
can be called, passing the libxsvf_host struct as first and the
|
||||
mode (LIBXSVF_MODE_SVF, LIBXSVF_MODE_XSVF or LIBXSVF_MODE_SCAN)
|
||||
as second argument.
|
||||
|
||||
Example given:
|
||||
|
||||
if (libxsvf_play(&h, LIBXSVF_MODE_XSVF) < 0) {
|
||||
/* Error handling */
|
||||
}
|
||||
|
||||
The libxsvf_host struct is passed back to all callback functions
|
||||
and the 'user_data' member (a void pointer) can be used to pass
|
||||
additional data (such as a file handle) to the callbacks.
|
||||
|
||||
|
||||
Host accessor macros
|
||||
--------------------
|
||||
|
||||
Despite its great flexibility, APIs based on callback functions
|
||||
as the one used by libxsvf are unusual in the embedded community.
|
||||
Basically because they introduce a slight overhead in the memory
|
||||
footprint.
|
||||
|
||||
For those who prefer a more direct integration with their host
|
||||
environments libxsvf also provides 'host accessor macros' in the
|
||||
libxsvf.h header file. Simply remove the callback functions from
|
||||
the libxsvf_host struct and modify the LIBXSVF_HOST_ macros
|
||||
to fit your needs.
|
||||
|
||||
|
||||
Using libxsvf with asynchronous interfaces
|
||||
------------------------------------------
|
||||
|
||||
This library has been designed at first for a register mapped bit banging
|
||||
interface as it can be found on many microcontrollers or host CPUs. But
|
||||
some interfaces might require the JTAG data to be send and recivied in
|
||||
blocks and/or asynchronously. This is not trivial with this library because the
|
||||
pulse_tck() callback function is expected to transfer one single bit at a time.
|
||||
The solution to this is to buffer all data sent to pulse_tck() and always
|
||||
return a valid status (i.e. 'tdo < 0 ? 1 : tdo') and do the transfers when the
|
||||
buffer is full or when an interface shutdown is requested.
|
||||
|
||||
However, some JTAG transaction must be performed synchronously (e.g. the last
|
||||
transaction in an XSVF XREPEAT data shift. In this cases pulse_tck() is called
|
||||
with the 'sync' argument set to 1. The pulse_tck() function must then perform
|
||||
all buffered JTAG transactions and return the actual tdo value for this last
|
||||
JTAG transaction or -1 if an error was detected before.
|
||||
|
||||
An asynchronous interface binding also must implement the sync() function. It
|
||||
must perform all buffered JTAG transactions and return -1 if a TDO error was
|
||||
detected an 0 otherwise.
|
||||
|
||||
Note: The returncode of pulse_tck is not checked in all conditions! So whenever
|
||||
an error is detected all further calls to pulse_tck() up to and including
|
||||
the next call of pulse_tck() with the 'sync' argument set or the next call to
|
||||
sync() or shutdown() must return -1.
|
||||
|
||||
Have a look at the example program 'xsvftool-ft232h.c' for a reference
|
||||
implementation.
|
||||
|
||||
|
||||
Stripping down libxsvf
|
||||
----------------------
|
||||
|
||||
It is possible to disable SVF, XSVF and/or SCAN support by setting the
|
||||
LIBXSVF_WITHOUT_SVF, LIBXSVF_WITHOUT_XSVF or LIBXSVF_WITHOUT_SCAN
|
||||
defines. In this cases one would not want to link against svf.o, xsvf.o
|
||||
or scan.o.
|
||||
|
||||
One does not need to link agains statename.o and memname.o if the
|
||||
libxsvf_state2str() and libxsvf_mem2str() functions are not needed.
|
||||
Usually this functions are used for debugging purposes only.
|
||||
|
||||
It is possible to modify the LIBXSVF_HOST_REPORT_STATUS() and
|
||||
LIBXSVF_HOST_REPORT_ERROR() macros in libxsvf.h to be empty
|
||||
instructions. This drastically reduces the number of string
|
||||
constants in the code.
|
||||
|
@ -0,0 +1,139 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef LIBXSVF_H
|
||||
#define LIBXSVF_H
|
||||
|
||||
enum libxsvf_mode {
|
||||
LIBXSVF_MODE_SVF = 1,
|
||||
LIBXSVF_MODE_XSVF = 2,
|
||||
LIBXSVF_MODE_SCAN = 3
|
||||
};
|
||||
|
||||
enum libxsvf_tap_state {
|
||||
/* Special States */
|
||||
LIBXSVF_TAP_INIT = 0,
|
||||
LIBXSVF_TAP_RESET = 1,
|
||||
LIBXSVF_TAP_IDLE = 2,
|
||||
/* DR States */
|
||||
LIBXSVF_TAP_DRSELECT = 3,
|
||||
LIBXSVF_TAP_DRCAPTURE = 4,
|
||||
LIBXSVF_TAP_DRSHIFT = 5,
|
||||
LIBXSVF_TAP_DREXIT1 = 6,
|
||||
LIBXSVF_TAP_DRPAUSE = 7,
|
||||
LIBXSVF_TAP_DREXIT2 = 8,
|
||||
LIBXSVF_TAP_DRUPDATE = 9,
|
||||
/* IR States */
|
||||
LIBXSVF_TAP_IRSELECT = 10,
|
||||
LIBXSVF_TAP_IRCAPTURE = 11,
|
||||
LIBXSVF_TAP_IRSHIFT = 12,
|
||||
LIBXSVF_TAP_IREXIT1 = 13,
|
||||
LIBXSVF_TAP_IRPAUSE = 14,
|
||||
LIBXSVF_TAP_IREXIT2 = 15,
|
||||
LIBXSVF_TAP_IRUPDATE = 16
|
||||
};
|
||||
|
||||
enum libxsvf_mem {
|
||||
LIBXSVF_MEM_XSVF_TDI_DATA = 0,
|
||||
LIBXSVF_MEM_XSVF_TDO_DATA = 1,
|
||||
LIBXSVF_MEM_XSVF_TDO_MASK = 2,
|
||||
LIBXSVF_MEM_XSVF_ADDR_MASK = 3,
|
||||
LIBXSVF_MEM_XSVF_DATA_MASK = 4,
|
||||
LIBXSVF_MEM_SVF_COMMANDBUF = 5,
|
||||
LIBXSVF_MEM_SVF_SDR_TDI_DATA = 6,
|
||||
LIBXSVF_MEM_SVF_SDR_TDI_MASK = 7,
|
||||
LIBXSVF_MEM_SVF_SDR_TDO_DATA = 8,
|
||||
LIBXSVF_MEM_SVF_SDR_TDO_MASK = 9,
|
||||
LIBXSVF_MEM_SVF_SDR_RET_MASK = 10,
|
||||
LIBXSVF_MEM_SVF_SIR_TDI_DATA = 11,
|
||||
LIBXSVF_MEM_SVF_SIR_TDI_MASK = 12,
|
||||
LIBXSVF_MEM_SVF_SIR_TDO_DATA = 13,
|
||||
LIBXSVF_MEM_SVF_SIR_TDO_MASK = 14,
|
||||
LIBXSVF_MEM_SVF_SIR_RET_MASK = 15,
|
||||
LIBXSVF_MEM_SVF_HDR_TDI_DATA = 16,
|
||||
LIBXSVF_MEM_SVF_HDR_TDI_MASK = 17,
|
||||
LIBXSVF_MEM_SVF_HDR_TDO_DATA = 18,
|
||||
LIBXSVF_MEM_SVF_HDR_TDO_MASK = 19,
|
||||
LIBXSVF_MEM_SVF_HDR_RET_MASK = 20,
|
||||
LIBXSVF_MEM_SVF_HIR_TDI_DATA = 21,
|
||||
LIBXSVF_MEM_SVF_HIR_TDI_MASK = 22,
|
||||
LIBXSVF_MEM_SVF_HIR_TDO_DATA = 23,
|
||||
LIBXSVF_MEM_SVF_HIR_TDO_MASK = 24,
|
||||
LIBXSVF_MEM_SVF_HIR_RET_MASK = 25,
|
||||
LIBXSVF_MEM_SVF_TDR_TDI_DATA = 26,
|
||||
LIBXSVF_MEM_SVF_TDR_TDI_MASK = 27,
|
||||
LIBXSVF_MEM_SVF_TDR_TDO_DATA = 28,
|
||||
LIBXSVF_MEM_SVF_TDR_TDO_MASK = 29,
|
||||
LIBXSVF_MEM_SVF_TDR_RET_MASK = 30,
|
||||
LIBXSVF_MEM_SVF_TIR_TDI_DATA = 31,
|
||||
LIBXSVF_MEM_SVF_TIR_TDI_MASK = 32,
|
||||
LIBXSVF_MEM_SVF_TIR_TDO_DATA = 33,
|
||||
LIBXSVF_MEM_SVF_TIR_TDO_MASK = 34,
|
||||
LIBXSVF_MEM_SVF_TIR_RET_MASK = 35,
|
||||
LIBXSVF_MEM_NUM = 36
|
||||
};
|
||||
|
||||
struct libxsvf_host {
|
||||
int (*setup)(struct libxsvf_host *h);
|
||||
int (*shutdown)(struct libxsvf_host *h);
|
||||
void (*udelay)(struct libxsvf_host *h, long usecs, int tms, long num_tck);
|
||||
int (*getbyte)(struct libxsvf_host *h);
|
||||
int (*sync)(struct libxsvf_host *h);
|
||||
int (*pulse_tck)(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync);
|
||||
void (*pulse_sck)(struct libxsvf_host *h);
|
||||
void (*set_trst)(struct libxsvf_host *h, int v);
|
||||
int (*set_frequency)(struct libxsvf_host *h, int v);
|
||||
void (*report_tapstate)(struct libxsvf_host *h);
|
||||
void (*report_device)(struct libxsvf_host *h, unsigned long idcode);
|
||||
void (*report_status)(struct libxsvf_host *h, const char *message);
|
||||
void (*report_error)(struct libxsvf_host *h, const char *file, int line, const char *message);
|
||||
void *(*realloc)(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which);
|
||||
enum libxsvf_tap_state tap_state;
|
||||
void *user_data;
|
||||
};
|
||||
|
||||
int libxsvf_play(struct libxsvf_host *, enum libxsvf_mode mode);
|
||||
const char *libxsvf_state2str(enum libxsvf_tap_state tap_state);
|
||||
const char *libxsvf_mem2str(enum libxsvf_mem which);
|
||||
|
||||
/* Internal API */
|
||||
int libxsvf_svf(struct libxsvf_host *h);
|
||||
int libxsvf_xsvf(struct libxsvf_host *h);
|
||||
int libxsvf_scan(struct libxsvf_host *h);
|
||||
int libxsvf_tap_walk(struct libxsvf_host *, enum libxsvf_tap_state);
|
||||
|
||||
/* Host accessor macros (see README) */
|
||||
#define LIBXSVF_HOST_SETUP() h->setup(h)
|
||||
#define LIBXSVF_HOST_SHUTDOWN() h->shutdown(h)
|
||||
#define LIBXSVF_HOST_UDELAY(_usecs, _tms, _num_tck) h->udelay(h, _usecs, _tms, _num_tck)
|
||||
#define LIBXSVF_HOST_GETBYTE() h->getbyte(h)
|
||||
#define LIBXSVF_HOST_SYNC() (h->sync ? h->sync(h) : 0)
|
||||
#define LIBXSVF_HOST_PULSE_TCK(_tms, _tdi, _tdo, _rmask, _sync) h->pulse_tck(h, _tms, _tdi, _tdo, _rmask, _sync)
|
||||
#define LIBXSVF_HOST_PULSE_SCK() do { if (h->pulse_sck) h->pulse_sck(h); } while (0)
|
||||
#define LIBXSVF_HOST_SET_TRST(_v) do { if (h->set_trst) h->set_trst(h, _v); } while (0)
|
||||
#define LIBXSVF_HOST_SET_FREQUENCY(_v) (h->set_frequency ? h->set_frequency(h, _v) : -1)
|
||||
#define LIBXSVF_HOST_REPORT_TAPSTATE() do { if (h->report_tapstate) h->report_tapstate(h); } while (0)
|
||||
#define LIBXSVF_HOST_REPORT_DEVICE(_v) do { if (h->report_device) h->report_device(h, _v); } while (0)
|
||||
#define LIBXSVF_HOST_REPORT_STATUS(_msg) do { if (h->report_status) h->report_status(h, _msg); } while (0)
|
||||
#define LIBXSVF_HOST_REPORT_ERROR(_msg) h->report_error(h, __FILE__, __LINE__, _msg)
|
||||
#define LIBXSVF_HOST_REALLOC(_ptr, _size, _which) h->realloc(h, _ptr, _size, _which)
|
||||
|
||||
#endif
|
||||
|
@ -0,0 +1,65 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
const char *libxsvf_mem2str(enum libxsvf_mem which)
|
||||
{
|
||||
#define X(_w, _t) if (which == LIBXSVF_MEM_ ## _w) return #_t;
|
||||
X(XSVF_TDI_DATA, xsvf_tdi_data)
|
||||
X(XSVF_TDO_DATA, xsvf_tdo_data)
|
||||
X(XSVF_TDO_MASK, xsvf_tdo_mask)
|
||||
X(XSVF_ADDR_MASK, xsvf_addr_mask)
|
||||
X(XSVF_DATA_MASK, xsvf_data_mask)
|
||||
X(SVF_COMMANDBUF, svf_commandbuf)
|
||||
X(SVF_HDR_TDI_DATA, svf_hdr_tdi_data)
|
||||
X(SVF_HDR_TDI_MASK, svf_hdr_tdi_mask)
|
||||
X(SVF_HDR_TDO_DATA, svf_hdr_tdo_data)
|
||||
X(SVF_HDR_TDO_MASK, svf_hdr_tdo_mask)
|
||||
X(SVF_HDR_RET_MASK, svf_hdr_ret_mask)
|
||||
X(SVF_HIR_TDI_DATA, svf_hir_tdi_data)
|
||||
X(SVF_HIR_TDI_MASK, svf_hir_tdi_mask)
|
||||
X(SVF_HIR_TDO_DATA, svf_hir_tdo_data)
|
||||
X(SVF_HIR_TDO_MASK, svf_hir_tdo_mask)
|
||||
X(SVF_HIR_RET_MASK, svf_hir_ret_mask)
|
||||
X(SVF_TDR_TDI_DATA, svf_tdr_tdi_data)
|
||||
X(SVF_TDR_TDI_MASK, svf_tdr_tdi_mask)
|
||||
X(SVF_TDR_TDO_DATA, svf_tdr_tdo_data)
|
||||
X(SVF_TDR_TDO_MASK, svf_tdr_tdo_mask)
|
||||
X(SVF_TDR_RET_MASK, svf_tdr_ret_mask)
|
||||
X(SVF_TIR_TDI_DATA, svf_tir_tdi_data)
|
||||
X(SVF_TIR_TDI_MASK, svf_tir_tdi_mask)
|
||||
X(SVF_TIR_TDO_DATA, svf_tir_tdo_data)
|
||||
X(SVF_TIR_TDO_MASK, svf_tir_tdo_mask)
|
||||
X(SVF_TIR_RET_MASK, svf_tir_ret_mask)
|
||||
X(SVF_SDR_TDI_DATA, svf_sdr_tdi_data)
|
||||
X(SVF_SDR_TDI_MASK, svf_sdr_tdi_mask)
|
||||
X(SVF_SDR_TDO_DATA, svf_sdr_tdo_data)
|
||||
X(SVF_SDR_TDO_MASK, svf_sdr_tdo_mask)
|
||||
X(SVF_SDR_RET_MASK, svf_sdr_ret_mask)
|
||||
X(SVF_SIR_TDI_DATA, svf_sir_tdi_data)
|
||||
X(SVF_SIR_TDI_MASK, svf_sir_tdi_mask)
|
||||
X(SVF_SIR_TDO_DATA, svf_sir_tdo_data)
|
||||
X(SVF_SIR_TDO_MASK, svf_sir_tdo_mask)
|
||||
X(SVF_SIR_RET_MASK, svf_sir_ret_mask)
|
||||
#undef X
|
||||
return (void*)0;
|
||||
}
|
||||
|
@ -0,0 +1,72 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
int libxsvf_play(struct libxsvf_host *h, enum libxsvf_mode mode)
|
||||
{
|
||||
int rc = -1;
|
||||
|
||||
h->tap_state = LIBXSVF_TAP_INIT;
|
||||
if (LIBXSVF_HOST_SETUP() < 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Setup of JTAG interface failed.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (mode == LIBXSVF_MODE_SVF) {
|
||||
#ifdef LIBXSVF_WITHOUT_SVF
|
||||
LIBXSVF_HOST_REPORT_ERROR("SVF support in libxsvf is disabled.");
|
||||
#else
|
||||
rc = libxsvf_svf(h);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mode == LIBXSVF_MODE_XSVF) {
|
||||
#ifdef LIBXSVF_WITHOUT_XSVF
|
||||
LIBXSVF_HOST_REPORT_ERROR("XSVF support in libxsvf is disabled.");
|
||||
#else
|
||||
rc = libxsvf_xsvf(h);
|
||||
#endif
|
||||
}
|
||||
|
||||
if (mode == LIBXSVF_MODE_SCAN) {
|
||||
#ifdef LIBXSVF_WITHOUT_SCAN
|
||||
LIBXSVF_HOST_REPORT_ERROR("SCAN support in libxsvf is disabled.");
|
||||
#else
|
||||
rc = libxsvf_scan(h);
|
||||
#endif
|
||||
}
|
||||
|
||||
libxsvf_tap_walk(h, LIBXSVF_TAP_RESET);
|
||||
if (LIBXSVF_HOST_SYNC() != 0 && rc >= 0 ) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch in TAP reset. (this is not possible!)");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
int shutdown_rc = LIBXSVF_HOST_SHUTDOWN();
|
||||
|
||||
if (shutdown_rc < 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Shutdown of JTAG interface failed.");
|
||||
rc = rc < 0 ? rc : shutdown_rc;
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -0,0 +1,58 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
int libxsvf_scan(struct libxsvf_host *h)
|
||||
{
|
||||
int i, j;
|
||||
|
||||
if (libxsvf_tap_walk(h, LIBXSVF_TAP_RESET) < 0)
|
||||
return -1;
|
||||
|
||||
if (libxsvf_tap_walk(h, LIBXSVF_TAP_DRSHIFT) < 0)
|
||||
return -1;
|
||||
|
||||
for (i=0; i<256; i++)
|
||||
{
|
||||
int bit = LIBXSVF_HOST_PULSE_TCK(0, 1, -1, 0, 1);
|
||||
|
||||
if (bit < 0)
|
||||
return -1;
|
||||
|
||||
if (bit == 0) {
|
||||
LIBXSVF_HOST_REPORT_DEVICE(0);
|
||||
} else {
|
||||
unsigned long idcode = 1;
|
||||
for (j=1; j<32; j++) {
|
||||
int bit = LIBXSVF_HOST_PULSE_TCK(0, 1, -1, 0, 1);
|
||||
if (bit < 0)
|
||||
return -1;
|
||||
idcode |= ((unsigned long)bit) << j;
|
||||
}
|
||||
if (idcode == 0xffffffff)
|
||||
break;
|
||||
LIBXSVF_HOST_REPORT_DEVICE(idcode);
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
@ -0,0 +1,46 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
const char *libxsvf_state2str(enum libxsvf_tap_state tap_state)
|
||||
{
|
||||
#define X(_s) if (tap_state == _s) return #_s;
|
||||
X(LIBXSVF_TAP_INIT)
|
||||
X(LIBXSVF_TAP_RESET)
|
||||
X(LIBXSVF_TAP_IDLE)
|
||||
X(LIBXSVF_TAP_DRSELECT)
|
||||
X(LIBXSVF_TAP_DRCAPTURE)
|
||||
X(LIBXSVF_TAP_DRSHIFT)
|
||||
X(LIBXSVF_TAP_DREXIT1)
|
||||
X(LIBXSVF_TAP_DRPAUSE)
|
||||
X(LIBXSVF_TAP_DREXIT2)
|
||||
X(LIBXSVF_TAP_DRUPDATE)
|
||||
X(LIBXSVF_TAP_IRSELECT)
|
||||
X(LIBXSVF_TAP_IRCAPTURE)
|
||||
X(LIBXSVF_TAP_IRSHIFT)
|
||||
X(LIBXSVF_TAP_IREXIT1)
|
||||
X(LIBXSVF_TAP_IRPAUSE)
|
||||
X(LIBXSVF_TAP_IREXIT2)
|
||||
X(LIBXSVF_TAP_IRUPDATE)
|
||||
#undef X
|
||||
return "UNKOWN_STATE";
|
||||
}
|
||||
|
@ -0,0 +1,657 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
static int read_command(struct libxsvf_host *h, char **buffer_p, int *len_p)
|
||||
{
|
||||
char *buffer = *buffer_p;
|
||||
int braket_mode = 0;
|
||||
int len = *len_p;
|
||||
int p = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
if (len < p+10) {
|
||||
len = len < 64 ? 96 : len*2;
|
||||
buffer = LIBXSVF_HOST_REALLOC(buffer, len, LIBXSVF_MEM_SVF_COMMANDBUF);
|
||||
*buffer_p = buffer;
|
||||
*len_p = len;
|
||||
if (!buffer) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Allocating memory failed.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
buffer[p] = 0;
|
||||
|
||||
int ch = LIBXSVF_HOST_GETBYTE();
|
||||
if (ch < 0) {
|
||||
handle_eof:
|
||||
if (p == 0)
|
||||
return 0;
|
||||
LIBXSVF_HOST_REPORT_ERROR("Unexpected EOF.");
|
||||
return -1;
|
||||
}
|
||||
if (ch <= ' ') {
|
||||
insert_eol:
|
||||
if (!braket_mode && p > 0 && buffer[p-1] != ' ')
|
||||
buffer[p++] = ' ';
|
||||
continue;
|
||||
}
|
||||
if (ch == '!') {
|
||||
skip_to_eol:
|
||||
while (1) {
|
||||
ch = LIBXSVF_HOST_GETBYTE();
|
||||
if (ch < 0)
|
||||
goto handle_eof;
|
||||
if (ch < ' ' && ch != '\t')
|
||||
goto insert_eol;
|
||||
}
|
||||
}
|
||||
if (ch == '/' && p > 0 && buffer[p-1] == '/') {
|
||||
p--;
|
||||
goto skip_to_eol;
|
||||
}
|
||||
if (ch == ';')
|
||||
break;
|
||||
if (ch == '(') {
|
||||
if (!braket_mode && p > 0 && buffer[p-1] != ' ')
|
||||
buffer[p++] = ' ';
|
||||
braket_mode++;
|
||||
}
|
||||
if (ch >= 'a' && ch <= 'z')
|
||||
buffer[p++] = ch - ('a' - 'A');
|
||||
else
|
||||
buffer[p++] = ch;
|
||||
if (ch == ')') {
|
||||
braket_mode--;
|
||||
if (!braket_mode)
|
||||
buffer[p++] = ' ';
|
||||
}
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
static int strtokencmp(const char *str1, const char *str2)
|
||||
{
|
||||
int i = 0;
|
||||
while (1) {
|
||||
if ((str1[i] == ' ' || str1[i] == 0) && (str2[i] == ' ' || str2[i] == 0))
|
||||
return 0;
|
||||
if (str1[i] < str2[i])
|
||||
return -1;
|
||||
if (str1[i] > str2[i])
|
||||
return +1;
|
||||
i++;
|
||||
}
|
||||
}
|
||||
|
||||
static int strtokenskip(const char *str1)
|
||||
{
|
||||
int i = 0;
|
||||
while (str1[i] != 0 && str1[i] != ' ') i++;
|
||||
while (str1[i] == ' ') i++;
|
||||
return i;
|
||||
}
|
||||
|
||||
static int token2tapstate(const char *str1)
|
||||
{
|
||||
#define X(_t) if (!strtokencmp(str1, #_t)) return LIBXSVF_TAP_ ## _t;
|
||||
X(RESET)
|
||||
X(IDLE)
|
||||
X(DRSELECT)
|
||||
X(DRCAPTURE)
|
||||
X(DRSHIFT)
|
||||
X(DREXIT1)
|
||||
X(DRPAUSE)
|
||||
X(DREXIT2)
|
||||
X(DRUPDATE)
|
||||
X(IRSELECT)
|
||||
X(IRCAPTURE)
|
||||
X(IRSHIFT)
|
||||
X(IREXIT1)
|
||||
X(IRPAUSE)
|
||||
X(IREXIT2)
|
||||
X(IRUPDATE)
|
||||
#undef X
|
||||
return -1;
|
||||
}
|
||||
|
||||
struct bitdata_s {
|
||||
int len, alloced_len;
|
||||
int alloced_bytes;
|
||||
unsigned char *tdi_data;
|
||||
unsigned char *tdi_mask;
|
||||
unsigned char *tdo_data;
|
||||
unsigned char *tdo_mask;
|
||||
unsigned char *ret_mask;
|
||||
int has_tdo_data;
|
||||
};
|
||||
|
||||
static void bitdata_free(struct libxsvf_host *h, struct bitdata_s *bd, int offset)
|
||||
{
|
||||
LIBXSVF_HOST_REALLOC(bd->tdi_data, 0, offset+0);
|
||||
LIBXSVF_HOST_REALLOC(bd->tdi_mask, 0, offset+1);
|
||||
LIBXSVF_HOST_REALLOC(bd->tdo_data, 0, offset+2);
|
||||
LIBXSVF_HOST_REALLOC(bd->tdo_mask, 0, offset+3);
|
||||
LIBXSVF_HOST_REALLOC(bd->ret_mask, 0, offset+4);
|
||||
|
||||
bd->tdi_data = (void*)0;
|
||||
bd->tdi_mask = (void*)0;
|
||||
bd->tdo_data = (void*)0;
|
||||
bd->tdo_mask = (void*)0;
|
||||
bd->ret_mask = (void*)0;
|
||||
}
|
||||
|
||||
static int hex(char ch)
|
||||
{
|
||||
if (ch >= 'A' && ch <= 'Z')
|
||||
return (ch - 'A') + 10;
|
||||
if (ch >= '0' && ch <= '9')
|
||||
return ch - '0';
|
||||
return 0;
|
||||
}
|
||||
|
||||
static const char *bitdata_parse(struct libxsvf_host *h, const char *p, struct bitdata_s *bd, int offset)
|
||||
{
|
||||
int i, j;
|
||||
bd->len = 0;
|
||||
bd->has_tdo_data = 0;
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
bd->len = bd->len * 10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
if (bd->len != bd->alloced_len) {
|
||||
bitdata_free(h, bd, offset);
|
||||
bd->alloced_len = bd->len;
|
||||
bd->alloced_bytes = (bd->len+7) / 8;
|
||||
}
|
||||
while (*p)
|
||||
{
|
||||
int memnum = 0;
|
||||
unsigned char **dp = (void*)0;
|
||||
if (!strtokencmp(p, "TDI")) {
|
||||
p += strtokenskip(p);
|
||||
dp = &bd->tdi_data;
|
||||
memnum = 0;
|
||||
}
|
||||
if (!strtokencmp(p, "TDO")) {
|
||||
p += strtokenskip(p);
|
||||
dp = &bd->tdo_data;
|
||||
bd->has_tdo_data = 1;
|
||||
memnum = 1;
|
||||
}
|
||||
if (!strtokencmp(p, "SMASK")) {
|
||||
p += strtokenskip(p);
|
||||
dp = &bd->tdi_mask;
|
||||
memnum = 2;
|
||||
}
|
||||
if (!strtokencmp(p, "MASK")) {
|
||||
p += strtokenskip(p);
|
||||
dp = &bd->tdo_mask;
|
||||
memnum = 3;
|
||||
}
|
||||
if (!strtokencmp(p, "RMASK")) {
|
||||
p += strtokenskip(p);
|
||||
dp = &bd->ret_mask;
|
||||
memnum = 4;
|
||||
}
|
||||
if (!dp)
|
||||
return (void*)0;
|
||||
if (*dp == (void*)0) {
|
||||
*dp = LIBXSVF_HOST_REALLOC(*dp, bd->alloced_bytes, offset+memnum);
|
||||
}
|
||||
if (*dp == (void*)0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Allocating memory failed.");
|
||||
return (void*)0;
|
||||
}
|
||||
|
||||
unsigned char *d = *dp;
|
||||
for (i=0; i<bd->alloced_bytes; i++)
|
||||
d[i] = 0;
|
||||
|
||||
if (*p != '(')
|
||||
return (void*)0;
|
||||
p++;
|
||||
|
||||
int hexdigits = 0;
|
||||
for (i=0; (p[i] >= 'A' && p[i] <= 'F') || (p[i] >= '0' && p[i] <= '9'); i++)
|
||||
hexdigits++;
|
||||
|
||||
i = bd->alloced_bytes*2 - hexdigits;
|
||||
for (j=0; j<hexdigits; j++, i++, p++) {
|
||||
if (i%2 == 0) {
|
||||
d[i/2] |= hex(*p) << 4;
|
||||
} else {
|
||||
d[i/2] |= hex(*p);
|
||||
}
|
||||
}
|
||||
|
||||
if (*p != ')')
|
||||
return (void*)0;
|
||||
p++;
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
}
|
||||
#if 0
|
||||
/* Debugging Output, needs <stdio.h> */
|
||||
printf("--- Parsed bitdata [%d] ---\n", bd->len);
|
||||
if (bd->tdi_data) {
|
||||
printf("TDI DATA:");
|
||||
for (i=0; i<bd->alloced_bytes; i++)
|
||||
printf(" %02x", bd->tdi_data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
if (bd->tdo_data && has_tdo_data) {
|
||||
printf("TDO DATA:");
|
||||
for (i=0; i<bd->alloced_bytes; i++)
|
||||
printf(" %02x", bd->tdo_data[i]);
|
||||
printf("\n");
|
||||
}
|
||||
if (bd->tdi_mask) {
|
||||
printf("TDI MASK:");
|
||||
for (i=0; i<bd->alloced_bytes; i++)
|
||||
printf(" %02x", bd->tdi_mask[i]);
|
||||
printf("\n");
|
||||
}
|
||||
if (bd->tdo_mask) {
|
||||
printf("TDO MASK:");
|
||||
for (i=0; i<bd->alloced_bytes; i++)
|
||||
printf(" %02x", bd->tdo_mask[i]);
|
||||
printf("\n");
|
||||
}
|
||||
#endif
|
||||
return p;
|
||||
}
|
||||
|
||||
static int getbit(unsigned char *data, int n)
|
||||
{
|
||||
return (data[n/8] & (1 << (7 - n%8))) ? 1 : 0;
|
||||
}
|
||||
|
||||
static int bitdata_play(struct libxsvf_host *h, struct bitdata_s *bd, enum libxsvf_tap_state estate)
|
||||
{
|
||||
int left_padding = (8 - bd->len % 8) % 8;
|
||||
int tdo_error = 0;
|
||||
int tms = 0;
|
||||
int i;
|
||||
|
||||
for (i=bd->len+left_padding-1; i >= left_padding; i--) {
|
||||
if (i == left_padding && h->tap_state != estate) {
|
||||
h->tap_state++;
|
||||
tms = 1;
|
||||
}
|
||||
int tdi = -1;
|
||||
if (bd->tdi_data) {
|
||||
if (!bd->tdi_mask || getbit(bd->tdi_mask, i))
|
||||
tdi = getbit(bd->tdi_data, i);
|
||||
}
|
||||
int tdo = -1;
|
||||
if (bd->tdo_data && bd->has_tdo_data && (!bd->tdo_mask || getbit(bd->tdo_mask, i)))
|
||||
tdo = getbit(bd->tdo_data, i);
|
||||
int rmask = bd->ret_mask && getbit(bd->ret_mask, i);
|
||||
if (LIBXSVF_HOST_PULSE_TCK(tms, tdi, tdo, rmask, 0) < 0)
|
||||
tdo_error = 1;
|
||||
}
|
||||
|
||||
if (tms)
|
||||
LIBXSVF_HOST_REPORT_TAPSTATE();
|
||||
|
||||
if (!tdo_error)
|
||||
return 0;
|
||||
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
int libxsvf_svf(struct libxsvf_host *h)
|
||||
{
|
||||
char *command_buffer = (void*)0;
|
||||
int command_buffer_len = 0;
|
||||
int rc, i;
|
||||
|
||||
struct bitdata_s bd_hdr = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
struct bitdata_s bd_hir = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
struct bitdata_s bd_tdr = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
struct bitdata_s bd_tir = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
struct bitdata_s bd_sdr = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
struct bitdata_s bd_sir = { 0, 0, 0, (void*)0, (void*)0, (void*)0, (void*)0, (void*)0 };
|
||||
|
||||
int state_endir = LIBXSVF_TAP_IDLE;
|
||||
int state_enddr = LIBXSVF_TAP_IDLE;
|
||||
int state_run = LIBXSVF_TAP_IDLE;
|
||||
int state_endrun = LIBXSVF_TAP_IDLE;
|
||||
|
||||
while (1)
|
||||
{
|
||||
rc = read_command(h, &command_buffer, &command_buffer_len);
|
||||
|
||||
if (rc <= 0)
|
||||
break;
|
||||
|
||||
const char *p = command_buffer;
|
||||
|
||||
LIBXSVF_HOST_REPORT_STATUS(command_buffer);
|
||||
|
||||
if (!strtokencmp(p, "ENDIR")) {
|
||||
p += strtokenskip(p);
|
||||
state_endir = token2tapstate(p);
|
||||
if (state_endir < 0)
|
||||
goto syntax_error;
|
||||
p += strtokenskip(p);
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "ENDDR")) {
|
||||
p += strtokenskip(p);
|
||||
state_enddr = token2tapstate(p);
|
||||
if (state_endir < 0)
|
||||
goto syntax_error;
|
||||
p += strtokenskip(p);
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "FREQUENCY")) {
|
||||
unsigned long number = 0;
|
||||
int exp = 0;
|
||||
p += strtokenskip(p);
|
||||
if (*p < '0' || *p > '9')
|
||||
goto syntax_error;
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
number = number*10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
if(*p == 'E' || *p == 'e') {
|
||||
p++;
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
exp = exp*10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
for(i=0; i<exp; i++)
|
||||
number *= 10;
|
||||
}
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
p += strtokenskip(p);
|
||||
if (LIBXSVF_HOST_SET_FREQUENCY(number) < 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("FREQUENCY command failed!");
|
||||
goto error;
|
||||
}
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "HDR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_hdr, LIBXSVF_MEM_SVF_HDR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "HIR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_hir, LIBXSVF_MEM_SVF_HIR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "PIO") || !strtokencmp(p, "PIOMAP")) {
|
||||
goto unsupported_error;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "RUNTEST")) {
|
||||
p += strtokenskip(p);
|
||||
int tck_count = -1;
|
||||
int sck_count = -1;
|
||||
int min_time = -1;
|
||||
int max_time = -1;
|
||||
while (*p) {
|
||||
int got_maximum = 0;
|
||||
if (!strtokencmp(p, "MAXIMUM")) {
|
||||
p += strtokenskip(p);
|
||||
got_maximum = 1;
|
||||
}
|
||||
int got_endstate = 0;
|
||||
if (!strtokencmp(p, "ENDSTATE")) {
|
||||
p += strtokenskip(p);
|
||||
got_endstate = 1;
|
||||
}
|
||||
int st = token2tapstate(p);
|
||||
if (st >= 0) {
|
||||
p += strtokenskip(p);
|
||||
if (got_endstate)
|
||||
state_endrun = st;
|
||||
else
|
||||
state_run = st;
|
||||
continue;
|
||||
}
|
||||
if (*p < '0' || *p > '9')
|
||||
goto syntax_error;
|
||||
int number = 0;
|
||||
int exp = 0, expsign = 1;
|
||||
int number_e6, exp_e6;
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
number = number*10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
if(*p == 'E' || *p == 'e') {
|
||||
p++;
|
||||
if(*p == '-') {
|
||||
expsign = -1;
|
||||
p++;
|
||||
}
|
||||
while (*p >= '0' && *p <= '9') {
|
||||
exp = exp*10 + (*p - '0');
|
||||
p++;
|
||||
}
|
||||
exp = exp * expsign;
|
||||
number_e6 = number;
|
||||
exp_e6 = exp + 6;
|
||||
while (exp < 0) {
|
||||
number /= 10;
|
||||
exp++;
|
||||
}
|
||||
while (exp > 0) {
|
||||
number *= 10;
|
||||
exp--;
|
||||
}
|
||||
while (exp_e6 < 0) {
|
||||
number_e6 /= 10;
|
||||
exp_e6++;
|
||||
}
|
||||
while (exp_e6 > 0) {
|
||||
number_e6 *= 10;
|
||||
exp_e6--;
|
||||
}
|
||||
} else {
|
||||
number_e6 = number * 1000000;
|
||||
}
|
||||
while (*p == ' ') {
|
||||
p++;
|
||||
}
|
||||
if (!strtokencmp(p, "SEC")) {
|
||||
p += strtokenskip(p);
|
||||
if (got_maximum)
|
||||
max_time = number_e6;
|
||||
else
|
||||
min_time = number_e6;
|
||||
continue;
|
||||
}
|
||||
if (!strtokencmp(p, "TCK")) {
|
||||
p += strtokenskip(p);
|
||||
tck_count = number;
|
||||
continue;
|
||||
}
|
||||
if (!strtokencmp(p, "SCK")) {
|
||||
p += strtokenskip(p);
|
||||
sck_count = number;
|
||||
continue;
|
||||
}
|
||||
goto syntax_error;
|
||||
}
|
||||
if (libxsvf_tap_walk(h, state_run) < 0)
|
||||
goto error;
|
||||
if (max_time >= 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("WARNING: Maximum time in SVF RUNTEST command is ignored.");
|
||||
}
|
||||
if (sck_count >= 0) {
|
||||
for (i=0; i < sck_count; i++) {
|
||||
LIBXSVF_HOST_PULSE_SCK();
|
||||
}
|
||||
}
|
||||
if (min_time >= 0 || tck_count >= 0) {
|
||||
LIBXSVF_HOST_UDELAY(min_time >= 0 ? min_time : 0, 0, tck_count >= 0 ? tck_count : 0);
|
||||
}
|
||||
if (libxsvf_tap_walk(h, state_endrun) < 0)
|
||||
goto error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "SDR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_sdr, LIBXSVF_MEM_SVF_SDR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
if (libxsvf_tap_walk(h, LIBXSVF_TAP_DRSHIFT) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_hdr, bd_sdr.len+bd_tdr.len > 0 ? LIBXSVF_TAP_DRSHIFT : state_enddr) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_sdr, bd_tdr.len > 0 ? LIBXSVF_TAP_DRSHIFT : state_enddr) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_tdr, state_enddr) < 0)
|
||||
goto error;
|
||||
if (libxsvf_tap_walk(h, state_enddr) < 0)
|
||||
goto error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "SIR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_sir, LIBXSVF_MEM_SVF_SIR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
if (libxsvf_tap_walk(h, LIBXSVF_TAP_IRSHIFT) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_hir, bd_sir.len+bd_tir.len > 0 ? LIBXSVF_TAP_IRSHIFT : state_endir) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_sir, bd_tir.len > 0 ? LIBXSVF_TAP_IRSHIFT : state_endir) < 0)
|
||||
goto error;
|
||||
if (bitdata_play(h, &bd_tir, state_endir) < 0)
|
||||
goto error;
|
||||
if (libxsvf_tap_walk(h, state_endir) < 0)
|
||||
goto error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "STATE")) {
|
||||
p += strtokenskip(p);
|
||||
while (*p) {
|
||||
int st = token2tapstate(p);
|
||||
if (st < 0)
|
||||
goto syntax_error;
|
||||
if (libxsvf_tap_walk(h, st) < 0)
|
||||
goto error;
|
||||
p += strtokenskip(p);
|
||||
}
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "TDR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_tdr, LIBXSVF_MEM_SVF_TDR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "TIR")) {
|
||||
p += strtokenskip(p);
|
||||
p = bitdata_parse(h, p, &bd_tir, LIBXSVF_MEM_SVF_TIR_TDI_DATA);
|
||||
if (!p)
|
||||
goto syntax_error;
|
||||
goto eol_check;
|
||||
}
|
||||
|
||||
if (!strtokencmp(p, "TRST")) {
|
||||
p += strtokenskip(p);
|
||||
if (!strtokencmp(p, "ON")) {
|
||||
p += strtokenskip(p);
|
||||
LIBXSVF_HOST_SET_TRST(1);
|
||||
goto eol_check;
|
||||
}
|
||||
if (!strtokencmp(p, "OFF")) {
|
||||
p += strtokenskip(p);
|
||||
LIBXSVF_HOST_SET_TRST(0);
|
||||
goto eol_check;
|
||||
}
|
||||
if (!strtokencmp(p, "Z")) {
|
||||
p += strtokenskip(p);
|
||||
LIBXSVF_HOST_SET_TRST(-1);
|
||||
goto eol_check;
|
||||
}
|
||||
if (!strtokencmp(p, "ABSENT")) {
|
||||
p += strtokenskip(p);
|
||||
LIBXSVF_HOST_SET_TRST(-2);
|
||||
goto eol_check;
|
||||
}
|
||||
goto syntax_error;
|
||||
}
|
||||
|
||||
eol_check:
|
||||
while (*p == ' ')
|
||||
p++;
|
||||
if (*p == 0)
|
||||
continue;
|
||||
|
||||
syntax_error:
|
||||
LIBXSVF_HOST_REPORT_ERROR("SVF Syntax Error:");
|
||||
if (0) {
|
||||
unsupported_error:
|
||||
LIBXSVF_HOST_REPORT_ERROR("Error in SVF input: unsupported command:");
|
||||
}
|
||||
LIBXSVF_HOST_REPORT_ERROR(command_buffer);
|
||||
error:
|
||||
rc = -1;
|
||||
break;
|
||||
}
|
||||
|
||||
if (LIBXSVF_HOST_SYNC() != 0 && rc >= 0 ) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch.");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
bitdata_free(h, &bd_hdr, LIBXSVF_MEM_SVF_HDR_TDI_DATA);
|
||||
bitdata_free(h, &bd_hir, LIBXSVF_MEM_SVF_HIR_TDI_DATA);
|
||||
bitdata_free(h, &bd_tdr, LIBXSVF_MEM_SVF_TDR_TDI_DATA);
|
||||
bitdata_free(h, &bd_tir, LIBXSVF_MEM_SVF_TIR_TDI_DATA);
|
||||
bitdata_free(h, &bd_sdr, LIBXSVF_MEM_SVF_SDR_TDI_DATA);
|
||||
bitdata_free(h, &bd_sir, LIBXSVF_MEM_SVF_SIR_TDI_DATA);
|
||||
|
||||
LIBXSVF_HOST_REALLOC(command_buffer, 0, LIBXSVF_MEM_SVF_COMMANDBUF);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -0,0 +1,173 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
static void tap_transition(struct libxsvf_host *h, int v)
|
||||
{
|
||||
LIBXSVF_HOST_PULSE_TCK(v, -1, -1, 0, 0);
|
||||
}
|
||||
|
||||
int libxsvf_tap_walk(struct libxsvf_host *h, enum libxsvf_tap_state s)
|
||||
{
|
||||
int i, j;
|
||||
for (i=0; s != h->tap_state; i++)
|
||||
{
|
||||
switch (h->tap_state)
|
||||
{
|
||||
/* Special States */
|
||||
case LIBXSVF_TAP_INIT:
|
||||
for (j = 0; j < 6; j++)
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_RESET;
|
||||
break;
|
||||
case LIBXSVF_TAP_RESET:
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IDLE;
|
||||
break;
|
||||
case LIBXSVF_TAP_IDLE:
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DRSELECT;
|
||||
break;
|
||||
|
||||
/* DR States */
|
||||
case LIBXSVF_TAP_DRSELECT:
|
||||
if (s >= LIBXSVF_TAP_IRSELECT || s == LIBXSVF_TAP_RESET) {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IRSELECT;
|
||||
} else {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_DRCAPTURE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_DRCAPTURE:
|
||||
if (s == LIBXSVF_TAP_DRSHIFT) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_DRSHIFT;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DREXIT1;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_DRSHIFT:
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DREXIT1;
|
||||
break;
|
||||
case LIBXSVF_TAP_DREXIT1:
|
||||
if (s == LIBXSVF_TAP_DRPAUSE) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_DRPAUSE;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DRUPDATE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_DRPAUSE:
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DREXIT2;
|
||||
break;
|
||||
case LIBXSVF_TAP_DREXIT2:
|
||||
if (s == LIBXSVF_TAP_DRSHIFT) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_DRSHIFT;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DRUPDATE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_DRUPDATE:
|
||||
if (s == LIBXSVF_TAP_IDLE) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IDLE;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DRSELECT;
|
||||
}
|
||||
break;
|
||||
|
||||
/* IR States */
|
||||
case LIBXSVF_TAP_IRSELECT:
|
||||
if (s == LIBXSVF_TAP_RESET) {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_RESET;
|
||||
} else {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IRCAPTURE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_IRCAPTURE:
|
||||
if (s == LIBXSVF_TAP_IRSHIFT) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IRSHIFT;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IREXIT1;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_IRSHIFT:
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IREXIT1;
|
||||
break;
|
||||
case LIBXSVF_TAP_IREXIT1:
|
||||
if (s == LIBXSVF_TAP_IRPAUSE) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IRPAUSE;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IRUPDATE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_IRPAUSE:
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IREXIT2;
|
||||
break;
|
||||
case LIBXSVF_TAP_IREXIT2:
|
||||
if (s == LIBXSVF_TAP_IRSHIFT) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IRSHIFT;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_IRUPDATE;
|
||||
}
|
||||
break;
|
||||
case LIBXSVF_TAP_IRUPDATE:
|
||||
if (s == LIBXSVF_TAP_IDLE) {
|
||||
tap_transition(h, 0);
|
||||
h->tap_state = LIBXSVF_TAP_IDLE;
|
||||
} else {
|
||||
tap_transition(h, 1);
|
||||
h->tap_state = LIBXSVF_TAP_DRSELECT;
|
||||
}
|
||||
break;
|
||||
|
||||
default:
|
||||
LIBXSVF_HOST_REPORT_ERROR("Illegal tap state.");
|
||||
return -1;
|
||||
}
|
||||
if (h->report_tapstate)
|
||||
LIBXSVF_HOST_REPORT_TAPSTATE();
|
||||
if (i>10) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Loop in tap walker.");
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
@ -0,0 +1,474 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
/* command codes as defined in xilinx xapp503 */
|
||||
enum xsvf_cmd {
|
||||
XCOMPLETE = 0x00,
|
||||
XTDOMASK = 0x01,
|
||||
XSIR = 0x02,
|
||||
XSDR = 0x03,
|
||||
XRUNTEST = 0x04,
|
||||
XREPEAT = 0x07,
|
||||
XSDRSIZE = 0x08,
|
||||
XSDRTDO = 0x09,
|
||||
XSETSDRMASKS = 0x0A,
|
||||
XSDRINC = 0x0B,
|
||||
XSDRB = 0x0C,
|
||||
XSDRC = 0x0D,
|
||||
XSDRE = 0x0E,
|
||||
XSDRTDOB = 0x0F,
|
||||
XSDRTDOC = 0x10,
|
||||
XSDRTDOE = 0x11,
|
||||
XSTATE = 0x12,
|
||||
XENDIR = 0x13,
|
||||
XENDDR = 0x14,
|
||||
XSIR2 = 0x15,
|
||||
XCOMMENT = 0x16,
|
||||
XWAIT = 0x17
|
||||
};
|
||||
|
||||
// This is to not confuse the VIM syntax highlighting
|
||||
#define VAL_OPEN (
|
||||
#define VAL_CLOSE )
|
||||
|
||||
#define READ_BITS(_buf, _len) do { \
|
||||
unsigned char *_p = _buf; int _i; \
|
||||
for (_i=0; _i<(_len); _i+=8) { \
|
||||
int tmp = LIBXSVF_HOST_GETBYTE(); \
|
||||
if (tmp < 0) { \
|
||||
LIBXSVF_HOST_REPORT_ERROR("Unexpected EOF."); \
|
||||
goto error; \
|
||||
} \
|
||||
*(_p++) = tmp; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define READ_LONG() VAL_OPEN{ \
|
||||
long _buf = 0; int _i; \
|
||||
for (_i=0; _i<4; _i++) { \
|
||||
int tmp = LIBXSVF_HOST_GETBYTE(); \
|
||||
if (tmp < 0) { \
|
||||
LIBXSVF_HOST_REPORT_ERROR("Unexpected EOF."); \
|
||||
goto error; \
|
||||
} \
|
||||
_buf = _buf << 8 | tmp; \
|
||||
} \
|
||||
_buf; \
|
||||
}VAL_CLOSE
|
||||
|
||||
#define READ_BYTE() VAL_OPEN{ \
|
||||
int _tmp = LIBXSVF_HOST_GETBYTE(); \
|
||||
if (_tmp < 0) { \
|
||||
LIBXSVF_HOST_REPORT_ERROR("Unexpected EOF."); \
|
||||
goto error; \
|
||||
} \
|
||||
_tmp; \
|
||||
}VAL_CLOSE
|
||||
|
||||
#define SHIFT_DATA(_inp, _outp, _maskp, _len, _state, _estate, _edelay, _ret) do { \
|
||||
if (shift_data(h, _inp, _outp, _maskp, _len, _state, _estate, _edelay, _ret) < 0) { \
|
||||
goto error; \
|
||||
} \
|
||||
} while (0)
|
||||
|
||||
#define TAP(_state) do { \
|
||||
if (libxsvf_tap_walk(h, _state) < 0) \
|
||||
goto error; \
|
||||
} while (0)
|
||||
|
||||
static int bits2bytes(int bits)
|
||||
{
|
||||
return (bits+7) / 8;
|
||||
}
|
||||
|
||||
static int getbit(unsigned char *data, int n)
|
||||
{
|
||||
return (data[n/8] & (1 << (7 - n%8))) ? 1 : 0;
|
||||
}
|
||||
|
||||
static void setbit(unsigned char *data, int n, int v)
|
||||
{
|
||||
unsigned char mask = 1 << (7 - n%8);
|
||||
if (v)
|
||||
data[n/8] |= mask;
|
||||
else
|
||||
data[n/8] &= ~mask;
|
||||
}
|
||||
|
||||
static int xilinx_tap(int state)
|
||||
{
|
||||
/* state codes as defined in xilinx xapp503 */
|
||||
switch (state)
|
||||
{
|
||||
case 0x00:
|
||||
return LIBXSVF_TAP_RESET;
|
||||
break;
|
||||
case 0x01:
|
||||
return LIBXSVF_TAP_IDLE;
|
||||
break;
|
||||
case 0x02:
|
||||
return LIBXSVF_TAP_DRSELECT;
|
||||
break;
|
||||
case 0x03:
|
||||
return LIBXSVF_TAP_DRCAPTURE;
|
||||
break;
|
||||
case 0x04:
|
||||
return LIBXSVF_TAP_DRSHIFT;
|
||||
break;
|
||||
case 0x05:
|
||||
return LIBXSVF_TAP_DREXIT1;
|
||||
break;
|
||||
case 0x06:
|
||||
return LIBXSVF_TAP_DRPAUSE;
|
||||
break;
|
||||
case 0x07:
|
||||
return LIBXSVF_TAP_DREXIT2;
|
||||
break;
|
||||
case 0x08:
|
||||
return LIBXSVF_TAP_DRUPDATE;
|
||||
break;
|
||||
case 0x09:
|
||||
return LIBXSVF_TAP_IRSELECT;
|
||||
break;
|
||||
case 0x0A:
|
||||
return LIBXSVF_TAP_IRCAPTURE;
|
||||
break;
|
||||
case 0x0B:
|
||||
return LIBXSVF_TAP_IRSHIFT;
|
||||
break;
|
||||
case 0x0C:
|
||||
return LIBXSVF_TAP_IREXIT1;
|
||||
break;
|
||||
case 0x0D:
|
||||
return LIBXSVF_TAP_IRPAUSE;
|
||||
break;
|
||||
case 0x0E:
|
||||
return LIBXSVF_TAP_IREXIT2;
|
||||
break;
|
||||
case 0x0F:
|
||||
return LIBXSVF_TAP_IRUPDATE;
|
||||
break;
|
||||
}
|
||||
return -1;
|
||||
}
|
||||
|
||||
static int shift_data(struct libxsvf_host *h, unsigned char *inp, unsigned char *outp, unsigned char *maskp, int len, enum libxsvf_tap_state state, enum libxsvf_tap_state estate, int edelay, int retries)
|
||||
{
|
||||
int left_padding = (8 - len % 8) % 8;
|
||||
int with_retries = retries > 0;
|
||||
int i;
|
||||
|
||||
if (with_retries && LIBXSVF_HOST_SYNC() < 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
while (1)
|
||||
{
|
||||
int tdo_error = 0;
|
||||
int tms = 0;
|
||||
|
||||
TAP(state);
|
||||
tms = 0;
|
||||
|
||||
for (i=len+left_padding-1; i>=left_padding; i--) {
|
||||
if (i == left_padding && h->tap_state != estate) {
|
||||
h->tap_state++;
|
||||
tms = 1;
|
||||
}
|
||||
int tdi = getbit(inp, i);
|
||||
int tdo = -1;
|
||||
if (maskp && getbit(maskp, i))
|
||||
tdo = outp && getbit(outp, i);
|
||||
int sync = with_retries && i == left_padding;
|
||||
if (LIBXSVF_HOST_PULSE_TCK(tms, tdi, tdo, 0, sync) < 0)
|
||||
tdo_error = 1;
|
||||
}
|
||||
|
||||
if (tms)
|
||||
LIBXSVF_HOST_REPORT_TAPSTATE();
|
||||
|
||||
if (edelay) {
|
||||
TAP(LIBXSVF_TAP_IDLE);
|
||||
LIBXSVF_HOST_UDELAY(edelay, 0, edelay);
|
||||
} else {
|
||||
TAP(estate);
|
||||
}
|
||||
|
||||
if (!tdo_error)
|
||||
return 0;
|
||||
|
||||
if (retries <= 0) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch.");
|
||||
return -1;
|
||||
}
|
||||
|
||||
retries--;
|
||||
}
|
||||
|
||||
error:
|
||||
return -1;
|
||||
}
|
||||
|
||||
int libxsvf_xsvf(struct libxsvf_host *h)
|
||||
{
|
||||
int rc = 0;
|
||||
int i, j;
|
||||
|
||||
unsigned char *buf_tdi_data = (void*)0;
|
||||
unsigned char *buf_tdo_data = (void*)0;
|
||||
unsigned char *buf_tdo_mask = (void*)0;
|
||||
unsigned char *buf_addr_mask = (void*)0;
|
||||
unsigned char *buf_data_mask = (void*)0;
|
||||
|
||||
long state_dr_size = 0;
|
||||
long state_data_size = 0;
|
||||
long state_runtest = 0;
|
||||
unsigned char state_xendir = 0;
|
||||
unsigned char state_xenddr = 0;
|
||||
unsigned char state_retries = 0;
|
||||
unsigned char cmd = 0;
|
||||
|
||||
while (1)
|
||||
{
|
||||
unsigned char last_cmd = cmd;
|
||||
cmd = LIBXSVF_HOST_GETBYTE();
|
||||
|
||||
#define STATUS(_c) LIBXSVF_HOST_REPORT_STATUS("XSVF Command " #_c);
|
||||
|
||||
switch (cmd)
|
||||
{
|
||||
case XCOMPLETE: {
|
||||
STATUS(XCOMPLETE);
|
||||
goto got_complete_command;
|
||||
}
|
||||
case XTDOMASK: {
|
||||
STATUS(XTDOMASK);
|
||||
READ_BITS(buf_tdo_mask, state_dr_size);
|
||||
break;
|
||||
}
|
||||
case XSIR: {
|
||||
STATUS(XSIR);
|
||||
int length = READ_BYTE();
|
||||
unsigned char buf[bits2bytes(length)];
|
||||
READ_BITS(buf, length);
|
||||
SHIFT_DATA(buf, (void*)0, (void*)0, length, LIBXSVF_TAP_IRSHIFT,
|
||||
state_xendir ? LIBXSVF_TAP_IRPAUSE : LIBXSVF_TAP_IDLE,
|
||||
state_runtest, state_retries);
|
||||
break;
|
||||
}
|
||||
case XSDR: {
|
||||
STATUS(XSDR);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, buf_tdo_mask, state_dr_size, LIBXSVF_TAP_DRSHIFT,
|
||||
state_xenddr ? LIBXSVF_TAP_DRPAUSE : LIBXSVF_TAP_IDLE,
|
||||
state_runtest, state_retries);
|
||||
break;
|
||||
}
|
||||
case XRUNTEST: {
|
||||
STATUS(XRUNTEST);
|
||||
state_runtest = READ_LONG();
|
||||
break;
|
||||
}
|
||||
case XREPEAT: {
|
||||
STATUS(XREPEAT);
|
||||
state_retries = READ_BYTE();
|
||||
break;
|
||||
}
|
||||
case XSDRSIZE: {
|
||||
STATUS(XSDRSIZE);
|
||||
state_dr_size = READ_LONG();
|
||||
buf_tdi_data = LIBXSVF_HOST_REALLOC(buf_tdi_data, bits2bytes(state_dr_size), LIBXSVF_MEM_XSVF_TDI_DATA);
|
||||
buf_tdo_data = LIBXSVF_HOST_REALLOC(buf_tdo_data, bits2bytes(state_dr_size), LIBXSVF_MEM_XSVF_TDO_DATA);
|
||||
buf_tdo_mask = LIBXSVF_HOST_REALLOC(buf_tdo_mask, bits2bytes(state_dr_size), LIBXSVF_MEM_XSVF_TDO_MASK);
|
||||
buf_addr_mask = LIBXSVF_HOST_REALLOC(buf_addr_mask, bits2bytes(state_dr_size), LIBXSVF_MEM_XSVF_ADDR_MASK);
|
||||
buf_data_mask = LIBXSVF_HOST_REALLOC(buf_data_mask, bits2bytes(state_dr_size), LIBXSVF_MEM_XSVF_DATA_MASK);
|
||||
if (!buf_tdi_data || !buf_tdo_data || !buf_tdo_mask || !buf_addr_mask || !buf_data_mask) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("Allocating memory failed.");
|
||||
goto error;
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XSDRTDO: {
|
||||
STATUS(XSDRTDO);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
READ_BITS(buf_tdo_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, buf_tdo_mask, state_dr_size, LIBXSVF_TAP_DRSHIFT,
|
||||
state_xenddr ? LIBXSVF_TAP_DRPAUSE : LIBXSVF_TAP_IDLE,
|
||||
state_runtest, state_retries);
|
||||
break;
|
||||
}
|
||||
case XSETSDRMASKS: {
|
||||
STATUS(XSETSDRMASKS);
|
||||
READ_BITS(buf_addr_mask, state_dr_size);
|
||||
READ_BITS(buf_data_mask, state_dr_size);
|
||||
state_data_size = 0;
|
||||
for (i=0; i<state_dr_size; i++)
|
||||
state_data_size += getbit(buf_data_mask, i);
|
||||
break;
|
||||
}
|
||||
case XSDRINC: {
|
||||
STATUS(XSDRINC);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
int num = READ_BYTE();
|
||||
while (1) {
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, buf_tdo_mask, state_dr_size, LIBXSVF_TAP_DRSHIFT,
|
||||
state_xenddr ? LIBXSVF_TAP_DRPAUSE : LIBXSVF_TAP_IDLE,
|
||||
state_runtest, state_retries);
|
||||
if (num-- <= 0)
|
||||
break;
|
||||
int carry = 1;
|
||||
for (i=state_dr_size-1; i>=0; i--) {
|
||||
if (getbit(buf_addr_mask, i) == 0)
|
||||
continue;
|
||||
if (getbit(buf_tdi_data, i)) {
|
||||
setbit(buf_tdi_data, i, !carry);
|
||||
} else {
|
||||
setbit(buf_tdi_data, i, carry);
|
||||
carry = 0;
|
||||
}
|
||||
}
|
||||
unsigned char this_byte = 0;
|
||||
for (i=0, j=0; i<state_data_size; i++) {
|
||||
if (i%8 == 0)
|
||||
this_byte = READ_BYTE();
|
||||
while (getbit(buf_data_mask, j) == 0)
|
||||
j++;
|
||||
setbit(buf_tdi_data, j++, getbit(&this_byte, i%8));
|
||||
}
|
||||
}
|
||||
break;
|
||||
}
|
||||
case XSDRB: {
|
||||
STATUS(XSDRB);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, (void*)0, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT, LIBXSVF_TAP_DRSHIFT, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSDRC: {
|
||||
STATUS(XSDRC);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, (void*)0, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT, LIBXSVF_TAP_DRSHIFT, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSDRE: {
|
||||
STATUS(XSDRE);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, (void*)0, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT,
|
||||
state_xenddr ? LIBXSVF_TAP_DRPAUSE : LIBXSVF_TAP_IDLE, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSDRTDOB: {
|
||||
STATUS(XSDRTDOB);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
READ_BITS(buf_tdo_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT, LIBXSVF_TAP_DRSHIFT, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSDRTDOC: {
|
||||
STATUS(XSDRTDOC);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
READ_BITS(buf_tdo_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT, LIBXSVF_TAP_DRSHIFT, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSDRTDOE: {
|
||||
STATUS(XSDRTDOE);
|
||||
READ_BITS(buf_tdi_data, state_dr_size);
|
||||
READ_BITS(buf_tdo_data, state_dr_size);
|
||||
SHIFT_DATA(buf_tdi_data, buf_tdo_data, (void*)0, state_dr_size, LIBXSVF_TAP_DRSHIFT,
|
||||
state_xenddr ? LIBXSVF_TAP_DRPAUSE : LIBXSVF_TAP_IDLE, 0, 0);
|
||||
break;
|
||||
}
|
||||
case XSTATE: {
|
||||
STATUS(XSTATE);
|
||||
if (state_runtest && last_cmd == XRUNTEST) {
|
||||
TAP(LIBXSVF_TAP_IDLE);
|
||||
LIBXSVF_HOST_UDELAY(state_runtest, 0, state_runtest);
|
||||
}
|
||||
unsigned char state = READ_BYTE();
|
||||
TAP(xilinx_tap(state));
|
||||
break;
|
||||
}
|
||||
case XENDIR: {
|
||||
STATUS(XENDIR);
|
||||
state_xendir = READ_BYTE();
|
||||
break;
|
||||
}
|
||||
case XENDDR: {
|
||||
STATUS(XENDDR);
|
||||
state_xenddr = READ_BYTE();
|
||||
break;
|
||||
}
|
||||
case XSIR2: {
|
||||
STATUS(XSIR2);
|
||||
int length = READ_BYTE();
|
||||
length = length << 8 | READ_BYTE();
|
||||
unsigned char buf[bits2bytes(length)];
|
||||
READ_BITS(buf, length);
|
||||
SHIFT_DATA(buf, (void*)0, (void*)0, length, LIBXSVF_TAP_IRSHIFT,
|
||||
state_xendir ? LIBXSVF_TAP_IRPAUSE : LIBXSVF_TAP_IDLE,
|
||||
state_runtest, state_retries);
|
||||
break;
|
||||
}
|
||||
case XCOMMENT: {
|
||||
STATUS(XCOMMENT);
|
||||
unsigned char this_byte;
|
||||
do {
|
||||
this_byte = READ_BYTE();
|
||||
} while (this_byte);
|
||||
break;
|
||||
}
|
||||
case XWAIT: {
|
||||
STATUS(XWAIT);
|
||||
unsigned char state1 = READ_BYTE();
|
||||
unsigned char state2 = READ_BYTE();
|
||||
long usecs = READ_LONG();
|
||||
TAP(xilinx_tap(state1));
|
||||
LIBXSVF_HOST_UDELAY(usecs, 0, 0);
|
||||
TAP(xilinx_tap(state2));
|
||||
break;
|
||||
}
|
||||
default:
|
||||
LIBXSVF_HOST_REPORT_ERROR("Unknown XSVF command.");
|
||||
goto error;
|
||||
}
|
||||
}
|
||||
|
||||
error:
|
||||
rc = -1;
|
||||
|
||||
got_complete_command:
|
||||
if (LIBXSVF_HOST_SYNC() != 0 && rc >= 0 ) {
|
||||
LIBXSVF_HOST_REPORT_ERROR("TDO mismatch.");
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
LIBXSVF_HOST_REALLOC(buf_tdi_data, 0, LIBXSVF_MEM_XSVF_TDI_DATA);
|
||||
LIBXSVF_HOST_REALLOC(buf_tdo_data, 0, LIBXSVF_MEM_XSVF_TDO_DATA);
|
||||
LIBXSVF_HOST_REALLOC(buf_tdo_mask, 0, LIBXSVF_MEM_XSVF_TDO_MASK);
|
||||
LIBXSVF_HOST_REALLOC(buf_addr_mask, 0, LIBXSVF_MEM_XSVF_ADDR_MASK);
|
||||
LIBXSVF_HOST_REALLOC(buf_data_mask, 0, LIBXSVF_MEM_XSVF_DATA_MASK);
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,542 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/** BEGIN: Low-Level I/O Implementation **/
|
||||
|
||||
#ifdef XSVFTOOL_RLMS_VLINE
|
||||
|
||||
// Simple example with MPC8349E GPIO pins
|
||||
// (RIEGL LMS V-Line motherboard)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define IO_PORT_ADDR 0xE0000C00
|
||||
|
||||
struct io_layout {
|
||||
unsigned long tdi:1;
|
||||
unsigned long tdo:1;
|
||||
unsigned long tms:1;
|
||||
unsigned long tck:1;
|
||||
unsigned long reserved:28;
|
||||
};
|
||||
|
||||
static volatile struct io_layout *io_direction;
|
||||
static volatile struct io_layout *io_opendrain;
|
||||
static volatile struct io_layout *io_data;
|
||||
|
||||
static void io_setup(void)
|
||||
{
|
||||
/* open /dev/mem device file */
|
||||
int fd = open("/dev/mem", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Can't open /dev/mem: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* calculate offsets to page and within page */
|
||||
unsigned long psize = getpagesize();
|
||||
unsigned long off_inpage = IO_PORT_ADDR % psize;
|
||||
unsigned long off_topage = IO_PORT_ADDR - off_inpage;
|
||||
unsigned long mapsize = off_inpage + sizeof(struct io_layout) * 3;
|
||||
|
||||
/* map it into logical memory */
|
||||
void *io_addr_map = mmap(0, mapsize, PROT_WRITE, MAP_SHARED, fd, off_topage);
|
||||
if (io_addr_map == MAP_FAILED) {
|
||||
fprintf(stderr, "Can't map physical memory: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* calculate register addresses */
|
||||
io_direction = io_addr_map + off_inpage;
|
||||
io_opendrain = io_addr_map + off_inpage + 4;
|
||||
io_data = io_addr_map + off_inpage + 8;
|
||||
|
||||
/* set direction reg */
|
||||
io_direction->tms = 1;
|
||||
io_direction->tck = 1;
|
||||
io_direction->tdo = 0;
|
||||
io_direction->tdi = 1;
|
||||
|
||||
/* set open drain reg */
|
||||
io_opendrain->tms = 0;
|
||||
io_opendrain->tck = 0;
|
||||
io_opendrain->tdo = 0;
|
||||
io_opendrain->tdi = 0;
|
||||
|
||||
#ifdef HAVE_TRST
|
||||
/* for boards with TRST, must be driven high */
|
||||
io_data->trst = 1;
|
||||
io_direction->trst = 1;
|
||||
io_opendrain->trst = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void io_shutdown(void)
|
||||
{
|
||||
/* set all to z-state */
|
||||
io_direction->tms = 0;
|
||||
io_direction->tck = 0;
|
||||
io_direction->tdo = 0;
|
||||
io_direction->tdi = 0;
|
||||
|
||||
#ifdef HAVE_TRST
|
||||
/* for boards with TRST, assuming there is a pull-down resistor */
|
||||
io_direction->trst = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void io_tms(int val)
|
||||
{
|
||||
io_data->tms = val;
|
||||
}
|
||||
|
||||
static void io_tdi(int val)
|
||||
{
|
||||
io_data->tdi = val;
|
||||
}
|
||||
|
||||
static void io_tck(int val)
|
||||
{
|
||||
io_data->tck = val;
|
||||
// usleep(1);
|
||||
}
|
||||
|
||||
static void io_sck(int val)
|
||||
{
|
||||
/* not available */
|
||||
}
|
||||
|
||||
static void io_trst(int val)
|
||||
{
|
||||
/* not available */
|
||||
}
|
||||
|
||||
static int io_tdo()
|
||||
{
|
||||
return io_data->tdo ? 1 : 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void io_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tms(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tdi(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tck(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_sck(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_trst(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static int io_tdo()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** END: Low-Level I/O Implementation **/
|
||||
|
||||
|
||||
struct udata_s {
|
||||
FILE *f;
|
||||
int verbose;
|
||||
int clockcount;
|
||||
int bitcount_tdi;
|
||||
int bitcount_tdo;
|
||||
int retval_i;
|
||||
int retval[256];
|
||||
};
|
||||
|
||||
static int h_setup(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[SETUP]\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
io_setup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h_shutdown(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[SHUTDOWN]\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
io_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck);
|
||||
fflush(stderr);
|
||||
}
|
||||
if (num_tck > 0) {
|
||||
struct timeval tv1, tv2;
|
||||
gettimeofday(&tv1, NULL);
|
||||
io_tms(tms);
|
||||
while (num_tck > 0) {
|
||||
io_tck(0);
|
||||
io_tck(1);
|
||||
num_tck--;
|
||||
}
|
||||
gettimeofday(&tv2, NULL);
|
||||
if (tv2.tv_sec > tv1.tv_sec) {
|
||||
usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
|
||||
tv1.tv_usec = 0;
|
||||
}
|
||||
usecs -= tv2.tv_usec - tv1.tv_usec;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
if (usecs > 0) {
|
||||
usleep(usecs);
|
||||
}
|
||||
}
|
||||
|
||||
static int h_getbyte(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
return fgetc(u->f);
|
||||
}
|
||||
|
||||
static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
|
||||
io_tms(tms);
|
||||
|
||||
if (tdi >= 0) {
|
||||
u->bitcount_tdi++;
|
||||
io_tdi(tdi);
|
||||
}
|
||||
|
||||
io_tck(0);
|
||||
io_tck(1);
|
||||
|
||||
int line_tdo = io_tdo();
|
||||
int rc = line_tdo >= 0 ? line_tdo : 0;
|
||||
|
||||
if (rmask == 1 && u->retval_i < 256)
|
||||
u->retval[u->retval_i++] = line_tdo;
|
||||
|
||||
if (tdo >= 0 && line_tdo >= 0) {
|
||||
u->bitcount_tdo++;
|
||||
if (tdo != line_tdo)
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc);
|
||||
}
|
||||
|
||||
u->clockcount++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void h_pulse_sck(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[SCK]\n");
|
||||
}
|
||||
io_sck(0);
|
||||
io_sck(1);
|
||||
}
|
||||
|
||||
static void h_set_trst(struct libxsvf_host *h, int v)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[TRST:%d]\n", v);
|
||||
}
|
||||
io_trst(v);
|
||||
}
|
||||
|
||||
static int h_set_frequency(struct libxsvf_host *h, int v)
|
||||
{
|
||||
fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h_report_tapstate(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state));
|
||||
}
|
||||
}
|
||||
|
||||
static void h_report_device(struct libxsvf_host *h, unsigned long idcode)
|
||||
{
|
||||
// struct udata_s *u = h->user_data;
|
||||
printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
|
||||
(idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
|
||||
}
|
||||
|
||||
static void h_report_status(struct libxsvf_host *h, const char *message)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[STATUS] %s\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] %s\n", file, line, message);
|
||||
}
|
||||
|
||||
static int realloc_maxsize[LIBXSVF_MEM_NUM];
|
||||
|
||||
static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (size > realloc_maxsize[which])
|
||||
realloc_maxsize[which] = size;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size);
|
||||
}
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static struct udata_s u;
|
||||
|
||||
static struct libxsvf_host h = {
|
||||
.udelay = h_udelay,
|
||||
.setup = h_setup,
|
||||
.shutdown = h_shutdown,
|
||||
.getbyte = h_getbyte,
|
||||
.pulse_tck = h_pulse_tck,
|
||||
.pulse_sck = h_pulse_sck,
|
||||
.set_trst = h_set_trst,
|
||||
.set_frequency = h_set_frequency,
|
||||
.report_tapstate = h_report_tapstate,
|
||||
.report_device = h_report_device,
|
||||
.report_status = h_report_status,
|
||||
.report_error = h_report_error,
|
||||
.realloc = h_realloc,
|
||||
.user_data = &u
|
||||
};
|
||||
|
||||
const char *progname;
|
||||
|
||||
static void copyleft()
|
||||
{
|
||||
static int already_printed = 0;
|
||||
if (already_printed)
|
||||
return;
|
||||
fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>\n");
|
||||
fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n");
|
||||
already_printed = 1;
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
copyleft();
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -r funcname\n");
|
||||
fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -v, -vv, -vvv, -vvvv\n");
|
||||
fprintf(stderr, " Verbose, more verbose and even more verbose\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -L, -B\n");
|
||||
fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -s svf-file\n");
|
||||
fprintf(stderr, " Play the specified SVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -x xsvf-file\n");
|
||||
fprintf(stderr, " Play the specified XSVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -c\n");
|
||||
fprintf(stderr, " List devices in JTAG chain\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
int gotaction = 0;
|
||||
int hex_mode = 0;
|
||||
const char *realloc_name = NULL;
|
||||
int opt, i, j;
|
||||
|
||||
progname = argc >= 1 ? argv[0] : "xvsftool";
|
||||
while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'r':
|
||||
realloc_name = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
copyleft();
|
||||
u.verbose++;
|
||||
break;
|
||||
case 'x':
|
||||
case 's':
|
||||
gotaction = 1;
|
||||
if (u.verbose)
|
||||
fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
if (!strcmp(optarg, "-"))
|
||||
u.f = stdin;
|
||||
else
|
||||
u.f = fopen(optarg, "rb");
|
||||
if (u.f == NULL) {
|
||||
fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
|
||||
fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
rc = 1;
|
||||
}
|
||||
if (strcmp(optarg, "-"))
|
||||
fclose(u.f);
|
||||
break;
|
||||
case 'c':
|
||||
gotaction = 1;
|
||||
if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
|
||||
fprintf(stderr, "Error while scanning JTAG chain.\n");
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
hex_mode = 1;
|
||||
break;
|
||||
case 'B':
|
||||
hex_mode = 2;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotaction)
|
||||
help();
|
||||
|
||||
if (u.verbose) {
|
||||
fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount);
|
||||
fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi);
|
||||
fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo);
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "Finished without errors.\n");
|
||||
} else {
|
||||
fprintf(stderr, "Finished with errors!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (u.retval_i) {
|
||||
if (hex_mode) {
|
||||
printf("0x");
|
||||
for (i=0; i < u.retval_i; i+=4) {
|
||||
int val = 0;
|
||||
for (j=i; j<i+4; j++)
|
||||
val = val << 1 | u.retval[hex_mode > 1 ? j : u.retval_i - j - 1];
|
||||
printf("%x", val);
|
||||
}
|
||||
} else {
|
||||
printf("%d rmask bits:", u.retval_i);
|
||||
for (i=0; i < u.retval_i; i++)
|
||||
printf(" %d", u.retval[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (realloc_name) {
|
||||
int num = 0;
|
||||
for (i = 0; i < LIBXSVF_MEM_NUM; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
num = i+1;
|
||||
}
|
||||
printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]);
|
||||
}
|
||||
printf("\tstatic unsigned char *buflist[%d] = {", num);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i));
|
||||
else
|
||||
printf("%s(void*)0", i ? ", " : " ");
|
||||
}
|
||||
printf(" };\n\tstatic int sizelist[%d] = {", num);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i));
|
||||
else
|
||||
printf("%s0", i ? ", " : " ");
|
||||
}
|
||||
printf(" };\n");
|
||||
printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num);
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -0,0 +1,113 @@
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 44
|
||||
/libxsvf/!svn/ver/59/trunk/xsvftool-xpcu.src
|
||||
END
|
||||
prep_erasecpld.svf
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 63
|
||||
/libxsvf/!svn/ver/51/trunk/xsvftool-xpcu.src/prep_erasecpld.svf
|
||||
END
|
||||
fx2.h
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 50
|
||||
/libxsvf/!svn/ver/32/trunk/xsvftool-xpcu.src/fx2.h
|
||||
END
|
||||
fx2usb-interface.c
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 63
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/fx2usb-interface.c
|
||||
END
|
||||
prep_firmware.ihx
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 62
|
||||
/libxsvf/!svn/ver/52/trunk/xsvftool-xpcu.src/prep_firmware.ihx
|
||||
END
|
||||
fx2usb-interface.h
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 63
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/fx2usb-interface.h
|
||||
END
|
||||
firmware.c
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 55
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/firmware.c
|
||||
END
|
||||
README
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 51
|
||||
/libxsvf/!svn/ver/59/trunk/xsvftool-xpcu.src/README
|
||||
END
|
||||
gpifprog.c
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 55
|
||||
/libxsvf/!svn/ver/32/trunk/xsvftool-xpcu.src/gpifprog.c
|
||||
END
|
||||
genfx2hrd.sh
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 57
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/genfx2hrd.sh
|
||||
END
|
||||
hardware.v
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 55
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/hardware.v
|
||||
END
|
||||
hardware.sh
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 56
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/hardware.sh
|
||||
END
|
||||
fx2regs.h
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 54
|
||||
/libxsvf/!svn/ver/32/trunk/xsvftool-xpcu.src/fx2regs.h
|
||||
END
|
||||
hardware.ucf
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 57
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/hardware.ucf
|
||||
END
|
||||
reset-probe-impact.sh
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 66
|
||||
/libxsvf/!svn/ver/51/trunk/xsvftool-xpcu.src/reset-probe-impact.sh
|
||||
END
|
||||
Makefile
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 53
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/Makefile
|
||||
END
|
||||
prep_hardware.svf
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 62
|
||||
/libxsvf/!svn/ver/51/trunk/xsvftool-xpcu.src/prep_hardware.svf
|
||||
END
|
||||
fx2sdly.h
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 54
|
||||
/libxsvf/!svn/ver/32/trunk/xsvftool-xpcu.src/fx2sdly.h
|
||||
END
|
||||
xsvftool-xpcu.c
|
||||
K 25
|
||||
svn:wc:ra_dav:version-url
|
||||
V 60
|
||||
/libxsvf/!svn/ver/58/trunk/xsvftool-xpcu.src/xsvftool-xpcu.c
|
||||
END
|
@ -0,0 +1,53 @@
|
||||
K 10
|
||||
svn:ignore
|
||||
V 656
|
||||
*.d
|
||||
hardware.gyd
|
||||
hardware.ngr
|
||||
firmware.map
|
||||
firmware.mem
|
||||
hardware.lso
|
||||
firmware.asm
|
||||
hardware.xml
|
||||
hardware.bld
|
||||
firmware.rel
|
||||
_impactbatch.log
|
||||
tmperr.err
|
||||
xsvftool-xpcu
|
||||
hardware.chk
|
||||
hardware.mfd
|
||||
hardware.vm6
|
||||
hardware.syr
|
||||
hardware.xst
|
||||
xilinx
|
||||
hardware_pad.csv
|
||||
gpifprog_fixed.c
|
||||
firmware.lst
|
||||
hardware_html
|
||||
firmware.sym
|
||||
firmware.rst
|
||||
hardware.prj
|
||||
hardware_xst.xrpt
|
||||
hardware.svf
|
||||
hardware.cxt
|
||||
xlnx_auto_0_xdb
|
||||
hardware.jed
|
||||
hardware.cmd
|
||||
firmware.lnk
|
||||
hardware.pad
|
||||
_xmsgs
|
||||
hardware.rpt
|
||||
hardware_ngdbuild.xrpt
|
||||
hardware.pnx
|
||||
firmware.ihx
|
||||
hardware.ngc
|
||||
hardware.ngd
|
||||
hardware_build.xml
|
||||
hardware.log
|
||||
hardware_cksum_c.inc
|
||||
hardware_cksum_vl.inc
|
||||
filedata.h
|
||||
erasecpld.svf
|
||||
erasecpld.cmd
|
||||
|
||||
END
|
@ -0,0 +1,97 @@
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
USE_PREP_FIRMWARE = 1
|
||||
USE_PREP_HARDWARE = 1
|
||||
|
||||
LIBXSVFDIR=..
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -Werror -Os -ggdb -I$(LIBXSVFDIR) -MD
|
||||
LDFLAGS = -L$(LIBXSVFDIR)
|
||||
LDLIBS = -lusb -lreadline -lxsvf
|
||||
|
||||
SDCC = sdcc
|
||||
SDCFLAGS = -mmcs51 --xram-loc 0x2000
|
||||
|
||||
all: xsvftool-xpcu
|
||||
|
||||
xsvftool-xpcu: filedata.h hardware_cksum_c.inc $(LIBXSVFDIR)/libxsvf.a xsvftool-xpcu.o fx2usb-interface.o
|
||||
$(CC) $(LDFLAGS) xsvftool-xpcu.o fx2usb-interface.o $(LDLIBS) -o $@
|
||||
|
||||
hardware.svf erasecpld.svf: hardware.sh hardware.ucf hardware.v hardware_cksum_vl.inc
|
||||
ifeq ($(USE_PREP_HARDWARE),1)
|
||||
cp prep_hardware.svf hardware.svf
|
||||
cp prep_erasecpld.svf erasecpld.svf
|
||||
else
|
||||
bash hardware.sh
|
||||
endif
|
||||
|
||||
firmware.ihx: firmware.c
|
||||
ifeq ($(USE_PREP_FIRMWARE),1)
|
||||
cp prep_firmware.ihx firmware.ihx
|
||||
else
|
||||
cpp -MD -MF $(basename $<).d -MT $(basename $<).ihx -o /dev/null $<
|
||||
$(SDCC) $(SDCFLAGS) $<
|
||||
endif
|
||||
|
||||
firmware.ihx: gpifprog_fixed.c
|
||||
gpifprog_fixed.c: gpifprog.c
|
||||
sed 's/ xdata / /g;' < $< > $@
|
||||
|
||||
$(LIBXSVFDIR)/libxsvf.a:
|
||||
$(MAKE) -C $(LIBXSVFDIR) libxsvf.a
|
||||
|
||||
hardware_cksum_vl.inc hardware_cksum_c.inc: hardware.sh hardware.ucf hardware.v
|
||||
echo "'h$$(cat $^ | md5sum | cut -c1-6 | tr a-z A-Z)" > hardware_cksum_vl.inc
|
||||
echo "\"$$(cat $^ | md5sum | cut -c1-6 | tr a-z A-Z)\"" > hardware_cksum_c.inc
|
||||
|
||||
filedata.h: hardware.svf erasecpld.svf firmware.ihx
|
||||
{ echo "unsigned char hardware_svf[] = { " && perl -pe 's/(.)/ord($$1).","/sge' hardware.svf && echo "};" && \
|
||||
echo "unsigned char erasecpld_svf[] = { " && perl -pe 's/(.)/ord($$1).","/sge' erasecpld.svf && echo "};" && \
|
||||
echo "unsigned char firmware_ihx[] = { " && perl -pe 's/(.)/ord($$1).","/sge' firmware.ihx && echo "};"; } | \
|
||||
perl -pe 's/(.{70}.*?,)/$$1\n/g' > filedata.h_new
|
||||
mv filedata.h_new filedata.h
|
||||
|
||||
prep:
|
||||
make clean
|
||||
sed -i '/^USE_PREP_/ s/1/0/;' Makefile
|
||||
make hardware.svf firmware.ihx
|
||||
cp hardware.svf prep_hardware.svf
|
||||
cp erasecpld.svf prep_erasecpld.svf
|
||||
cp firmware.ihx prep_firmware.ihx
|
||||
sed -i '/^USE_PREP_/ s/0/1/;' Makefile
|
||||
make clean
|
||||
|
||||
clean:
|
||||
rm -f firmware.asm firmware.lnk firmware.lst firmware.map
|
||||
rm -f firmware.mem firmware.rel firmware.rst firmware.sym
|
||||
rm -f hardware.bld hardware_build.xml hardware.chk hardware.cmd
|
||||
rm -f hardware.log hardware.lso hardware.mfd hardware.ngc hardware.ngd
|
||||
rm -f hardware_ngdbuild.xrpt hardware.ngr hardware.pad hardware_pad.csv
|
||||
rm -f hardware.pnx hardware.prj hardware.rpt hardware.svf hardware.syr
|
||||
rm -f hardware.vm6 hardware.xml hardware.xst hardware_xst.xrpt
|
||||
rm -f hardware.cxt hardware.gyd hardware.jed _impactbatch.log tmperr.err
|
||||
rm -f hardware_cksum_vl.inc hardware_cksum_c.inc gpifprog_fixed.c
|
||||
rm -rf hardware_html xilinx xlnx_auto_0_xdb _xmsgs
|
||||
rm -f filedata.h firmware.ihx erasecpld.cmd erasecpld.svf
|
||||
rm -f xsvftool-xpcu core *.o *.d
|
||||
|
||||
-include *.d
|
||||
|
@ -0,0 +1,173 @@
|
||||
|
||||
xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
==================================================================
|
||||
|
||||
This program can be used to play SVF and XSVF files on the "Xilinx
|
||||
Platform Cable USB" family of JTAG probes.
|
||||
|
||||
It is based on the libxsvf library:
|
||||
http://www.clifford.at/libxsvf/
|
||||
|
||||
This tool replaces the original CPLD firmware from Xilinx when run
|
||||
on one of the probes. See the notes below on how to restore the Xilinx
|
||||
firmware on the CPLD.
|
||||
|
||||
The file 'firmware.c' also contains a brief description of the pin mappings
|
||||
between the the Cypress CY7C68013A-100AIX and the Xilinx XC2C256-7VQ100
|
||||
on the probe as used by this software, as well as a brief description of
|
||||
the USB protocol this software is using.
|
||||
|
||||
With this software it is possible to use JTAG clock speeds up to 24 MHz.
|
||||
But with the high frequencies there are "gaps" in the transmission resulting
|
||||
in an effective transfer rate of approx 6 MBit/s.
|
||||
|
||||
This tool contains firmware for the CY7C68013A-100AIX (firmware.c) and for the
|
||||
XC2C256-7VQ100 (hardware.v) on the probe. Some more exotic tools are needed to
|
||||
build these. So pre-compiled versions of this firmware images are distributed
|
||||
along with the xsvftool-xpcu source code. You need to set the USE_PREP_* config
|
||||
options in the Makefile to '0' if you prefer building the firmware yourself.
|
||||
|
||||
|
||||
xsvftool-xpcu vs. Xilinx USB cable driver
|
||||
-----------------------------------------
|
||||
|
||||
When installed, the Xilinx "USB cable driver" tries to load its own FX2 firmware
|
||||
to the probes as soon as the probe is connected to the system. Once the Xilinx
|
||||
firmware is loaded into the probe the probe can't be accessed using xsvftool-xpcu.
|
||||
|
||||
So in order to use xsvftool-xpcu with a probe you need to uninstall or disable
|
||||
the Xilinx driver. This can usually be done by commenting out the udev rules in
|
||||
the /etc/udev/rules.d/xusbdfwu.rules file.
|
||||
|
||||
A probe that shows up as 03fd:0008 in the lsusb output is running the Xilinx
|
||||
firmware. You won't be able to access this probe with xsvftool-xpcu unless you
|
||||
deactivate the Xilinx driver as explained above, disconnect the probe from the
|
||||
PC and reconnect it.
|
||||
|
||||
You can always load the Xilinx FX2 firmware in the probe manually without using
|
||||
the udev rules (see "fxload" examples below).
|
||||
|
||||
|
||||
Supported and unsupported hardware
|
||||
----------------------------------
|
||||
|
||||
This software has been tested using the following probes:
|
||||
|
||||
- A Xilinx Platform Cable USB
|
||||
- The on-board probe of a Spartan-6 development board
|
||||
- A self-built clone of the Xilinx Platform Cable USB
|
||||
|
||||
Per default the software recognizes the following USB vendor IDs and device IDs
|
||||
(VID:PID) as a supported probe:
|
||||
|
||||
03fd:0009 Xilinx Platform Cable USB
|
||||
03fd:000d Xilinx Platform Cable USB (embedded)
|
||||
03fd:000f Xilinx Platform Cable USB (low power)
|
||||
04b4:8613 Cypress FX2 without configuration PROM
|
||||
|
||||
Currently there is no support for the "Xilinx Platform Cable USB II" in this
|
||||
software.
|
||||
|
||||
|
||||
Notes on device permissions
|
||||
---------------------------
|
||||
|
||||
To run xsvftool-xpcu as unprivileged user you need to set the permissions on
|
||||
the USB device accordingly. E.g.:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 002 Device 021: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ sudo chmod 0666 /dev/bus/usb/002/021
|
||||
|
||||
$ ./xsvftool-xpcu -Pc
|
||||
Scanning JTAG chain..
|
||||
idcode=0x16d4a093, revision=0x1, part=0x6d4a, manufactor=0x049
|
||||
Total number of JTAG clock cycles performed: 79
|
||||
READY.
|
||||
|
||||
Instead of doing this manually each time the device is connected one might
|
||||
prefer to create a udev rule that does set the permissions automatically:
|
||||
|
||||
$ sudo vi /etc/udev/rules.d/xsvftool-xpcu.rules
|
||||
# Allow everyone access to the Xilinx Platform Cable USB (see 'man 7 udev' for details)
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0008", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0009", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000d", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000f", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="8613", MODE:="0666"
|
||||
|
||||
NOTE: The line for 03fd:0008 is for the re-enumerated device when the original
|
||||
Xilinx firmware is used on the probe. It is not used nor needed when using
|
||||
xsvftool-xpcu exclusively, but isn't harmful either.
|
||||
|
||||
|
||||
Restore Xilinx CPLD Firmware with "xsvftool-xpcu"
|
||||
-------------------------------------------------
|
||||
|
||||
The Xilinx ISE comes with XSVF files for programming the CPLD with the Xilinx
|
||||
firmware. You can simply use "xsvftool-xpcu" to program the CPLD to the original
|
||||
firmware:
|
||||
|
||||
$ ./xsvftool-xpcu -P -x /opt/Xilinx/13.1/ISE_DS/ISE/data/xusb_emb.fmwr
|
||||
|
||||
After that you need to disconnect and reconnect the probe before you can load
|
||||
the Xilinx FX2 firmware and use the probe with impact:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 001 Device 106: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ fxload -t fx2 -D /dev/bus/usb/001/106 -I /opt/Xilinx/13.1/ISE_DS/ISE/bin/lin/xusb_emb.hex
|
||||
|
||||
### usually you need to wait a few seconds here for the device to re-enumerate and settle ###
|
||||
$ lsusb -d 03fd:0008
|
||||
Bus 001 Device 108: ID 03fd:0008 Xilinx, Inc.
|
||||
|
||||
### just scan the JTAG chain to test the probe ###
|
||||
$ /opt/Xilinx/13.1/ISE_DS/ISE/bin/lin/impact -batch /dev/null
|
||||
> setMode -bs
|
||||
> setCable -port usb21
|
||||
> identify
|
||||
> quit
|
||||
|
||||
NOTE: Use the *.hex file from the "ISE/bin/lin/" directory! It is different
|
||||
from the one in the "ISE/data/" directory and only this one seams to work.
|
||||
|
||||
|
||||
Restore Xilinx CPLD Firmware with "impact"
|
||||
------------------------------------------
|
||||
|
||||
Up to ISE 11 the Xilinx "impact" program did automatically reprogram the CPLD on
|
||||
the probe whenever needed. Since ISE 12 this does only work when there is already
|
||||
an (older) Xilinx firmware on the probe. So in order to reprogram the CPLD on
|
||||
the probe with "impact" you need ISE 11 installed. Then it is possible to
|
||||
reprogram the CPLD just by loading the fx2 firmware and running impact on the
|
||||
probe:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 002 Device 021: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ fxload -t fx2 -D /dev/bus/usb/002/021 -I /opt/Xilinx/11.3/ISE/bin/lin/xusb_emb.hex
|
||||
|
||||
### usually you need to wait a few seconds here for the device to re-enumerate and settle ###
|
||||
$ lsusb -d 03fd:0008
|
||||
Bus 002 Device 022: ID 03fd:0008 Xilinx, Inc.
|
||||
|
||||
$ vi impatch_batch.cmd
|
||||
setMode -bs
|
||||
setCable -port usb21
|
||||
quit
|
||||
|
||||
### this automatically reprograms the CPLD without doing anything else with the probe ###
|
||||
$ /opt/Xilinx/11.3/ISE/bin/lin/impact -batch impatch_batch.cmd
|
||||
|
||||
The "reset-probe.sh" shell script in this directory (libxsvf/xsvftool-xpcu.src/)
|
||||
does this automatically:
|
||||
|
||||
$ bash reset-probe-impact.sh
|
||||
|
||||
WARNING: For some reason this procedure fails when the probe has been used with
|
||||
xsvftool-xpcu between being connected to USB and loading xusb_emb.hex into the
|
||||
FX2. So disconnect and reconnect the probe before running the reset-probe.sh
|
||||
script!
|
||||
|
@ -0,0 +1,782 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command Reference (EP1)
|
||||
* -----------------------
|
||||
*
|
||||
* Request: T<nn>
|
||||
* Response: OK (T<nn>)
|
||||
* Configure timing for EP2/JTAG transfers
|
||||
*
|
||||
* Request: R
|
||||
* Response: OK (R)
|
||||
* Perform internal and CPLD reset
|
||||
*
|
||||
* Request: W<n>
|
||||
* Response: OK (W<n>)
|
||||
* Wait for the CPLD sync signal to become <n>
|
||||
*
|
||||
* Request: C
|
||||
* Response: <nnnnnn> (C)
|
||||
* Read out the CPLD verilog checksum
|
||||
*
|
||||
* Request: B<n>
|
||||
* Response: OK (B<n>)
|
||||
* Set BUFFER_OE to <n>
|
||||
*
|
||||
* Request: I<n>
|
||||
* Response: OK (I<n>)
|
||||
* Set INIT_INT to <n>
|
||||
*
|
||||
* Request: S
|
||||
* Response: <n><m><k><p><x><y><s> (S)
|
||||
* Read and reset status bits
|
||||
* (<n> = FX2-JTAG-ERR, <m> = CPLD-JTAG-ERR, <k> = INIT_B_INT,
|
||||
* <p> = SLOE_INT, <x> = FX2-JTAG-TDO, <y> = CPLD-JTAG-TDO, <s> = SYNC)
|
||||
*
|
||||
* Request: P
|
||||
* Response: <n><m><k><p><x><y><s> (P)
|
||||
* Peek status bits without resetting them
|
||||
*
|
||||
* Request: J<bindata>
|
||||
* Response: -- NONE --
|
||||
* Execute JTAG transaction (4bit/cycle)
|
||||
*
|
||||
* Request: X
|
||||
* Response: OK (X)
|
||||
* Exit. Restore FX2 default settings and enter endless loop
|
||||
*
|
||||
*
|
||||
* Target JTAG Programming (EP2)
|
||||
* -----------------------------
|
||||
*
|
||||
* Raw JTAG transaction codes.
|
||||
* (4bit/cycle when T=0, 8bit/cycle otherwise)
|
||||
*
|
||||
*
|
||||
* JTAG Transaction codes
|
||||
* ----------------------
|
||||
*
|
||||
* 0000:
|
||||
* NOP
|
||||
*
|
||||
* 0001 xxxx:
|
||||
* Set sync signal to 'xxxx' (engine on CPLD only)
|
||||
*
|
||||
* 001x:
|
||||
* reserved for future use
|
||||
*
|
||||
* 01xy:
|
||||
* JTAG transaction without TDO check. TMS=x, TDI=y
|
||||
*
|
||||
* 1zxy:
|
||||
* JTAG transaction with TDO check. TDO=z, TMS=x, TDI=y
|
||||
*
|
||||
*
|
||||
* FX2 <-> CPLD Interface
|
||||
* ----------------------
|
||||
*
|
||||
* FD[7:0] ---> FD[7:0]
|
||||
* CTL0 ---> STROBE_FD (neg)
|
||||
* CTL1 ---> STROBE_SHIFT (neg)
|
||||
* CTL2 ---> STROBE_PUSH (neg)
|
||||
*
|
||||
* PC[7:4] <--- SYNC
|
||||
* PC3 <--- TDO
|
||||
* PC2 <--- CKSUM
|
||||
* PC1 <--- INIT_B_INT
|
||||
* PC0 <--- ERR
|
||||
*
|
||||
* PD4 ---> RESET_SYNC
|
||||
* PD3 ---> RESET_ERR
|
||||
* PD2 ---> INIT_INT
|
||||
* PD1 ---> SHIFT_CKSUM
|
||||
* PD0 ---> RESET_CKSUM
|
||||
*
|
||||
*
|
||||
* Other FX2 Connections
|
||||
* ---------------------
|
||||
*
|
||||
* PA0 ---> LED_GREEN
|
||||
* PA1 ---> LED_RED
|
||||
* PA2 <--- SLOE_INT
|
||||
* PA3 ---> CPLD_PWR
|
||||
* PA5 ---> BUFFER_OE
|
||||
*
|
||||
* IOE[3] ---> CPLD TCK
|
||||
* IOE[4] ---> CPLD TMS
|
||||
* IOE[5] <--- CPLD TDO
|
||||
* IOE[6] ---> CPLD TDI
|
||||
*
|
||||
*/
|
||||
|
||||
// #include "fx2.h"
|
||||
// #include "fx2regs.h"
|
||||
// #include "fx2sdly.h"
|
||||
#include "gpifprog_fixed.c"
|
||||
|
||||
// set to '1' on CPLD JTAG error
|
||||
BYTE state_err;
|
||||
|
||||
// use quad buffering and larger buffers
|
||||
#define ALL_RESOURCES_ON_EP2
|
||||
|
||||
void sleep3us(void)
|
||||
{
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
}
|
||||
|
||||
void msleep(WORD ms)
|
||||
{
|
||||
WORD i;
|
||||
while (ms-- > 0) {
|
||||
for (i = 0; i < 1000; i += 3)
|
||||
sleep3us();
|
||||
}
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
BYTE i;
|
||||
|
||||
/* CPU: 48MHz, don't drive CLKOUT */
|
||||
CPUCS = 0x10;
|
||||
|
||||
#ifdef ALL_RESOURCES_ON_EP2
|
||||
/* Configure the Endpoints (EP2 => 4x 1kB) */
|
||||
EP2CFG = 0xA8; // VALID=1, DIR=0, TYPE=10, SIZE=1, BUF=00
|
||||
EP4CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
EP6CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
EP8CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
#else
|
||||
/* Configure the Endpoints (default config) */
|
||||
EP2CFG = 0xA2; // VALID=1, DIR=0, TYPE=10, SIZE=0, BUF=10
|
||||
EP4CFG = 0xA0; // VALID=1, DIR=0, TYPE=10, SIZE=0, BUF=00
|
||||
EP6CFG = 0xA2; // VALID=1, DIR=1, TYPE=10, SIZE=0, BUF=10
|
||||
EP8CFG = 0xA0; // VALID=1, DIR=1, TYPE=10, SIZE=0, BUF=00
|
||||
#endif
|
||||
|
||||
/* USB FIFO */
|
||||
FIFORESET = 0x80;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 2;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 4;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 6;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 8;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 0;
|
||||
SYNCDELAY;
|
||||
|
||||
/* Set WORDWIDE=0 for all FIFOs */
|
||||
EP2FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP4FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP6FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP8FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
|
||||
/* Initialize GPIF Subsystem */
|
||||
GpifInit();
|
||||
|
||||
/* Misc signals on port A */
|
||||
PORTACFG = 0;
|
||||
OEA = bmBIT0 | bmBIT1 | bmBIT3 | bmBIT5;
|
||||
IOA = 0;
|
||||
|
||||
/* FX2 <-> CPLD signals on port C */
|
||||
PORTCCFG = 0;
|
||||
OEC = 0;
|
||||
IOC = 0;
|
||||
|
||||
/* FX2 <-> CPLD signals on port D */
|
||||
OED = bmBIT0 | bmBIT1 | bmBIT2 | bmBIT3 | bmBIT4;
|
||||
IOD = 0;
|
||||
|
||||
/* TURN ON CPLD VCC */
|
||||
PA3 = 1;
|
||||
msleep(100);
|
||||
|
||||
/* XC2S256 JTAG on port E */
|
||||
OEE = bmBIT3|bmBIT4|bmBIT6;
|
||||
IOE = bmBIT3|bmBIT4|bmBIT6;
|
||||
|
||||
/* Set TAP to logic reset state */
|
||||
for (i=0; i<16; i++) {
|
||||
// TMS is high - just generate a few TCK pulses
|
||||
sleep3us();
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
}
|
||||
|
||||
/* All set up: Let the host find out about the new EP config */
|
||||
#if 0
|
||||
USBCS |= bmDISCON;
|
||||
msleep(10);
|
||||
USBCS &= ~bmDISCON;
|
||||
#endif
|
||||
}
|
||||
|
||||
void unsetup(void)
|
||||
{
|
||||
WORD i, j;
|
||||
|
||||
/* 1st TURN OFF CPLD VCC */
|
||||
PA3 = 0;
|
||||
msleep(100);
|
||||
|
||||
/*
|
||||
* Restore default configuration as good as possible
|
||||
*
|
||||
* The idea is that one could load the xilinx firmware without
|
||||
* the need to reconnect. Unfortunately it doesn't work. Something
|
||||
* important is still different between the FX2 after reset and
|
||||
* after running this unsetup() function.
|
||||
*/
|
||||
|
||||
GPIFABORT = 0xFF;
|
||||
SYNCDELAY;
|
||||
|
||||
CPUCS = 0x02;
|
||||
SYNCDELAY;
|
||||
IFCONFIG = 0x80;
|
||||
SYNCDELAY;
|
||||
|
||||
EP2CFG = 0xA2;
|
||||
SYNCDELAY;
|
||||
EP4CFG = 0xA0;
|
||||
SYNCDELAY;
|
||||
EP6CFG = 0xA2;
|
||||
SYNCDELAY;
|
||||
EP8CFG = 0xA0;
|
||||
SYNCDELAY;
|
||||
|
||||
EP2FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP4FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP6FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP8FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
|
||||
FIFORESET = 0x80;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 2;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 4;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 6;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 8;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 0;
|
||||
SYNCDELAY;
|
||||
|
||||
IOA = 0;
|
||||
IOC = 0;
|
||||
IOD = 0;
|
||||
IOE = 0;
|
||||
|
||||
OEA = 0;
|
||||
OEC = 0;
|
||||
OED = 0;
|
||||
OEE = 0;
|
||||
|
||||
PORTACFG = 0;
|
||||
PORTCCFG = 0;
|
||||
|
||||
OEA = 1;
|
||||
for (i=0; i<3; i++) {
|
||||
PA0 = 1;
|
||||
for (j=0; j<3000; j++) sleep3us();
|
||||
PA1 = 0;
|
||||
for (j=0; j<3000; j++) sleep3us();
|
||||
}
|
||||
OEA = 0;
|
||||
|
||||
// just ack everything and wait
|
||||
while (1) {
|
||||
if((EP1OUTCS & bmBIT1) == 0) {
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
}
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BYTE nibble2hex(BYTE v)
|
||||
{
|
||||
return "0123456789ABCDEF"[v&0x0f];
|
||||
}
|
||||
|
||||
BYTE hex2nibble(BYTE v)
|
||||
{
|
||||
if (v >= '0' && v <= '9')
|
||||
return v - '0';
|
||||
if (v >= 'a' && v <= 'f')
|
||||
return 0x0A + v - 'a';
|
||||
if (v >= 'A' && v <= 'F')
|
||||
return 0x0A + v - 'A';
|
||||
return 0;
|
||||
}
|
||||
|
||||
xdata at (0xE400 + 64) volatile BYTE GPIF_WAVE2_LEN0;
|
||||
xdata at (0xE400 + 66) volatile BYTE GPIF_WAVE2_LEN2;
|
||||
|
||||
void proc_command_t(BYTE t)
|
||||
{
|
||||
if (t == 0) {
|
||||
GPIFWFSELECT = 0x4E; SYNCDELAY;
|
||||
} else {
|
||||
GPIFWFSELECT = 0x4A; SYNCDELAY;
|
||||
GPIF_WAVE2_LEN0 = t; SYNCDELAY;
|
||||
GPIF_WAVE2_LEN2 = t; SYNCDELAY;
|
||||
}
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[5] = nibble2hex((t >> 4) & 0x0f); SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex((t >> 0) & 0x0f); SYNCDELAY;
|
||||
EP1INBUF[7] = ')'; SYNCDELAY;
|
||||
EP1INBC = 8; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_r(void)
|
||||
{
|
||||
BYTE i, *p = "OK (R)";
|
||||
|
||||
/* Reset TAP to logic reset state */
|
||||
IOE = bmBIT3|bmBIT4|bmBIT6;
|
||||
for (i=0; i<16; i++) {
|
||||
// TMS is high - just generate a few TCK pulses
|
||||
sleep3us();
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
}
|
||||
|
||||
/* Reset speed to max. */
|
||||
GPIFWFSELECT = 0x4E; SYNCDELAY;
|
||||
|
||||
/* Reset JTAG error state */
|
||||
state_err = 0;
|
||||
|
||||
/* Reset LEDs and BUFFER_OE */
|
||||
PA0 = PA1 = PA5 = 0;
|
||||
|
||||
/* Assert CPLD reset pins */
|
||||
IOD = bmBIT0 | bmBIT3 | bmBIT4;
|
||||
SYNCDELAY;
|
||||
IOD |= bmBIT1;
|
||||
SYNCDELAY;
|
||||
IOD = 0;
|
||||
|
||||
/* Send response */
|
||||
for (i = 0; p[i]; i++) {
|
||||
EP1INBUF[i] = p[i]; SYNCDELAY;
|
||||
}
|
||||
EP1INBC = i; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_bulkdata(void);
|
||||
|
||||
void proc_command_w_ok(BYTE v)
|
||||
{
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'W'; SYNCDELAY;
|
||||
EP1INBUF[5] = nibble2hex(v); SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_w_timeout(BYTE v)
|
||||
{
|
||||
EP1INBUF[0] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'I'; SYNCDELAY;
|
||||
EP1INBUF[2] = 'M'; SYNCDELAY;
|
||||
EP1INBUF[3] = 'E'; SYNCDELAY;
|
||||
EP1INBUF[4] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[5] = 'U'; SYNCDELAY;
|
||||
EP1INBUF[6] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[7] = '!'; SYNCDELAY;
|
||||
EP1INBUF[8] = ' '; SYNCDELAY;
|
||||
EP1INBUF[9] = 'S'; SYNCDELAY;
|
||||
EP1INBUF[10] = '='; SYNCDELAY;
|
||||
EP1INBUF[11] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[12] = ' '; SYNCDELAY;
|
||||
EP1INBUF[13] = '('; SYNCDELAY;
|
||||
EP1INBUF[14] = 'W'; SYNCDELAY;
|
||||
EP1INBUF[15] = nibble2hex(v); SYNCDELAY;
|
||||
EP1INBUF[16] = ')'; SYNCDELAY;
|
||||
EP1INBC = 17; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_w(BYTE v)
|
||||
{
|
||||
WORD i, j;
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
for (j = 0; j < 1000; j++)
|
||||
{
|
||||
/* check for wait condition */
|
||||
if ((IOC >> 4) == v) {
|
||||
proc_command_w_ok(v);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for data on EP2 */
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
PA0 = 1;
|
||||
proc_bulkdata();
|
||||
PA0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
proc_command_w_timeout(v);
|
||||
}
|
||||
|
||||
void proc_command_c(void)
|
||||
{
|
||||
BYTE i, j, buf;
|
||||
|
||||
/* Reset chksum register */
|
||||
PD0 = 1;
|
||||
PD1 = 0;
|
||||
SYNCDELAY;
|
||||
PD1 = 1;
|
||||
SYNCDELAY;
|
||||
PD0 = 0;
|
||||
PD1 = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
buf = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
buf = buf << 1 | PC2;
|
||||
SYNCDELAY;
|
||||
PD1 = 1;
|
||||
SYNCDELAY;
|
||||
PD1 = 0;
|
||||
}
|
||||
EP1INBUF[i] = nibble2hex(buf); SYNCDELAY;
|
||||
}
|
||||
|
||||
EP1INBUF[6] = ' '; SYNCDELAY;
|
||||
EP1INBUF[7] = '('; SYNCDELAY;
|
||||
EP1INBUF[8] = 'C'; SYNCDELAY;
|
||||
EP1INBUF[9] = ')'; SYNCDELAY;
|
||||
EP1INBC = 10; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_b(BYTE v)
|
||||
{
|
||||
PA5 = v;
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'B'; SYNCDELAY;
|
||||
EP1INBUF[5] = v ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_i(BYTE v)
|
||||
{
|
||||
PD2 = v;
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'I'; SYNCDELAY;
|
||||
EP1INBUF[5] = v ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_s(void)
|
||||
{
|
||||
EP1INBUF[0] = PC0 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[1] = state_err ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[2] = PC1 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[3] = PA2 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[4] = PC3 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[5] = (IOE & bmBIT5) ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[7] = ' '; SYNCDELAY;
|
||||
EP1INBUF[8] = '('; SYNCDELAY;
|
||||
EP1INBUF[9] = 'S'; SYNCDELAY;
|
||||
EP1INBUF[10] = ')'; SYNCDELAY;
|
||||
EP1INBC = 11; SYNCDELAY;
|
||||
|
||||
// reset error state
|
||||
state_err = 0;
|
||||
IOD = bmBIT3;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
IOD &= ~bmBIT3;
|
||||
}
|
||||
|
||||
void proc_command_p(void)
|
||||
{
|
||||
EP1INBUF[0] = PC0 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[1] = state_err ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[2] = PC1 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[3] = PA2 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[4] = PC3 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[5] = (IOE & bmBIT5) ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[7] = ' '; SYNCDELAY;
|
||||
EP1INBUF[8] = '('; SYNCDELAY;
|
||||
EP1INBUF[9] = 'P'; SYNCDELAY;
|
||||
EP1INBUF[10] = ')'; SYNCDELAY;
|
||||
EP1INBC = 11; SYNCDELAY;
|
||||
}
|
||||
|
||||
BYTE proc_command_j_exec_skip_next;
|
||||
void proc_command_j_exec(BYTE cmd)
|
||||
{
|
||||
if (proc_command_j_exec_skip_next) {
|
||||
proc_command_j_exec_skip_next = 0;
|
||||
return;
|
||||
}
|
||||
if (cmd == 0x00)
|
||||
return;
|
||||
if (cmd == 0x01) {
|
||||
// 0001 xxxx: Set sync signal to 'xxxx' (engine on CPLD only)
|
||||
proc_command_j_exec_skip_next = 1;
|
||||
return;
|
||||
}
|
||||
if ((cmd & 0x0c) == 0x04)
|
||||
{
|
||||
// 01xy: JTAG transaction without TDO check. TMS=x, TDI=y
|
||||
|
||||
/* set tms line */
|
||||
if (cmd & 0x02)
|
||||
IOE |= bmBIT4;
|
||||
else
|
||||
IOE &= ~bmBIT4;
|
||||
|
||||
/* set tdi line */
|
||||
if (cmd & 0x01)
|
||||
IOE |= bmBIT6;
|
||||
else
|
||||
IOE &= ~bmBIT6;
|
||||
|
||||
/* generate tck pulse */
|
||||
SYNCDELAY;
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
SYNCDELAY;
|
||||
|
||||
return;
|
||||
}
|
||||
if ((cmd & 0x08) == 0x08)
|
||||
{
|
||||
// 1zxy: JTAG transaction with TDO check. TDO=z, TMS=x, TDI=y
|
||||
|
||||
/* set tms line */
|
||||
if (cmd & 0x02)
|
||||
IOE |= bmBIT4;
|
||||
else
|
||||
IOE &= ~bmBIT4;
|
||||
|
||||
/* set tdi line */
|
||||
if (cmd & 0x01)
|
||||
IOE |= bmBIT6;
|
||||
else
|
||||
IOE &= ~bmBIT6;
|
||||
|
||||
/* generate tck pulse */
|
||||
SYNCDELAY;
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
SYNCDELAY;
|
||||
|
||||
/* perform tdo check */
|
||||
if (((cmd & 0x04) == 0) != ((IOE & bmBIT5) == 0))
|
||||
state_err = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void proc_command_j(BYTE len)
|
||||
{
|
||||
BYTE i;
|
||||
proc_command_j_exec_skip_next = 0;
|
||||
for (i = 1; i < len; i++) {
|
||||
BYTE cmd = EP1OUTBUF[i];
|
||||
proc_command_j_exec(cmd & 0x0f);
|
||||
proc_command_j_exec(cmd >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
void proc_command_x(void)
|
||||
{
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'X'; SYNCDELAY;
|
||||
EP1INBUF[5] = ')'; SYNCDELAY;
|
||||
EP1INBC = 6; SYNCDELAY;
|
||||
|
||||
/* accept new data on EP1OUT */
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
|
||||
unsetup();
|
||||
}
|
||||
|
||||
void proc_command(void)
|
||||
{
|
||||
BYTE len, cmd;
|
||||
|
||||
/* process command(s) */
|
||||
len = EP1OUTBC;
|
||||
cmd = EP1OUTBUF[0];
|
||||
|
||||
if (cmd == 'T' && len == 3)
|
||||
proc_command_t((hex2nibble(EP1OUTBUF[1]) << 4) | hex2nibble(EP1OUTBUF[2]));
|
||||
else if (cmd == 'R' && len == 1)
|
||||
proc_command_r();
|
||||
else if (cmd == 'W' && len == 2)
|
||||
proc_command_w(hex2nibble(EP1OUTBUF[1]));
|
||||
else if (cmd == 'C' && len == 1)
|
||||
proc_command_c();
|
||||
else if (cmd == 'B' && len == 2)
|
||||
proc_command_b(EP1OUTBUF[1] == '1');
|
||||
else if (cmd == 'I' && len == 2)
|
||||
proc_command_i(EP1OUTBUF[1] == '1');
|
||||
else if (cmd == 'S' && len == 1)
|
||||
proc_command_s();
|
||||
else if (cmd == 'P' && len == 1)
|
||||
proc_command_p();
|
||||
else if (cmd == 'J')
|
||||
proc_command_j(len);
|
||||
else if (cmd == 'X')
|
||||
proc_command_x();
|
||||
else
|
||||
{
|
||||
/* send error response */
|
||||
EP1INBUF[0] = 'E'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[2] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[3] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[4] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[5] = '!'; SYNCDELAY;
|
||||
EP1INBC = 6; SYNCDELAY;
|
||||
}
|
||||
|
||||
/* accept new data on EP1OUT */
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_bulkdata(void)
|
||||
{
|
||||
WORD len;
|
||||
|
||||
len = (EP2BCH << 8) | EP2BCL;
|
||||
if (len == 0)
|
||||
{
|
||||
/* ignore this and accept data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
#if 0
|
||||
else if (len == 1)
|
||||
{
|
||||
while ((GPIFTRIG & 0x80) == 0) { /* GPIF is busy */ }
|
||||
|
||||
/* transfer single byte */
|
||||
XGPIFSGLDATH = 0; SYNCDELAY;
|
||||
XGPIFSGLDATLX = EP2FIFOBUF[0]; SYNCDELAY;
|
||||
|
||||
/* accept new data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
while ((GPIFTRIG & 0x80) == 0) { /* GPIF is busy */ }
|
||||
|
||||
/* pass pkt to GPIF master */
|
||||
EP2GPIFTCH = EP2BCH;
|
||||
EP2GPIFTCL = EP2BCL;
|
||||
EP2BCL = 0x00;
|
||||
EP2GPIFTRIG = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
state_err = 0;
|
||||
|
||||
setup();
|
||||
|
||||
/* accept data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY; // 1st buffer
|
||||
EP2BCL = 0xff; SYNCDELAY; // 2nd buffer
|
||||
#ifdef ALL_RESOURCES_ON_EP2
|
||||
EP2BCL = 0xff; SYNCDELAY; // 3rd buffer
|
||||
EP2BCL = 0xff; SYNCDELAY; // 4th buffer
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* check for data on EP1 */
|
||||
if((EP1OUTCS & bmBIT1) == 0) {
|
||||
PA1 = 1;
|
||||
proc_command();
|
||||
PA1 = 0;
|
||||
}
|
||||
|
||||
/* check for data on EP2 */
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
PA0 = 1;
|
||||
proc_bulkdata();
|
||||
PA0 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,332 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: FX2.h
|
||||
// Contents: EZ-USB FX2/FX2LP/FX1 constants, macros, datatypes, globals, and library
|
||||
// function prototypes.
|
||||
//
|
||||
// $Archive: /USB/Target/Inc/Fx2.h $
|
||||
// $Date: 3/23/05 2:30p $
|
||||
// $Revision: 16 $
|
||||
//
|
||||
// Copyright (c) 2005 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef FX2_H //Header sentry
|
||||
#define FX2_H
|
||||
|
||||
#define INTERNAL_DSCR_ADDR 0x0080 // Relocate Descriptors to 0x80
|
||||
#define bmSTRETCH 0x07
|
||||
#define FW_STRETCH_VALUE 0x0 // Set stretch to 0 in frameworks
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define bmBIT0 0x01
|
||||
#define bmBIT1 0x02
|
||||
#define bmBIT2 0x04
|
||||
#define bmBIT3 0x08
|
||||
#define bmBIT4 0x10
|
||||
#define bmBIT5 0x20
|
||||
#define bmBIT6 0x40
|
||||
#define bmBIT7 0x80
|
||||
|
||||
#define DEVICE_DSCR 0x01 // Descriptor type: Device
|
||||
#define CONFIG_DSCR 0x02 // Descriptor type: Configuration
|
||||
#define STRING_DSCR 0x03 // Descriptor type: String
|
||||
#define INTRFC_DSCR 0x04 // Descriptor type: Interface
|
||||
#define ENDPNT_DSCR 0x05 // Descriptor type: End Point
|
||||
#define DEVQUAL_DSCR 0x06 // Descriptor type: Device Qualifier
|
||||
#define OTHERSPEED_DSCR 0x07 // Descriptor type: Other Speed Configuration
|
||||
|
||||
#define bmBUSPWR bmBIT7 // Config. attribute: Bus powered
|
||||
#define bmSELFPWR bmBIT6 // Config. attribute: Self powered
|
||||
#define bmRWU bmBIT5 // Config. attribute: Remote Wakeup
|
||||
|
||||
#define bmEPOUT bmBIT7
|
||||
#define bmEPIN 0x00
|
||||
|
||||
#define EP_CONTROL 0x00 // End Point type: Control
|
||||
#define EP_ISO 0x01 // End Point type: Isochronous
|
||||
#define EP_BULK 0x02 // End Point type: Bulk
|
||||
#define EP_INT 0x03 // End Point type: Interrupt
|
||||
|
||||
#define SUD_SIZE 8 // Setup data packet size
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//Added for HID
|
||||
|
||||
#define SETUP_MASK 0x60 //Used to mask off request type
|
||||
#define SETUP_STANDARD_REQUEST 0 //Standard Request
|
||||
#define SETUP_CLASS_REQUEST 0x20 //Class Request
|
||||
#define SETUP_VENDOR_REQUEST 0x40 //Vendor Request
|
||||
#define SETUP_RESERVED_REQUEST 0x60 //Reserved or illegal request
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define SC_GET_STATUS 0x00 // Setup command: Get Status
|
||||
#define SC_CLEAR_FEATURE 0x01 // Setup command: Clear Feature
|
||||
#define SC_RESERVED 0x02 // Setup command: Reserved
|
||||
#define SC_SET_FEATURE 0x03 // Setup command: Set Feature
|
||||
#define SC_SET_ADDRESS 0x05 // Setup command: Set Address
|
||||
#define SC_GET_DESCRIPTOR 0x06 // Setup command: Get Descriptor
|
||||
#define SC_SET_DESCRIPTOR 0x07 // Setup command: Set Descriptor
|
||||
#define SC_GET_CONFIGURATION 0x08 // Setup command: Get Configuration
|
||||
#define SC_SET_CONFIGURATION 0x09 // Setup command: Set Configuration
|
||||
#define SC_GET_INTERFACE 0x0a // Setup command: Get Interface
|
||||
#define SC_SET_INTERFACE 0x0b // Setup command: Set Interface
|
||||
#define SC_SYNC_FRAME 0x0c // Setup command: Sync Frame
|
||||
#define SC_ANCHOR_LOAD 0xa0 // Setup command: Anchor load
|
||||
|
||||
#define GD_DEVICE 0x01 // Get descriptor: Device
|
||||
#define GD_CONFIGURATION 0x02 // Get descriptor: Configuration
|
||||
#define GD_STRING 0x03 // Get descriptor: String
|
||||
#define GD_INTERFACE 0x04 // Get descriptor: Interface
|
||||
#define GD_ENDPOINT 0x05 // Get descriptor: Endpoint
|
||||
#define GD_DEVICE_QUALIFIER 0x06 // Get descriptor: Device Qualifier
|
||||
#define GD_OTHER_SPEED_CONFIGURATION 0x07 // Get descriptor: Other Configuration
|
||||
#define GD_INTERFACE_POWER 0x08 // Get descriptor: Interface Power
|
||||
#define GD_HID 0x21 // Get descriptor: HID
|
||||
#define GD_REPORT 0x22 // Get descriptor: Report
|
||||
|
||||
#define GS_DEVICE 0x80 // Get Status: Device
|
||||
#define GS_INTERFACE 0x81 // Get Status: Interface
|
||||
#define GS_ENDPOINT 0x82 // Get Status: End Point
|
||||
|
||||
#define FT_DEVICE 0x00 // Feature: Device
|
||||
#define FT_ENDPOINT 0x02 // Feature: End Point
|
||||
|
||||
#define I2C_IDLE 0 // I2C Status: Idle mode
|
||||
#define I2C_SENDING 1 // I2C Status: I2C is sending data
|
||||
#define I2C_RECEIVING 2 // I2C Status: I2C is receiving data
|
||||
#define I2C_PRIME 3 // I2C Status: I2C is receiving the first byte of a string
|
||||
#define I2C_STOP 5 // I2C Status: I2C waiting for stop completion
|
||||
#define I2C_BERROR 6 // I2C Status: I2C error; Bit Error
|
||||
#define I2C_NACK 7 // I2C Status: I2C error; No Acknowledge
|
||||
#define I2C_OK 8 // I2C positive return code
|
||||
#define I2C_WAITSTOP 9 // I2C Status: Wait for STOP complete
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Macros
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MSB(word) (BYTE)(((WORD)(word) >> 8) & 0xff)
|
||||
#define LSB(word) (BYTE)((WORD)(word) & 0xff)
|
||||
|
||||
#define SWAP_ENDIAN(word) ((BYTE*)&word)[0] ^= ((BYTE*)&word)[1];\
|
||||
((BYTE*)&word)[1] ^= ((BYTE*)&word)[0];\
|
||||
((BYTE*)&word)[0] ^= ((BYTE*)&word)[1]
|
||||
|
||||
#define EZUSB_IRQ_ENABLE() EUSB = 1
|
||||
#define EZUSB_IRQ_DISABLE() EUSB = 0
|
||||
#define EZUSB_IRQ_CLEAR() EXIF &= ~0x10 // IE2_
|
||||
|
||||
#define EZUSB_STALL_EP0() EP0CS |= bmEPSTALL
|
||||
|
||||
// WRITEDELAY() has been replaced by SYNCDELAY; macro in fx2sdly.h
|
||||
// ...it is here for backwards compatibility...
|
||||
|
||||
// the WRITEDELAY macro compiles to the time equivalent of 3 NOPs.
|
||||
// It is used in the frameworks to allow for write recovery time
|
||||
// requirements of certain registers. This is only necessary for
|
||||
// EZ-USB FX parts. See the EZ-USB FX TRM for
|
||||
// more information on write recovery time issues.
|
||||
#define WRITEDELAY() {char writedelaydummy = 0;}
|
||||
// if this firmware will never run on an EZ-USB FX part replace
|
||||
// with:
|
||||
// #define WRITEDELAY()
|
||||
|
||||
// macro to reset and endpoint data toggle
|
||||
#define EZUSB_RESET_DATA_TOGGLE(ep) TOGCTL = (((ep & 0x80) >> 3) + (ep & 0x0F));\
|
||||
TOGCTL |= bmRESETTOGGLE
|
||||
|
||||
|
||||
#define EZUSB_ENABLE_RSMIRQ() (EICON |= 0x20) // Enable Resume Interrupt (EPFI_)
|
||||
#define EZUSB_DISABLE_RSMIRQ() (EICON &= ~0x20) // Disable Resume Interrupt (EPFI_)
|
||||
#define EZUSB_CLEAR_RSMIRQ() (EICON &= ~0x10) // Clear Resume Interrupt Flag (PFI_)
|
||||
|
||||
#define EZUSB_GETI2CSTATUS() (I2CPckt.status)
|
||||
#define EZUSB_CLEARI2CSTATUS() if((I2CPckt.status == I2C_BERROR) || (I2CPckt.status == I2C_NACK))\
|
||||
I2CPckt.status = I2C_IDLE;
|
||||
|
||||
#define EZUSB_ENABLEBP() (BREAKPT |= bmBPEN)
|
||||
#define EZUSB_DISABLEBP() (BREAKPT &= ~bmBPEN)
|
||||
#define EZUSB_CLEARBP() (BREAKPT |= bmBREAK)
|
||||
#define EZUSB_BP(addr) BPADDRH = (BYTE)(((WORD)addr >> 8) & 0xff);\
|
||||
BPADDRL = (BYTE)addr
|
||||
|
||||
#define EZUSB_EXTWAKEUP() (((WAKEUPCS & bmWU2) && (WAKEUPCS & bmWU2EN)) ||\
|
||||
((WAKEUPCS & bmWU) && (WAKEUPCS & bmWUEN)))
|
||||
|
||||
#define EZUSB_HIGHSPEED() (USBCS & bmHSM)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datatypes
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef bit BOOL;
|
||||
|
||||
#define INT0_VECT 0
|
||||
#define TMR0_VECT 1
|
||||
#define INT1_VECT 2
|
||||
#define TMR1_VECT 3
|
||||
#define COM0_VECT 4
|
||||
#define TMR2_VECT 5
|
||||
#define WKUP_VECT 6
|
||||
#define COM1_VECT 7
|
||||
#define USB_VECT 8
|
||||
#define I2C_VECT 9
|
||||
#define INT4_VECT 10
|
||||
#define INT5_VECT 11
|
||||
#define INT6_VECT 12
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length;
|
||||
BYTE type;
|
||||
}DSCR;
|
||||
|
||||
typedef struct // Device Descriptor
|
||||
{
|
||||
BYTE length; // Descriptor length ( = sizeof(DEVICEDSCR) )
|
||||
BYTE type; // Decriptor type (Device = 1)
|
||||
BYTE spec_ver_minor; // Specification Version (BCD) minor
|
||||
BYTE spec_ver_major; // Specification Version (BCD) major
|
||||
BYTE dev_class; // Device class
|
||||
BYTE sub_class; // Device sub-class
|
||||
BYTE protocol; // Device sub-sub-class
|
||||
BYTE max_packet; // Maximum packet size
|
||||
WORD vendor_id; // Vendor ID
|
||||
WORD product_id; // Product ID
|
||||
WORD version_id; // Product version ID
|
||||
BYTE mfg_str; // Manufacturer string index
|
||||
BYTE prod_str; // Product string index
|
||||
BYTE serialnum_str; // Serial number string index
|
||||
BYTE configs; // Number of configurations
|
||||
}DEVICEDSCR;
|
||||
|
||||
typedef struct // Device Qualifier Descriptor
|
||||
{
|
||||
BYTE length; // Descriptor length ( = sizeof(DEVICEQUALDSCR) )
|
||||
BYTE type; // Decriptor type (Device Qualifier = 6)
|
||||
BYTE spec_ver_minor; // Specification Version (BCD) minor
|
||||
BYTE spec_ver_major; // Specification Version (BCD) major
|
||||
BYTE dev_class; // Device class
|
||||
BYTE sub_class; // Device sub-class
|
||||
BYTE protocol; // Device sub-sub-class
|
||||
BYTE max_packet; // Maximum packet size
|
||||
BYTE configs; // Number of configurations
|
||||
BYTE reserved0;
|
||||
}DEVICEQUALDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // Configuration length ( = sizeof(CONFIGDSCR) )
|
||||
BYTE type; // Descriptor type (Configuration = 2)
|
||||
WORD config_len; // Configuration + End Points length
|
||||
BYTE interfaces; // Number of interfaces
|
||||
BYTE index; // Configuration number
|
||||
BYTE config_str; // Configuration string
|
||||
BYTE attrib; // Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu
|
||||
BYTE power; // Power requirement (div 2 ma)
|
||||
}CONFIGDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // Interface descriptor length ( - sizeof(INTRFCDSCR) )
|
||||
BYTE type; // Descriptor type (Interface = 4)
|
||||
BYTE index; // Zero-based index of this interface
|
||||
BYTE alt_setting; // Alternate setting
|
||||
BYTE ep_cnt; // Number of end points
|
||||
BYTE class; // Interface class
|
||||
BYTE sub_class; // Interface sub class
|
||||
BYTE protocol; // Interface sub sub class
|
||||
BYTE interface_str; // Interface descriptor string index
|
||||
}INTRFCDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // End point descriptor length ( = sizeof(ENDPNTDSCR) )
|
||||
BYTE type; // Descriptor type (End point = 5)
|
||||
BYTE addr; // End point address
|
||||
BYTE ep_type; // End point type
|
||||
BYTE mp_L; // Maximum packet size
|
||||
BYTE mp_H;
|
||||
BYTE interval; // Interrupt polling interval
|
||||
}ENDPNTDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // String descriptor length
|
||||
BYTE type; // Descriptor type
|
||||
}STRINGDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE cntrl; // End point control register
|
||||
BYTE bytes; // End point buffer byte count
|
||||
}EPIOC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length;
|
||||
BYTE *dat;
|
||||
BYTE count;
|
||||
BYTE status;
|
||||
}I2CPCKT;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals
|
||||
//-----------------------------------------------------------------------------
|
||||
extern code BYTE USB_AutoVector;
|
||||
|
||||
extern WORD pDeviceDscr;
|
||||
extern WORD pDeviceQualDscr;
|
||||
extern WORD pHighSpeedConfigDscr;
|
||||
extern WORD pFullSpeedConfigDscr;
|
||||
extern WORD pConfigDscr;
|
||||
extern WORD pOtherConfigDscr;
|
||||
extern WORD pStringDscr;
|
||||
|
||||
extern code DEVICEDSCR DeviceDscr;
|
||||
extern code DEVICEQUALDSCR DeviceQualDscr;
|
||||
extern code CONFIGDSCR HighSpeedConfigDscr;
|
||||
extern code CONFIGDSCR FullSpeedConfigDscr;
|
||||
extern code STRINGDSCR StringDscr;
|
||||
extern code DSCR UserDscr;
|
||||
|
||||
extern I2CPCKT I2CPckt;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function Prototypes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern void EZUSB_Renum(void);
|
||||
extern void EZUSB_Discon(BOOL renum);
|
||||
|
||||
extern void EZUSB_Susp(void);
|
||||
extern void EZUSB_Resume(void);
|
||||
|
||||
extern void EZUSB_Delay1ms(void);
|
||||
extern void EZUSB_Delay(WORD ms);
|
||||
|
||||
extern CONFIGDSCR xdata* EZUSB_GetConfigDscr(BYTE ConfigIdx);
|
||||
extern INTRFCDSCR xdata* EZUSB_GetIntrfcDscr(BYTE ConfigIdx, BYTE IntrfcIdx, BYTE AltSetting);
|
||||
extern STRINGDSCR xdata* EZUSB_GetStringDscr(BYTE StrIdx);
|
||||
extern DSCR xdata* EZUSB_GetDscr(BYTE index, DSCR* dscr, BYTE type);
|
||||
|
||||
extern void EZUSB_InitI2C(void);
|
||||
extern BOOL EZUSB_WriteI2C_(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_ReadI2C_(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_WriteI2C(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_ReadI2C(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern void EZUSB_WaitForEEPROMWrite(BYTE addr);
|
||||
|
||||
extern void modify_endpoint_stall(BYTE epid, BYTE stall);
|
||||
|
||||
#endif // FX2_H
|
@ -0,0 +1,687 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: FX2regs.h
|
||||
// Contents: EZ-USB FX2/FX2LP/FX1 register declarations and bit mask definitions.
|
||||
//
|
||||
// $Archive: /USB/Target/Inc/fx2regs.h $
|
||||
// $Date: 4/13/05 4:29p $
|
||||
// $Revision: 42 $
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2005 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef FX2REGS_H /* Header Sentry */
|
||||
#define FX2REGS_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FX2/FX2LP/FX1 Related Register Assignments
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The Ez-USB FX2/FX2LP/FX1 registers are defined here. We use fx2regs.h for register
|
||||
// address allocation by using "#define ALLOCATE_EXTERN".
|
||||
// When using "#define ALLOCATE_EXTERN", you get (for instance):
|
||||
// xdata volatile BYTE OUT7BUF[64] _at_ 0x7B40;
|
||||
// Such lines are created from FX2.h by using the preprocessor.
|
||||
// Incidently, these lines will not generate any space in the resulting hex
|
||||
// file; they just bind the symbols to the addresses for compilation.
|
||||
// You just need to put "#define ALLOCATE_EXTERN" in your main program file;
|
||||
// i.e. fw.c or a stand-alone C source file.
|
||||
// Without "#define ALLOCATE_EXTERN", you just get the external reference:
|
||||
// extern xdata volatile BYTE OUT7BUF[64] ;// 0x7B40;
|
||||
// This uses the concatenation operator "##" to insert a comment "//"
|
||||
// to cut off the end of the line, "_at_ 0x7B40;", which is not wanted.
|
||||
|
||||
#ifdef ALLOCATE_EXTERN
|
||||
#define EXTERN
|
||||
#define _AT_ _at_
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#define _AT_ ;/ ## /
|
||||
#endif
|
||||
|
||||
xdata at 0xE400 volatile BYTE GPIF_WAVE_DATA;
|
||||
xdata at 0xE480 volatile BYTE RES_WAVEDATA_END;
|
||||
|
||||
// General Configuration
|
||||
|
||||
xdata at 0xE600 volatile BYTE CPUCS; // Control & Status
|
||||
xdata at 0xE601 volatile BYTE IFCONFIG; // Interface Configuration
|
||||
xdata at 0xE602 volatile BYTE PINFLAGSAB; // FIFO FLAGA and FLAGB Assignments
|
||||
xdata at 0xE603 volatile BYTE PINFLAGSCD; // FIFO FLAGC and FLAGD Assignments
|
||||
xdata at 0xE604 volatile BYTE FIFORESET; // Restore FIFOS to default state
|
||||
xdata at 0xE605 volatile BYTE BREAKPT; // Breakpoint
|
||||
xdata at 0xE606 volatile BYTE BPADDRH; // Breakpoint Address H
|
||||
xdata at 0xE607 volatile BYTE BPADDRL; // Breakpoint Address L
|
||||
xdata at 0xE608 volatile BYTE UART230; // 230 Kbaud clock for T0,T1,T2
|
||||
xdata at 0xE609 volatile BYTE FIFOPINPOLAR; // FIFO polarities
|
||||
xdata at 0xE60A volatile BYTE REVID; // Chip Revision
|
||||
xdata at 0xE60B volatile BYTE REVCTL; // Chip Revision Control
|
||||
|
||||
// Endpoint Configuration
|
||||
|
||||
xdata at 0xE610 volatile BYTE EP1OUTCFG; // Endpoint 1-OUT Configuration
|
||||
xdata at 0xE611 volatile BYTE EP1INCFG; // Endpoint 1-IN Configuration
|
||||
xdata at 0xE612 volatile BYTE EP2CFG; // Endpoint 2 Configuration
|
||||
xdata at 0xE613 volatile BYTE EP4CFG; // Endpoint 4 Configuration
|
||||
xdata at 0xE614 volatile BYTE EP6CFG; // Endpoint 6 Configuration
|
||||
xdata at 0xE615 volatile BYTE EP8CFG; // Endpoint 8 Configuration
|
||||
xdata at 0xE618 volatile BYTE EP2FIFOCFG; // Endpoint 2 FIFO configuration
|
||||
xdata at 0xE619 volatile BYTE EP4FIFOCFG; // Endpoint 4 FIFO configuration
|
||||
xdata at 0xE61A volatile BYTE EP6FIFOCFG; // Endpoint 6 FIFO configuration
|
||||
xdata at 0xE61B volatile BYTE EP8FIFOCFG; // Endpoint 8 FIFO configuration
|
||||
xdata at 0xE620 volatile BYTE EP2AUTOINLENH; // Endpoint 2 Packet Length H (IN only)
|
||||
xdata at 0xE621 volatile BYTE EP2AUTOINLENL; // Endpoint 2 Packet Length L (IN only)
|
||||
xdata at 0xE622 volatile BYTE EP4AUTOINLENH; // Endpoint 4 Packet Length H (IN only)
|
||||
xdata at 0xE623 volatile BYTE EP4AUTOINLENL; // Endpoint 4 Packet Length L (IN only)
|
||||
xdata at 0xE624 volatile BYTE EP6AUTOINLENH; // Endpoint 6 Packet Length H (IN only)
|
||||
xdata at 0xE625 volatile BYTE EP6AUTOINLENL; // Endpoint 6 Packet Length L (IN only)
|
||||
xdata at 0xE626 volatile BYTE EP8AUTOINLENH; // Endpoint 8 Packet Length H (IN only)
|
||||
xdata at 0xE627 volatile BYTE EP8AUTOINLENL; // Endpoint 8 Packet Length L (IN only)
|
||||
xdata at 0xE630 volatile BYTE EP2FIFOPFH; // EP2 Programmable Flag trigger H
|
||||
xdata at 0xE631 volatile BYTE EP2FIFOPFL; // EP2 Programmable Flag trigger L
|
||||
xdata at 0xE632 volatile BYTE EP4FIFOPFH; // EP4 Programmable Flag trigger H
|
||||
xdata at 0xE633 volatile BYTE EP4FIFOPFL; // EP4 Programmable Flag trigger L
|
||||
xdata at 0xE634 volatile BYTE EP6FIFOPFH; // EP6 Programmable Flag trigger H
|
||||
xdata at 0xE635 volatile BYTE EP6FIFOPFL; // EP6 Programmable Flag trigger L
|
||||
xdata at 0xE636 volatile BYTE EP8FIFOPFH; // EP8 Programmable Flag trigger H
|
||||
xdata at 0xE637 volatile BYTE EP8FIFOPFL; // EP8 Programmable Flag trigger L
|
||||
xdata at 0xE640 volatile BYTE EP2ISOINPKTS; // EP2 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE641 volatile BYTE EP4ISOINPKTS; // EP4 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE642 volatile BYTE EP6ISOINPKTS; // EP6 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE643 volatile BYTE EP8ISOINPKTS; // EP8 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE648 volatile BYTE INPKTEND; // Force IN Packet End
|
||||
xdata at 0xE649 volatile BYTE OUTPKTEND; // Force OUT Packet End
|
||||
|
||||
// Interrupts
|
||||
|
||||
xdata at 0xE650 volatile BYTE EP2FIFOIE; // Endpoint 2 Flag Interrupt Enable
|
||||
xdata at 0xE651 volatile BYTE EP2FIFOIRQ; // Endpoint 2 Flag Interrupt Request
|
||||
xdata at 0xE652 volatile BYTE EP4FIFOIE; // Endpoint 4 Flag Interrupt Enable
|
||||
xdata at 0xE653 volatile BYTE EP4FIFOIRQ; // Endpoint 4 Flag Interrupt Request
|
||||
xdata at 0xE654 volatile BYTE EP6FIFOIE; // Endpoint 6 Flag Interrupt Enable
|
||||
xdata at 0xE655 volatile BYTE EP6FIFOIRQ; // Endpoint 6 Flag Interrupt Request
|
||||
xdata at 0xE656 volatile BYTE EP8FIFOIE; // Endpoint 8 Flag Interrupt Enable
|
||||
xdata at 0xE657 volatile BYTE EP8FIFOIRQ; // Endpoint 8 Flag Interrupt Request
|
||||
xdata at 0xE658 volatile BYTE IBNIE; // IN-BULK-NAK Interrupt Enable
|
||||
xdata at 0xE659 volatile BYTE IBNIRQ; // IN-BULK-NAK interrupt Request
|
||||
xdata at 0xE65A volatile BYTE NAKIE; // Endpoint Ping NAK interrupt Enable
|
||||
xdata at 0xE65B volatile BYTE NAKIRQ; // Endpoint Ping NAK interrupt Request
|
||||
xdata at 0xE65C volatile BYTE USBIE; // USB Int Enables
|
||||
xdata at 0xE65D volatile BYTE USBIRQ; // USB Interrupt Requests
|
||||
xdata at 0xE65E volatile BYTE EPIE; // Endpoint Interrupt Enables
|
||||
xdata at 0xE65F volatile BYTE EPIRQ; // Endpoint Interrupt Requests
|
||||
xdata at 0xE660 volatile BYTE GPIFIE; // GPIF Interrupt Enable
|
||||
xdata at 0xE661 volatile BYTE GPIFIRQ; // GPIF Interrupt Request
|
||||
xdata at 0xE662 volatile BYTE USBERRIE; // USB Error Interrupt Enables
|
||||
xdata at 0xE663 volatile BYTE USBERRIRQ; // USB Error Interrupt Requests
|
||||
xdata at 0xE664 volatile BYTE ERRCNTLIM; // USB Error counter and limit
|
||||
xdata at 0xE665 volatile BYTE CLRERRCNT; // Clear Error Counter EC[3..0]
|
||||
xdata at 0xE666 volatile BYTE INT2IVEC; // Interupt 2 (USB) Autovector
|
||||
xdata at 0xE667 volatile BYTE INT4IVEC; // Interupt 4 (FIFOS & GPIF) Autovector
|
||||
xdata at 0xE668 volatile BYTE INTSETUP; // Interrupt 2&4 Setup
|
||||
|
||||
// Input/Output
|
||||
|
||||
xdata at 0xE670 volatile BYTE PORTACFG; // I/O PORTA Alternate Configuration
|
||||
xdata at 0xE671 volatile BYTE PORTCCFG; // I/O PORTC Alternate Configuration
|
||||
xdata at 0xE672 volatile BYTE PORTECFG; // I/O PORTE Alternate Configuration
|
||||
xdata at 0xE678 volatile BYTE I2CS; // Control & Status
|
||||
xdata at 0xE679 volatile BYTE I2DAT; // Data
|
||||
xdata at 0xE67A volatile BYTE I2CTL; // I2C Control
|
||||
xdata at 0xE67B volatile BYTE XAUTODAT1; // Autoptr1 MOVX access
|
||||
xdata at 0xE67C volatile BYTE XAUTODAT2; // Autoptr2 MOVX access
|
||||
|
||||
#define EXTAUTODAT1 XAUTODAT1
|
||||
#define EXTAUTODAT2 XAUTODAT2
|
||||
|
||||
// USB Control
|
||||
|
||||
xdata at 0xE680 volatile BYTE USBCS; // USB Control & Status
|
||||
xdata at 0xE681 volatile BYTE SUSPEND; // Put chip into suspend
|
||||
xdata at 0xE682 volatile BYTE WAKEUPCS; // Wakeup source and polarity
|
||||
xdata at 0xE683 volatile BYTE TOGCTL; // Toggle Control
|
||||
xdata at 0xE684 volatile BYTE USBFRAMEH; // USB Frame count H
|
||||
xdata at 0xE685 volatile BYTE USBFRAMEL; // USB Frame count L
|
||||
xdata at 0xE686 volatile BYTE MICROFRAME; // Microframe count, 0-7
|
||||
xdata at 0xE687 volatile BYTE FNADDR; // USB Function address
|
||||
|
||||
// Endpoints
|
||||
|
||||
xdata at 0xE68A volatile BYTE EP0BCH; // Endpoint 0 Byte Count H
|
||||
xdata at 0xE68B volatile BYTE EP0BCL; // Endpoint 0 Byte Count L
|
||||
xdata at 0xE68D volatile BYTE EP1OUTBC; // Endpoint 1 OUT Byte Count
|
||||
xdata at 0xE68F volatile BYTE EP1INBC; // Endpoint 1 IN Byte Count
|
||||
xdata at 0xE690 volatile BYTE EP2BCH; // Endpoint 2 Byte Count H
|
||||
xdata at 0xE691 volatile BYTE EP2BCL; // Endpoint 2 Byte Count L
|
||||
xdata at 0xE694 volatile BYTE EP4BCH; // Endpoint 4 Byte Count H
|
||||
xdata at 0xE695 volatile BYTE EP4BCL; // Endpoint 4 Byte Count L
|
||||
xdata at 0xE698 volatile BYTE EP6BCH; // Endpoint 6 Byte Count H
|
||||
xdata at 0xE699 volatile BYTE EP6BCL; // Endpoint 6 Byte Count L
|
||||
xdata at 0xE69C volatile BYTE EP8BCH; // Endpoint 8 Byte Count H
|
||||
xdata at 0xE69D volatile BYTE EP8BCL; // Endpoint 8 Byte Count L
|
||||
xdata at 0xE6A0 volatile BYTE EP0CS; // Endpoint Control and Status
|
||||
xdata at 0xE6A1 volatile BYTE EP1OUTCS; // Endpoint 1 OUT Control and Status
|
||||
xdata at 0xE6A2 volatile BYTE EP1INCS; // Endpoint 1 IN Control and Status
|
||||
xdata at 0xE6A3 volatile BYTE EP2CS; // Endpoint 2 Control and Status
|
||||
xdata at 0xE6A4 volatile BYTE EP4CS; // Endpoint 4 Control and Status
|
||||
xdata at 0xE6A5 volatile BYTE EP6CS; // Endpoint 6 Control and Status
|
||||
xdata at 0xE6A6 volatile BYTE EP8CS; // Endpoint 8 Control and Status
|
||||
xdata at 0xE6A7 volatile BYTE EP2FIFOFLGS; // Endpoint 2 Flags
|
||||
xdata at 0xE6A8 volatile BYTE EP4FIFOFLGS; // Endpoint 4 Flags
|
||||
xdata at 0xE6A9 volatile BYTE EP6FIFOFLGS; // Endpoint 6 Flags
|
||||
xdata at 0xE6AA volatile BYTE EP8FIFOFLGS; // Endpoint 8 Flags
|
||||
xdata at 0xE6AB volatile BYTE EP2FIFOBCH; // EP2 FIFO total byte count H
|
||||
xdata at 0xE6AC volatile BYTE EP2FIFOBCL; // EP2 FIFO total byte count L
|
||||
xdata at 0xE6AD volatile BYTE EP4FIFOBCH; // EP4 FIFO total byte count H
|
||||
xdata at 0xE6AE volatile BYTE EP4FIFOBCL; // EP4 FIFO total byte count L
|
||||
xdata at 0xE6AF volatile BYTE EP6FIFOBCH; // EP6 FIFO total byte count H
|
||||
xdata at 0xE6B0 volatile BYTE EP6FIFOBCL; // EP6 FIFO total byte count L
|
||||
xdata at 0xE6B1 volatile BYTE EP8FIFOBCH; // EP8 FIFO total byte count H
|
||||
xdata at 0xE6B2 volatile BYTE EP8FIFOBCL; // EP8 FIFO total byte count L
|
||||
xdata at 0xE6B3 volatile BYTE SUDPTRH; // Setup Data Pointer high address byte
|
||||
xdata at 0xE6B4 volatile BYTE SUDPTRL; // Setup Data Pointer low address byte
|
||||
xdata at 0xE6B5 volatile BYTE SUDPTRCTL; // Setup Data Pointer Auto Mode
|
||||
xdata at 0xE6B8 volatile BYTE SETUPDAT[8]; // 8 bytes of SETUP data
|
||||
|
||||
// GPIF
|
||||
|
||||
xdata at 0xE6C0 volatile BYTE GPIFWFSELECT; // Waveform Selector
|
||||
xdata at 0xE6C1 volatile BYTE GPIFIDLECS; // GPIF Done, GPIF IDLE drive mode
|
||||
xdata at 0xE6C2 volatile BYTE GPIFIDLECTL; // Inactive Bus, CTL states
|
||||
xdata at 0xE6C3 volatile BYTE GPIFCTLCFG; // CTL OUT pin drive
|
||||
xdata at 0xE6C4 volatile BYTE GPIFADRH; // GPIF Address H
|
||||
xdata at 0xE6C5 volatile BYTE GPIFADRL; // GPIF Address L
|
||||
|
||||
xdata at 0xE6CE volatile BYTE GPIFTCB3; // GPIF Transaction Count Byte 3
|
||||
xdata at 0xE6CF volatile BYTE GPIFTCB2; // GPIF Transaction Count Byte 2
|
||||
xdata at 0xE6D0 volatile BYTE GPIFTCB1; // GPIF Transaction Count Byte 1
|
||||
xdata at 0xE6D1 volatile BYTE GPIFTCB0; // GPIF Transaction Count Byte 0
|
||||
|
||||
#define EP2GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP2GPIFTCL GPIFTCB0 //
|
||||
#define EP4GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP4GPIFTCL GPIFTCB0 //
|
||||
#define EP6GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP6GPIFTCL GPIFTCB0 //
|
||||
#define EP8GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP8GPIFTCL GPIFTCB0 //
|
||||
|
||||
xdata at 0xE6D2 volatile BYTE EP2GPIFFLGSEL; // EP2 GPIF Flag select
|
||||
xdata at 0xE6D3 volatile BYTE EP2GPIFPFSTOP; // Stop GPIF EP2 transaction on prog. flag
|
||||
xdata at 0xE6D4 volatile BYTE EP2GPIFTRIG; // EP2 FIFO Trigger
|
||||
xdata at 0xE6DA volatile BYTE EP4GPIFFLGSEL; // EP4 GPIF Flag select
|
||||
xdata at 0xE6DB volatile BYTE EP4GPIFPFSTOP; // Stop GPIF EP4 transaction on prog. flag
|
||||
xdata at 0xE6DC volatile BYTE EP4GPIFTRIG; // EP4 FIFO Trigger
|
||||
xdata at 0xE6E2 volatile BYTE EP6GPIFFLGSEL; // EP6 GPIF Flag select
|
||||
xdata at 0xE6E3 volatile BYTE EP6GPIFPFSTOP; // Stop GPIF EP6 transaction on prog. flag
|
||||
xdata at 0xE6E4 volatile BYTE EP6GPIFTRIG; // EP6 FIFO Trigger
|
||||
xdata at 0xE6EA volatile BYTE EP8GPIFFLGSEL; // EP8 GPIF Flag select
|
||||
xdata at 0xE6EB volatile BYTE EP8GPIFPFSTOP; // Stop GPIF EP8 transaction on prog. flag
|
||||
xdata at 0xE6EC volatile BYTE EP8GPIFTRIG; // EP8 FIFO Trigger
|
||||
xdata at 0xE6F0 volatile BYTE XGPIFSGLDATH; // GPIF Data H (16-bit mode only)
|
||||
xdata at 0xE6F1 volatile BYTE XGPIFSGLDATLX; // Read/Write GPIF Data L & trigger transac
|
||||
xdata at 0xE6F2 volatile BYTE XGPIFSGLDATLNOX; // Read GPIF Data L, no transac trigger
|
||||
xdata at 0xE6F3 volatile BYTE GPIFREADYCFG; // Internal RDY,Sync/Async, RDY5CFG
|
||||
xdata at 0xE6F4 volatile BYTE GPIFREADYSTAT; // RDY pin states
|
||||
xdata at 0xE6F5 volatile BYTE GPIFABORT; // Abort GPIF cycles
|
||||
|
||||
// UDMA
|
||||
|
||||
xdata at 0xE6C6 volatile BYTE FLOWSTATE; //Defines GPIF flow state
|
||||
xdata at 0xE6C7 volatile BYTE FLOWLOGIC; //Defines flow/hold decision criteria
|
||||
xdata at 0xE6C8 volatile BYTE FLOWEQ0CTL; //CTL states during active flow state
|
||||
xdata at 0xE6C9 volatile BYTE FLOWEQ1CTL; //CTL states during hold flow state
|
||||
xdata at 0xE6CA volatile BYTE FLOWHOLDOFF;
|
||||
xdata at 0xE6CB volatile BYTE FLOWSTB; //CTL/RDY Signal to use as master data strobe
|
||||
xdata at 0xE6CC volatile BYTE FLOWSTBEDGE; //Defines active master strobe edge
|
||||
xdata at 0xE6CD volatile BYTE FLOWSTBHPERIOD; //Half Period of output master strobe
|
||||
xdata at 0xE60C volatile BYTE GPIFHOLDAMOUNT; //Data delay shift
|
||||
xdata at 0xE67D volatile BYTE UDMACRCH; //CRC Upper byte
|
||||
xdata at 0xE67E volatile BYTE UDMACRCL; //CRC Lower byte
|
||||
xdata at 0xE67F volatile BYTE UDMACRCQUAL; //UDMA In only, host terminated use only
|
||||
|
||||
|
||||
// Debug/Test
|
||||
// The following registers are for Cypress's internal testing purposes only.
|
||||
// These registers are not documented in the datasheet or the Technical Reference
|
||||
// Manual as they were not designed for end user application usage
|
||||
xdata at 0xE6F8 volatile BYTE DBUG; // Debug
|
||||
xdata at 0xE6F9 volatile BYTE TESTCFG; // Test configuration
|
||||
xdata at 0xE6FA volatile BYTE USBTEST; // USB Test Modes
|
||||
xdata at 0xE6FB volatile BYTE CT1; // Chirp Test--Override
|
||||
xdata at 0xE6FC volatile BYTE CT2; // Chirp Test--FSM
|
||||
xdata at 0xE6FD volatile BYTE CT3; // Chirp Test--Control Signals
|
||||
xdata at 0xE6FE volatile BYTE CT4; // Chirp Test--Inputs
|
||||
|
||||
// Endpoint Buffers
|
||||
|
||||
xdata at 0xE740 volatile BYTE EP0BUF[64]; // EP0 IN-OUT buffer
|
||||
xdata at 0xE780 volatile BYTE EP1OUTBUF[64]; // EP1-OUT buffer
|
||||
xdata at 0xE7C0 volatile BYTE EP1INBUF[64]; // EP1-IN buffer
|
||||
xdata at 0xF000 volatile BYTE EP2FIFOBUF[1024]; // 512/1024-byte EP2 buffer (IN or OUT)
|
||||
xdata at 0xF400 volatile BYTE EP4FIFOBUF[1024]; // 512 byte EP4 buffer (IN or OUT)
|
||||
xdata at 0xF800 volatile BYTE EP6FIFOBUF[1024]; // 512/1024-byte EP6 buffer (IN or OUT)
|
||||
xdata at 0xFC00 volatile BYTE EP8FIFOBUF[1024]; // 512 byte EP8 buffer (IN or OUT)
|
||||
|
||||
// Error Correction Code (ECC) Registers (FX2LP/FX1 only)
|
||||
|
||||
xdata at 0xE628 volatile BYTE ECCCFG; // ECC Configuration
|
||||
xdata at 0xE629 volatile BYTE ECCRESET; // ECC Reset
|
||||
xdata at 0xE62A volatile BYTE ECC1B0; // ECC1 Byte 0
|
||||
xdata at 0xE62B volatile BYTE ECC1B1; // ECC1 Byte 1
|
||||
xdata at 0xE62C volatile BYTE ECC1B2; // ECC1 Byte 2
|
||||
xdata at 0xE62D volatile BYTE ECC2B0; // ECC2 Byte 0
|
||||
xdata at 0xE62E volatile BYTE ECC2B1; // ECC2 Byte 1
|
||||
xdata at 0xE62F volatile BYTE ECC2B2; // ECC2 Byte 2
|
||||
|
||||
// Feature Registers (FX2LP/FX1 only)
|
||||
xdata at 0xE50D volatile BYTE GPCR2; // Chip Features
|
||||
|
||||
#undef EXTERN
|
||||
#undef _AT_
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Special Function Registers (SFRs)
|
||||
The byte registers and bits defined in the following list are based
|
||||
on the Synopsis definition of the 8051 Special Function Registers for EZ-USB.
|
||||
If you modify the register definitions below, please regenerate the file
|
||||
"ezregs.inc" which includes the same basic information for assembly inclusion.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
sfr at 0x80 IOA;
|
||||
/* IOA */
|
||||
sbit at (0x80 + 0) PA0;
|
||||
sbit at (0x80 + 1) PA1;
|
||||
sbit at (0x80 + 2) PA2;
|
||||
sbit at (0x80 + 3) PA3;
|
||||
|
||||
sbit at (0x80 + 4) PA4;
|
||||
sbit at (0x80 + 5) PA5;
|
||||
sbit at (0x80 + 6) PA6;
|
||||
sbit at (0x80 + 7) PA7;
|
||||
sfr at 0x81 SP;
|
||||
sfr at 0x82 DPL;
|
||||
sfr at 0x83 DPH;
|
||||
sfr at 0x84 DPL1;
|
||||
sfr at 0x85 DPH1;
|
||||
sfr at 0x86 DPS;
|
||||
/* DPS */
|
||||
// sbit SEL = 0x86+0;
|
||||
sfr at 0x87 PCON;
|
||||
/* PCON */
|
||||
//sbit IDLE = 0x87+0;
|
||||
//sbit STOP = 0x87+1;
|
||||
//sbit GF0 = 0x87+2;
|
||||
//sbit GF1 = 0x87+3;
|
||||
//sbit SMOD0 = 0x87+7;
|
||||
sfr at 0x88 TCON;
|
||||
/* TCON */
|
||||
sbit at (0x88+0) IT0;
|
||||
sbit at (0x88+1) IE0;
|
||||
sbit at (0x88+2) IT1;
|
||||
sbit at (0x88+3) IE1;
|
||||
sbit at (0x88+4) TR0;
|
||||
sbit at (0x88+5) TF0;
|
||||
sbit at (0x88+6) TR1;
|
||||
sbit at (0x88+7) TF1;
|
||||
sfr at 0x89 TMOD;
|
||||
/* TMOD */
|
||||
//sbit M00 = 0x89+0;
|
||||
//sbit M10 = 0x89+1;
|
||||
//sbit CT0 = 0x89+2;
|
||||
//sbit GATE0 = 0x89+3;
|
||||
//sbit M01 = 0x89+4;
|
||||
//sbit M11 = 0x89+5;
|
||||
//sbit CT1 = 0x89+6;
|
||||
//sbit GATE1 = 0x89+7;
|
||||
sfr at 0x8A TL0;
|
||||
sfr at 0x8B TL1;
|
||||
sfr at 0x8C TH0;
|
||||
sfr at 0x8D TH1;
|
||||
sfr at 0x8E CKCON;
|
||||
/* CKCON */
|
||||
//sbit MD0 = 0x89+0;
|
||||
//sbit MD1 = 0x89+1;
|
||||
//sbit MD2 = 0x89+2;
|
||||
//sbit T0M = 0x89+3;
|
||||
//sbit T1M = 0x89+4;
|
||||
//sbit T2M = 0x89+5;
|
||||
sfr at 0x8F SPC_FNC; // Was WRS in Reg320
|
||||
/* CKCON */
|
||||
//sbit WRS = 0x8F+0;
|
||||
sfr at 0x90 IOB;
|
||||
/* IOB */
|
||||
sbit at (0x90 + 0) PB0;
|
||||
sbit at (0x90 + 1) PB1;
|
||||
sbit at (0x90 + 2) PB2;
|
||||
sbit at (0x90 + 3) PB3;
|
||||
|
||||
sbit at (0x90 + 4) PB4;
|
||||
sbit at (0x90 + 5) PB5;
|
||||
sbit at (0x90 + 6) PB6;
|
||||
sbit at (0x90 + 7) PB7;
|
||||
sfr at 0x91 EXIF; // EXIF Bit Values differ from Reg320
|
||||
/* EXIF */
|
||||
//sbit USBINT = 0x91+4;
|
||||
//sbit I2CINT = 0x91+5;
|
||||
//sbit IE4 = 0x91+6;
|
||||
//sbit IE5 = 0x91+7;
|
||||
sfr at 0x92 MPAGE;
|
||||
sfr at 0x98 SCON0;
|
||||
/* SCON0 */
|
||||
sbit at (0x98+0) RI;
|
||||
sbit at (0x98+1) TI;
|
||||
sbit at (0x98+2) RB8;
|
||||
sbit at (0x98+3) TB8;
|
||||
sbit at (0x98+4) REN;
|
||||
sbit at (0x98+5) SM2;
|
||||
sbit at (0x98+6) SM1;
|
||||
sbit at (0x98+7) SM0;
|
||||
sfr at 0x99 SBUF0;
|
||||
|
||||
#define AUTOPTR1H AUTOPTRH1 // for backwards compatibility with examples
|
||||
#define AUTOPTR1L AUTOPTRL1 // for backwards compatibility with examples
|
||||
#define APTR1H AUTOPTRH1 // for backwards compatibility with examples
|
||||
#define APTR1L AUTOPTRL1 // for backwards compatibility with examples
|
||||
|
||||
// this is how they are defined in the TRM
|
||||
sfr at 0x9A AUTOPTRH1;
|
||||
sfr at 0x9B AUTOPTRL1;
|
||||
sfr at 0x9D AUTOPTRH2;
|
||||
sfr at 0x9E AUTOPTRL2;
|
||||
|
||||
sfr at 0xA0 IOC;
|
||||
/* IOC */
|
||||
sbit at (0xA0 + 0) PC0;
|
||||
sbit at (0xA0 + 1) PC1;
|
||||
sbit at (0xA0 + 2) PC2;
|
||||
sbit at (0xA0 + 3) PC3;
|
||||
|
||||
sbit at (0xA0 + 4) PC4;
|
||||
sbit at (0xA0 + 5) PC5;
|
||||
sbit at (0xA0 + 6) PC6;
|
||||
sbit at (0xA0 + 7) PC7;
|
||||
sfr at 0xA1 INT2CLR;
|
||||
sfr at 0xA2 INT4CLR;
|
||||
|
||||
sfr at 0xA8 IE;
|
||||
/* IE */
|
||||
sbit at (0xA8+0) EX0;
|
||||
sbit at (0xA8+1) ET0;
|
||||
sbit at (0xA8+2) EX1;
|
||||
sbit at (0xA8+3) ET1;
|
||||
sbit at (0xA8+4) ES0;
|
||||
sbit at (0xA8+5) ET2;
|
||||
sbit at (0xA8+6) ES1;
|
||||
sbit at (0xA8+7) EA;
|
||||
|
||||
sfr at 0xAA EP2468STAT;
|
||||
/* EP2468STAT */
|
||||
//sbit EP2E = 0xAA+0;
|
||||
//sbit EP2F = 0xAA+1;
|
||||
//sbit EP4E = 0xAA+2;
|
||||
//sbit EP4F = 0xAA+3;
|
||||
//sbit EP6E = 0xAA+4;
|
||||
//sbit EP6F = 0xAA+5;
|
||||
//sbit EP8E = 0xAA+6;
|
||||
//sbit EP8F = 0xAA+7;
|
||||
|
||||
sfr at 0xAB EP24FIFOFLGS;
|
||||
sfr at 0xAC EP68FIFOFLGS;
|
||||
sfr at 0xAF AUTOPTRSETUP;
|
||||
/* AUTOPTRSETUP */
|
||||
// sbit EXTACC = 0xAF+0;
|
||||
// sbit APTR1FZ = 0xAF+1;
|
||||
// sbit APTR2FZ = 0xAF+2;
|
||||
|
||||
sfr at 0xB0 IOD;
|
||||
/* IOD */
|
||||
sbit at (0xB0 + 0) PD0;
|
||||
sbit at (0xB0 + 1) PD1;
|
||||
sbit at (0xB0 + 2) PD2;
|
||||
sbit at (0xB0 + 3) PD3;
|
||||
|
||||
sbit at (0xB0 + 4) PD4;
|
||||
sbit at (0xB0 + 5) PD5;
|
||||
sbit at (0xB0 + 6) PD6;
|
||||
sbit at (0xB0 + 7) PD7;
|
||||
sfr at 0xB1 IOE;
|
||||
sfr at 0xB2 OEA;
|
||||
sfr at 0xB3 OEB;
|
||||
sfr at 0xB4 OEC;
|
||||
sfr at 0xB5 OED;
|
||||
sfr at 0xB6 OEE;
|
||||
|
||||
sfr at 0xB8 IP;
|
||||
/* IP */
|
||||
sbit at (0xB8+0) PX0;
|
||||
sbit at (0xB8+1) PT0;
|
||||
sbit at (0xB8+2) PX1;
|
||||
sbit at (0xB8+3) PT1;
|
||||
sbit at (0xB8+4) PS0;
|
||||
sbit at (0xB8+5) PT2;
|
||||
sbit at (0xB8+6) PS1;
|
||||
|
||||
sfr at 0xBA EP01STAT;
|
||||
sfr at 0xBB GPIFTRIG;
|
||||
|
||||
sfr at 0xBD GPIFSGLDATH;
|
||||
sfr at 0xBE GPIFSGLDATLX;
|
||||
sfr at 0xBF GPIFSGLDATLNOX;
|
||||
|
||||
sfr at 0xC0 SCON1;
|
||||
/* SCON1 */
|
||||
sbit at (0xC0+0) RI1;
|
||||
sbit at (0xC0+1) TI1;
|
||||
sbit at (0xC0+2) RB81;
|
||||
sbit at (0xC0+3) TB81;
|
||||
sbit at (0xC0+4) REN1;
|
||||
sbit at (0xC0+5) SM21;
|
||||
sbit at (0xC0+6) SM11;
|
||||
sbit at (0xC0+7) SM01;
|
||||
sfr at 0xC1 SBUF1;
|
||||
sfr at 0xC8 T2CON;
|
||||
/* T2CON */
|
||||
sbit at (0xC8+0) CP_RL2;
|
||||
sbit at (0xC8+1) C_T2;
|
||||
sbit at (0xC8+2) TR2;
|
||||
sbit at (0xC8+3) EXEN2;
|
||||
sbit at (0xC8+4) TCLK;
|
||||
sbit at (0xC8+5) RCLK;
|
||||
sbit at (0xC8+6) EXF2;
|
||||
sbit at (0xC8+7) TF2;
|
||||
sfr at 0xCA RCAP2L;
|
||||
sfr at 0xCB RCAP2H;
|
||||
sfr at 0xCC TL2;
|
||||
sfr at 0xCD TH2;
|
||||
sfr at 0xD0 PSW;
|
||||
/* PSW */
|
||||
sbit at (0xD0+0) P;
|
||||
sbit at (0xD0+1) FL;
|
||||
sbit at (0xD0+2) OV;
|
||||
sbit at (0xD0+3) RS0;
|
||||
sbit at (0xD0+4) RS1;
|
||||
sbit at (0xD0+5) F0;
|
||||
sbit at (0xD0+6) AC;
|
||||
sbit at (0xD0+7) CY;
|
||||
sfr at 0xD8 EICON; // Was WDCON in DS80C320; Bit Values differ from Reg320
|
||||
/* EICON */
|
||||
sbit at (0xD8+3) INT6;
|
||||
sbit at (0xD8+4) RESI;
|
||||
sbit at (0xD8+5) ERESI;
|
||||
sbit at (0xD8+7) SMOD1;
|
||||
sfr at 0xE0 ACC;
|
||||
sfr at 0xE8 EIE; // EIE Bit Values differ from Reg320
|
||||
/* EIE */
|
||||
sbit at (0xE8+0) EUSB;
|
||||
sbit at (0xE8+1) EI2C;
|
||||
sbit at (0xE8+2) EIEX4;
|
||||
sbit at (0xE8+3) EIEX5;
|
||||
sbit at (0xE8+4) EIEX6;
|
||||
sfr at 0xF0 B;
|
||||
sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
|
||||
/* EIP */
|
||||
sbit at (0xF8+0) PUSB;
|
||||
sbit at (0xF8+1) PI2C;
|
||||
sbit at (0xF8+2) EIPX4;
|
||||
sbit at (0xF8+3) EIPX5;
|
||||
sbit at (0xF8+4) EIPX6;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Bit Masks
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* CPU Control & Status Register (CPUCS) */
|
||||
#define bmPRTCSTB bmBIT5
|
||||
#define bmCLKSPD (bmBIT4 | bmBIT3)
|
||||
#define bmCLKSPD1 bmBIT4
|
||||
#define bmCLKSPD0 bmBIT3
|
||||
#define bmCLKINV bmBIT2
|
||||
#define bmCLKOE bmBIT1
|
||||
#define bm8051RES bmBIT0
|
||||
/* Port Alternate Configuration Registers */
|
||||
/* Port A (PORTACFG) */
|
||||
#define bmFLAGD bmBIT7
|
||||
#define bmINT1 bmBIT1
|
||||
#define bmINT0 bmBIT0
|
||||
/* Port C (PORTCCFG) */
|
||||
#define bmGPIFA7 bmBIT7
|
||||
#define bmGPIFA6 bmBIT6
|
||||
#define bmGPIFA5 bmBIT5
|
||||
#define bmGPIFA4 bmBIT4
|
||||
#define bmGPIFA3 bmBIT3
|
||||
#define bmGPIFA2 bmBIT2
|
||||
#define bmGPIFA1 bmBIT1
|
||||
#define bmGPIFA0 bmBIT0
|
||||
/* Port E (PORTECFG) */
|
||||
#define bmGPIFA8 bmBIT7
|
||||
#define bmT2EX bmBIT6
|
||||
#define bmINT6 bmBIT5
|
||||
#define bmRXD1OUT bmBIT4
|
||||
#define bmRXD0OUT bmBIT3
|
||||
#define bmT2OUT bmBIT2
|
||||
#define bmT1OUT bmBIT1
|
||||
#define bmT0OUT bmBIT0
|
||||
|
||||
/* I2C Control & Status Register (I2CS) */
|
||||
#define bmSTART bmBIT7
|
||||
#define bmSTOP bmBIT6
|
||||
#define bmLASTRD bmBIT5
|
||||
#define bmID (bmBIT4 | bmBIT3)
|
||||
#define bmBERR bmBIT2
|
||||
#define bmACK bmBIT1
|
||||
#define bmDONE bmBIT0
|
||||
/* I2C Control Register (I2CTL) */
|
||||
#define bmSTOPIE bmBIT1
|
||||
#define bm400KHZ bmBIT0
|
||||
/* Interrupt 2 (USB) Autovector Register (INT2IVEC) */
|
||||
#define bmIV4 bmBIT6
|
||||
#define bmIV3 bmBIT5
|
||||
#define bmIV2 bmBIT4
|
||||
#define bmIV1 bmBIT3
|
||||
#define bmIV0 bmBIT2
|
||||
/* USB Interrupt Request & Enable Registers (USBIE/USBIRQ) */
|
||||
#define bmEP0ACK bmBIT6
|
||||
#define bmHSGRANT bmBIT5
|
||||
#define bmURES bmBIT4
|
||||
#define bmSUSP bmBIT3
|
||||
#define bmSUTOK bmBIT2
|
||||
#define bmSOF bmBIT1
|
||||
#define bmSUDAV bmBIT0
|
||||
/* Breakpoint register (BREAKPT) */
|
||||
#define bmBREAK bmBIT3
|
||||
#define bmBPPULSE bmBIT2
|
||||
#define bmBPEN bmBIT1
|
||||
/* Interrupt 2 & 4 Setup (INTSETUP) */
|
||||
#define bmAV2EN bmBIT3
|
||||
#define INT4IN bmBIT1
|
||||
#define bmAV4EN bmBIT0
|
||||
/* USB Control & Status Register (USBCS) */
|
||||
#define bmHSM bmBIT7
|
||||
#define bmDISCON bmBIT3
|
||||
#define bmNOSYNSOF bmBIT2
|
||||
#define bmRENUM bmBIT1
|
||||
#define bmSIGRESUME bmBIT0
|
||||
/* Wakeup Control and Status Register (WAKEUPCS) */
|
||||
#define bmWU2 bmBIT7
|
||||
#define bmWU bmBIT6
|
||||
#define bmWU2POL bmBIT5
|
||||
#define bmWUPOL bmBIT4
|
||||
#define bmDPEN bmBIT2
|
||||
#define bmWU2EN bmBIT1
|
||||
#define bmWUEN bmBIT0
|
||||
/* End Point 0 Control & Status Register (EP0CS) */
|
||||
#define bmHSNAK bmBIT7
|
||||
/* End Point 0-1 Control & Status Registers (EP0CS/EP1OUTCS/EP1INCS) */
|
||||
#define bmEPBUSY bmBIT1
|
||||
#define bmEPSTALL bmBIT0
|
||||
/* End Point 2-8 Control & Status Registers (EP2CS/EP4CS/EP6CS/EP8CS) */
|
||||
#define bmNPAK (bmBIT6 | bmBIT5 | bmBIT4)
|
||||
#define bmEPFULL bmBIT3
|
||||
#define bmEPEMPTY bmBIT2
|
||||
/* Endpoint Status (EP2468STAT) SFR bits */
|
||||
#define bmEP8FULL bmBIT7
|
||||
#define bmEP8EMPTY bmBIT6
|
||||
#define bmEP6FULL bmBIT5
|
||||
#define bmEP6EMPTY bmBIT4
|
||||
#define bmEP4FULL bmBIT3
|
||||
#define bmEP4EMPTY bmBIT2
|
||||
#define bmEP2FULL bmBIT1
|
||||
#define bmEP2EMPTY bmBIT0
|
||||
/* SETUP Data Pointer Auto Mode (SUDPTRCTL) */
|
||||
#define bmSDPAUTO bmBIT0
|
||||
/* Endpoint Data Toggle Control (TOGCTL) */
|
||||
#define bmQUERYTOGGLE bmBIT7
|
||||
#define bmSETTOGGLE bmBIT6
|
||||
#define bmRESETTOGGLE bmBIT5
|
||||
#define bmTOGCTLEPMASK bmBIT3 | bmBIT2 | bmBIT1 | bmBIT0
|
||||
/* IBN (In Bulk Nak) enable and request bits (IBNIE/IBNIRQ) */
|
||||
#define bmEP8IBN bmBIT5
|
||||
#define bmEP6IBN bmBIT4
|
||||
#define bmEP4IBN bmBIT3
|
||||
#define bmEP2IBN bmBIT2
|
||||
#define bmEP1IBN bmBIT1
|
||||
#define bmEP0IBN bmBIT0
|
||||
|
||||
/* PING-NAK enable and request bits (NAKIE/NAKIRQ) */
|
||||
#define bmEP8PING bmBIT7
|
||||
#define bmEP6PING bmBIT6
|
||||
#define bmEP4PING bmBIT5
|
||||
#define bmEP2PING bmBIT4
|
||||
#define bmEP1PING bmBIT3
|
||||
#define bmEP0PING bmBIT2
|
||||
#define bmIBN bmBIT0
|
||||
|
||||
/* Interface Configuration bits (IFCONFIG) */
|
||||
#define bmIFCLKSRC bmBIT7
|
||||
#define bm3048MHZ bmBIT6
|
||||
#define bmIFCLKOE bmBIT5
|
||||
#define bmIFCLKPOL bmBIT4
|
||||
#define bmASYNC bmBIT3
|
||||
#define bmGSTATE bmBIT2
|
||||
#define bmIFCFG1 bmBIT1
|
||||
#define bmIFCFG0 bmBIT0
|
||||
#define bmIFCFGMASK (bmIFCFG0 | bmIFCFG1)
|
||||
#define bmIFGPIF bmIFCFG1
|
||||
|
||||
/* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */
|
||||
#define bmINFM bmBIT6
|
||||
#define bmOEP bmBIT5
|
||||
#define bmAUTOOUT bmBIT4
|
||||
#define bmAUTOIN bmBIT3
|
||||
#define bmZEROLENIN bmBIT2
|
||||
#define bmWORDWIDE bmBIT0
|
||||
|
||||
/* Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specidic
|
||||
features */
|
||||
#define bmNOAUTOARM bmBIT1
|
||||
#define bmSKIPCOMMIT bmBIT0
|
||||
|
||||
/* Fifo Reset bits (FIFORESET) */
|
||||
#define bmNAKALL bmBIT7
|
||||
|
||||
/* Chip Feature Register (GPCR2) */
|
||||
#define bmFULLSPEEDONLY bmBIT4
|
||||
|
||||
#endif /* FX2REGS_H */
|
@ -0,0 +1,241 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: fx2sdly.h
|
||||
// Contents: EZ-USB FX2 Synchronization Delay (SYNCDELAY) Macro
|
||||
//
|
||||
// Enter with _IFREQ = IFCLK in kHz
|
||||
// Enter with _CFREQ = CLKOUT in kHz
|
||||
//
|
||||
// Copyright (c) 2001 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#define _nop_() do { _asm nop; _endasm; } while(0)
|
||||
|
||||
// Registers which require a synchronization delay, see section 15.14
|
||||
// FIFORESET FIFOPINPOLAR
|
||||
// INPKTEND OUTPKTEND
|
||||
// EPxBCH:L REVCTL
|
||||
// GPIFTCB3 GPIFTCB2
|
||||
// GPIFTCB1 GPIFTCB0
|
||||
// EPxFIFOPFH:L EPxAUTOINLENH:L
|
||||
// EPxFIFOCFG EPxGPIFFLGSEL
|
||||
// PINFLAGSxx EPxFIFOIRQ
|
||||
// EPxFIFOIE GPIFIRQ
|
||||
// GPIFIE GPIFADRH:L
|
||||
// UDMACRCH:L EPxGPIFTRIG
|
||||
// GPIFTRIG
|
||||
|
||||
// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
|
||||
// ...these have been replaced by GPIFTC[B3:B0] registers
|
||||
|
||||
// _IFREQ can be in the range of: 5000 to 48000
|
||||
#ifndef _IFREQ
|
||||
#define _IFREQ 48000 // IFCLK frequency in kHz
|
||||
#endif
|
||||
|
||||
// CFREQ can be any one of: 48000, 24000, or 12000
|
||||
#ifndef _CFREQ
|
||||
#define _CFREQ 48000 // CLKOUT frequency in kHz
|
||||
#endif
|
||||
|
||||
#if( _IFREQ < 5000 )
|
||||
#error "_IFREQ too small! Valid Range: 5000 to 48000..."
|
||||
#endif
|
||||
|
||||
#if( _IFREQ > 48000 )
|
||||
#error "_IFREQ too large! Valid Range: 5000 to 48000..."
|
||||
#endif
|
||||
|
||||
#if( _CFREQ != 48000 )
|
||||
#if( _CFREQ != 24000 )
|
||||
#if( _CFREQ != 12000 )
|
||||
#error "_CFREQ invalid! Valid values: 48000, 24000, 12000..."
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Synchronization Delay formula: see TRM section 15-14
|
||||
#define _SCYCL ( 3*(_CFREQ) + 5*(_IFREQ) - 1 ) / ( 2*(_IFREQ) )
|
||||
|
||||
#if( _SCYCL == 1 )
|
||||
#define SYNCDELAY _nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 2 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 3 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 4 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 5 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 6 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 7 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 8 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 9 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 10 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 11 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 12 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 13 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 14 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 15 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 16 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "fx2usb-interface.h"
|
||||
|
||||
usb_dev_handle *fx2usb_open(int vendor_id, int device_id, char *dev)
|
||||
{
|
||||
struct usb_bus *b;
|
||||
struct usb_device *d;
|
||||
char *dd = NULL;
|
||||
int devlen;
|
||||
|
||||
if (dev) {
|
||||
devlen = strlen(dev);
|
||||
dd = devlen > 8 ? &dev[devlen-8] : "|xxx|xxx";
|
||||
}
|
||||
|
||||
for (b = usb_get_busses(); b; b = b->next) {
|
||||
for (d = b->devices; d; d = d->next) {
|
||||
if (dd) {
|
||||
if (dd[0] == '/' && !strncmp(dd+1, b->dirname, 3) &&
|
||||
dd[4] == '/' && !strncmp(dd+5, d->filename, 3))
|
||||
return usb_open(d);
|
||||
} else
|
||||
if (vendor_id || device_id) {
|
||||
if ((d->descriptor.idVendor == vendor_id) && (d->descriptor.idProduct == device_id))
|
||||
return usb_open(d);
|
||||
} else {
|
||||
// The Xilinx Platform Cable USB Vendor/Device IDs
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x0009))
|
||||
return usb_open(d);
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x000D))
|
||||
return usb_open(d);
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x000F))
|
||||
return usb_open(d);
|
||||
// The plain CY7C68013 dev kit Vendor/Device IDs
|
||||
if ((d->descriptor.idVendor == 0x04b4) && (d->descriptor.idProduct == 0x8613))
|
||||
return usb_open(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fx2usb_fwload_ctrl_msg(usb_dev_handle *dh, int addr, const void *data, int len)
|
||||
{
|
||||
int ret = usb_control_msg(dh, 0x40, 0xA0, addr, 0, (char*)data, len, 1000);
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_fwload_ctrl_msg: usb_control_msg for addr=0x%04X, len=%d returned %d: %s\n", addr, len, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
||||
int fx2usb_upload_ihex(usb_dev_handle *dh, FILE *fp)
|
||||
{
|
||||
uint8_t on = 1, off = 0;
|
||||
|
||||
// assert reset
|
||||
if (fx2usb_fwload_ctrl_msg(dh, 0xE600, &on, 1) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: can't assert reset!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// parse and upload ihex file
|
||||
char line[1024];
|
||||
int linecount = 0;
|
||||
while (fgets(line, sizeof(line), fp) != NULL)
|
||||
{
|
||||
linecount++;
|
||||
|
||||
if (line[0] != ':')
|
||||
continue;
|
||||
|
||||
uint8_t cksum = 0;
|
||||
uint8_t ldata[512];
|
||||
int lsize = 0;
|
||||
|
||||
while (sscanf(line+1+lsize*2, "%2hhx", &ldata[lsize]) == 1) {
|
||||
cksum += ldata[lsize];
|
||||
lsize++;
|
||||
}
|
||||
|
||||
if (lsize < 5) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: record is to short!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ldata[0] != lsize-5) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: size does not match record length!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cksum -= ldata[lsize-1];
|
||||
cksum = ~cksum + 1;
|
||||
|
||||
if (cksum != ldata[lsize-1]) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: cksum error!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fx2usb_fwload_ctrl_msg(dh, (ldata[1] << 8) | ldata[2], &ldata[4], ldata[0]) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: error in fx2usb communication!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// release reset
|
||||
if (fx2usb_fwload_ctrl_msg(dh, 0xE600, &off, 1) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: can't release reset!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fx2usb_claim(usb_dev_handle *dh)
|
||||
{
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
usb_detach_kernel_driver_np(dh, 0);
|
||||
#endif
|
||||
if (usb_claim_interface(dh, 0) < 0) {
|
||||
fprintf(stderr, "fx2usb_claim: claiming interface 0 failed: %s!\n", usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
if (usb_set_altinterface(dh, 1) < 0) {
|
||||
usb_release_interface(dh, 0);
|
||||
fprintf(stderr, "fx2usb_claim: setting alternate interface 1 failed: %s!\n", usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fx2usb_release(usb_dev_handle *dh)
|
||||
{
|
||||
usb_release_interface(dh, 0);
|
||||
}
|
||||
|
||||
void fx2usb_flush(usb_dev_handle *dh)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
unsigned char readbuf[2] = { 0, 0 };
|
||||
int ret = usb_bulk_read(dh, 1, (char*)readbuf, 2, 10);
|
||||
if (ret <= 0)
|
||||
return;
|
||||
fprintf(stderr, "Unexpected data word from device: 0x%02x 0x%02x (%d)\n", readbuf[0], readbuf[1], ret);
|
||||
}
|
||||
}
|
||||
|
||||
int fx2usb_send_chunk(usb_dev_handle *dh, int ep, const void *data, int len)
|
||||
{
|
||||
int ret;
|
||||
#if 0
|
||||
if (ep == 2) {
|
||||
int i;
|
||||
fprintf(stderr, "<ep2:%4d bytes> ...", len);
|
||||
for (i = len-16; i < len; i++) {
|
||||
if (i < 0)
|
||||
continue;
|
||||
fprintf(stderr, " %02x", ((unsigned char*)data)[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
retry_write:
|
||||
ret = usb_bulk_write(dh, ep, data, len, 1000);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
fprintf(stderr, "fx2usb_recv_chunk: usb write timeout -> retry\n");
|
||||
fx2usb_flush(dh);
|
||||
goto retry_write;
|
||||
}
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_send_chunk: write of %d bytes to ep %d returned %d: %s\n", len, ep, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
||||
int fx2usb_recv_chunk(usb_dev_handle *dh, int ep, void *data, int len, int *ret_len)
|
||||
{
|
||||
int ret;
|
||||
retry_read:
|
||||
ret = usb_bulk_read(dh, ep, data, len, 1000);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
fprintf(stderr, "fx2usb_recv_chunk: usb read timeout -> retry\n");
|
||||
goto retry_read;
|
||||
}
|
||||
if (ret > 0 && ret_len != NULL)
|
||||
len = *ret_len = ret;
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_recv_chunk: read of %d bytes from ep %d returned %d: %s\n", len, ep, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FX2USB_INTERFACE_H
|
||||
#define FX2USB_INTERFACE_H
|
||||
|
||||
#include <usb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
usb_dev_handle *fx2usb_open(int vendor_id, int device_id, char *dev);
|
||||
int fx2usb_upload_ihex(usb_dev_handle *dh, FILE *fp);
|
||||
int fx2usb_claim(usb_dev_handle *dh);
|
||||
void fx2usb_release(usb_dev_handle *dh);
|
||||
|
||||
void fx2usb_flush(usb_dev_handle *dh);
|
||||
int fx2usb_send_chunk(usb_dev_handle *dh, int ep, const void *data, int len);
|
||||
int fx2usb_recv_chunk(usb_dev_handle *dh, int ep, void *data, int len, int *ret_len);
|
||||
|
||||
#endif /* FX2USB_INTERFACE_H */
|
||||
|
@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
ORIG_HDR_DIR="$HOME/.wine/drive_c/Cypress/USB/Target/Inc/"
|
||||
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed -r '
|
||||
# OLD: EXTERN xdata volatile BYTE CPUCS _AT_ 0xE600;
|
||||
# NEW: xdata at 0xE600 volatile BYTE CPUCS;
|
||||
s/^EXTERN xdata volatile BYTE ([^ ]+)( +)_AT_ +([^ ;]+);/xdata at \3 volatile BYTE \1;\2/;
|
||||
|
||||
# OLD: sfr IOA = 0x80;
|
||||
# NEW: sfr at 0x80 IOA;
|
||||
s/^sfr ([^ ]+)( +)= ([^ ;]+);/sfr at \3 \1;\2/;
|
||||
|
||||
# OLD: sbit PA0 = 0x80 + 0;
|
||||
# NEW: sbit at (0x80 + 0) IOA;
|
||||
s/^( *)sbit ([^ ]+)( +)= ([^;]+);/\1sbit at (\4) \2;\3/;
|
||||
' < "$ORIG_HDR_DIR/fx2regs.h"; } > fx2regs.h
|
||||
|
||||
# hotfix line ending in Fx2.h
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed -r 's,\\ *,\\,;' < "$ORIG_HDR_DIR/Fx2.h"; } > fx2.h
|
||||
|
||||
# we do not have intrins.h but it seams quite clear what _nop_() does..
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed 's,^#include "intrins.h",#define _nop_() do { _asm nop; _endasm; } while(0),' < "$ORIG_HDR_DIR/fx2sdly.h"; } > fx2sdly.h
|
||||
|
@ -0,0 +1,292 @@
|
||||
// This program configures the General Programmable Interface (GPIF) for FX2.
|
||||
// Please do not modify sections of text which are marked as "DO NOT EDIT ...".
|
||||
//
|
||||
// DO NOT EDIT ...
|
||||
// GPIF Initialization
|
||||
// Interface Timing Sync
|
||||
// Internal Ready Init IntRdy=1
|
||||
// CTL Out Tristate-able Binary
|
||||
// SingleWrite WF Select 1
|
||||
// SingleRead WF Select 0
|
||||
// FifoWrite WF Select 3
|
||||
// FifoRead WF Select 2
|
||||
// Data Bus Idle Drive Tristate
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
// GPIF Wave Names
|
||||
// Wave 0 = Single R
|
||||
// Wave 1 = Single W
|
||||
// Wave 2 = FIFO Slo
|
||||
// Wave 3 = FIFO Wri
|
||||
|
||||
// GPIF Ctrl Outputs Level
|
||||
// CTL 0 = CTL0 CMOS
|
||||
// CTL 1 = CTL1 CMOS
|
||||
// CTL 2 = CTL2 CMOS
|
||||
// CTL 3 = CTL3 CMOS
|
||||
// CTL 4 = CTL4 CMOS
|
||||
// CTL 5 = CTL5 CMOS
|
||||
|
||||
// GPIF Rdy Inputs
|
||||
// RDY0 = RDY0
|
||||
// RDY1 = RDY1
|
||||
// RDY2 = RDY2
|
||||
// RDY3 = RDY3
|
||||
// RDY4 = RDY4
|
||||
// RDY5 = TCXpire
|
||||
// FIFOFlag = FIFOFlag
|
||||
// IntReady = IntReady
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 0: Single R
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode NO Data NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData SameData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
|
||||
// Term A
|
||||
// LFunc
|
||||
// Term B
|
||||
// Branch1
|
||||
// Branch0
|
||||
// Re-Exec
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 1 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 1 1 1 1 1 1
|
||||
// CTL2 1 1 1 1 1 1 1 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 1: Single W
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode Activate NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData NextData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 IF Wait 1 Wait 1
|
||||
// Term A FIFOFlag
|
||||
// LFunc AND
|
||||
// Term B FIFOFlag
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 ElseIdle
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 0 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 0 1 1 1 1 1
|
||||
// CTL2 1 0 1 0 1 1 1 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 2: FIFO Slo
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode NO Data Activate NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData SameData NextData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 254 Wait 1 Wait 254 IF Wait 1 Wait 1 Wait 1
|
||||
// Term A TCXpire
|
||||
// LFunc AND
|
||||
// Term B TCXpire
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 Else 0
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 1 0 1 1 1 1 1 1
|
||||
// CTL1 1 1 1 1 1 1 1 1
|
||||
// CTL2 1 1 1 0 0 0 0 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 3: FIFO Wri
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode Activate NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData NextData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 IF Wait 1 Wait 1 Wait 1
|
||||
// Term A TCXpire
|
||||
// LFunc AND
|
||||
// Term B TCXpire
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 Else 0
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 0 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 0 1 1 1 1 1
|
||||
// CTL2 1 0 1 0 0 0 0 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
|
||||
// GPIF Program Code
|
||||
|
||||
// DO NOT EDIT ...
|
||||
#include "fx2.h"
|
||||
#include "fx2regs.h"
|
||||
#include "fx2sdly.h" // SYNCDELAY macro
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata WaveData[128] =
|
||||
{
|
||||
// Wave 0
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
|
||||
// Wave 1
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x02, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x06, 0x03, 0x05, 0x03, 0x07, 0x07, 0x07, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x3F,
|
||||
// Wave 2
|
||||
/* LenBr */ 0xFE, 0x01, 0xFE, 0x38, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x00, 0x02, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x07, 0x06, 0x07, 0x03, 0x03, 0x03, 0x03, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
|
||||
// Wave 3
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x06, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata FlowStates[36] =
|
||||
{
|
||||
/* Wave 0 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 2 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 3 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata InitData[7] =
|
||||
{
|
||||
/* Regs */ 0xE0,0x00,0x00,0x07,0xEA,0x4E,0x00
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// TO DO: You may add additional code below.
|
||||
|
||||
void GpifInit( void )
|
||||
{
|
||||
BYTE i;
|
||||
|
||||
// Registers which require a synchronization delay, see section 15.14
|
||||
// FIFORESET FIFOPINPOLAR
|
||||
// INPKTEND OUTPKTEND
|
||||
// EPxBCH:L REVCTL
|
||||
// GPIFTCB3 GPIFTCB2
|
||||
// GPIFTCB1 GPIFTCB0
|
||||
// EPxFIFOPFH:L EPxAUTOINLENH:L
|
||||
// EPxFIFOCFG EPxGPIFFLGSEL
|
||||
// PINFLAGSxx EPxFIFOIRQ
|
||||
// EPxFIFOIE GPIFIRQ
|
||||
// GPIFIE GPIFADRH:L
|
||||
// UDMACRCH:L EPxGPIFTRIG
|
||||
// GPIFTRIG
|
||||
|
||||
// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
|
||||
// ...these have been replaced by GPIFTC[B3:B0] registers
|
||||
|
||||
// 8051 doesn't have access to waveform memories 'til
|
||||
// the part is in GPIF mode.
|
||||
|
||||
IFCONFIG = 0xEA;
|
||||
// IFCLKSRC=1 , FIFOs executes on internal clk source
|
||||
// xMHz=1 , 48MHz internal clk rate
|
||||
// IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
|
||||
// IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
|
||||
// ASYNC=1 , master samples asynchronous
|
||||
// GSTATE=1 , Drive GPIF states out on PORTE[2:0], debug WF
|
||||
// IFCFG[1:0]=10, FX2 in GPIF master mode
|
||||
|
||||
GPIFABORT = 0xFF; // abort any waveforms pending
|
||||
|
||||
GPIFREADYCFG = InitData[ 0 ];
|
||||
GPIFCTLCFG = InitData[ 1 ];
|
||||
GPIFIDLECS = InitData[ 2 ];
|
||||
GPIFIDLECTL = InitData[ 3 ];
|
||||
GPIFWFSELECT = InitData[ 5 ];
|
||||
GPIFREADYSTAT = InitData[ 6 ];
|
||||
|
||||
// use dual autopointer feature...
|
||||
AUTOPTRSETUP = 0x07; // inc both pointers,
|
||||
// ...warning: this introduces pdata hole(s)
|
||||
// ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
|
||||
|
||||
// source
|
||||
AUTOPTRH1 = MSB( &WaveData );
|
||||
AUTOPTRL1 = LSB( &WaveData );
|
||||
|
||||
// destination
|
||||
AUTOPTRH2 = 0xE4;
|
||||
AUTOPTRL2 = 0x00;
|
||||
|
||||
// transfer
|
||||
for ( i = 0x00; i < 128; i++ )
|
||||
{
|
||||
EXTAUTODAT2 = EXTAUTODAT1;
|
||||
}
|
||||
|
||||
// Configure GPIF Address pins, output initial value,
|
||||
PORTCCFG = 0xFF; // [7:0] as alt. func. GPIFADR[7:0]
|
||||
OEC = 0xFF; // and as outputs
|
||||
PORTECFG |= 0x80; // [8] as alt. func. GPIFADR[8]
|
||||
OEE |= 0x80; // and as output
|
||||
|
||||
// ...OR... tri-state GPIFADR[8:0] pins
|
||||
// PORTCCFG = 0x00; // [7:0] as port I/O
|
||||
// OEC = 0x00; // and as inputs
|
||||
// PORTECFG &= 0x7F; // [8] as port I/O
|
||||
// OEE &= 0x7F; // and as input
|
||||
|
||||
// GPIF address pins update when GPIFADRH/L written
|
||||
SYNCDELAY; //
|
||||
GPIFADRH = 0x00; // bits[7:1] always 0
|
||||
SYNCDELAY; //
|
||||
GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
|
||||
|
||||
// Configure GPIF FlowStates registers for Wave 0 of WaveData
|
||||
FLOWSTATE = FlowStates[ 0 ];
|
||||
FLOWLOGIC = FlowStates[ 1 ];
|
||||
FLOWEQ0CTL = FlowStates[ 2 ];
|
||||
FLOWEQ1CTL = FlowStates[ 3 ];
|
||||
FLOWHOLDOFF = FlowStates[ 4 ];
|
||||
FLOWSTB = FlowStates[ 5 ];
|
||||
FLOWSTBEDGE = FlowStates[ 6 ];
|
||||
FLOWSTBHPERIOD = FlowStates[ 7 ];
|
||||
}
|
||||
|
@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
. /opt/Xilinx/13.1/ISE_DS/settings32.sh
|
||||
|
||||
cat > hardware.prj <<- EOT
|
||||
verilog work "hardware.v"
|
||||
EOT
|
||||
|
||||
cat > hardware.lso <<- EOT
|
||||
work
|
||||
EOT
|
||||
|
||||
cat > hardware.xst <<- EOT
|
||||
set -tmpdir "xilinx/projnav.tmp"
|
||||
set -xsthdpdir "xilinx"
|
||||
run
|
||||
-ifn hardware.prj
|
||||
-ifmt mixed
|
||||
-ofn hardware
|
||||
-ofmt NGC
|
||||
-p xbr
|
||||
-top top
|
||||
-opt_mode Speed
|
||||
-opt_level 1
|
||||
-iuc NO
|
||||
-lso hardware.lso
|
||||
-keep_hierarchy YES
|
||||
-netlist_hierarchy as_optimized
|
||||
-rtlview Yes
|
||||
-hierarchy_separator /
|
||||
-bus_delimiter <>
|
||||
-case maintain
|
||||
-verilog2001 YES
|
||||
-fsm_extract YES -fsm_encoding Auto
|
||||
-safe_implementation No
|
||||
-mux_extract YES
|
||||
-resource_sharing YES
|
||||
-iobuf YES
|
||||
-pld_mp YES
|
||||
-pld_xp YES
|
||||
-pld_ce YES
|
||||
-wysiwyg NO
|
||||
-equivalent_register_removal YES
|
||||
EOT
|
||||
|
||||
cat > hardware.cmd <<- EOT
|
||||
setMode -bs
|
||||
setCable -port svf -file "hardware.svf"
|
||||
addDevice -p 1 -file "hardware.jed"
|
||||
Erase -p 1
|
||||
Program -p 1 -e -v
|
||||
Verify -p 1
|
||||
quit
|
||||
EOT
|
||||
|
||||
cat > erasecpld.cmd <<- EOT
|
||||
setMode -bs
|
||||
setCable -port svf -file "erasecpld.svf"
|
||||
addDevice -p 1 -file "hardware.jed"
|
||||
Erase -p 1
|
||||
quit
|
||||
EOT
|
||||
|
||||
set -ex
|
||||
|
||||
mkdir -p xilinx/projnav.tmp/
|
||||
xst -ifn "hardware.xst" -ofn "hardware.syr"
|
||||
|
||||
mkdir -p xilinx/_ngo/
|
||||
ngdbuild -dd xilinx/_ngo -uc hardware.ucf -p xc2c256-VQ100-6 hardware.ngc hardware.ngd
|
||||
|
||||
cpldfit -p xc2c256-7-VQ100 -ofmt verilog -optimize density -htmlrpt -loc on -slew fast -init low \
|
||||
-inputs 32 -pterms 28 -unused keeper -terminate keeper -iostd LVCMOS18 hardware.ngd
|
||||
|
||||
hprep6 -i hardware
|
||||
|
||||
impact -batch hardware.cmd
|
||||
sed -i '\,^// Date:, d;' hardware.svf
|
||||
|
||||
impact -batch erasecpld.cmd
|
||||
sed -i '\,^// Date:, d;' erasecpld.svf
|
||||
|
@ -0,0 +1,59 @@
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
NET "clk" LOC = "23" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "tck" LOC = "66" | IOSTANDARD = LVCMOS33;
|
||||
NET "tms" LOC = "67" | IOSTANDARD = LVCMOS33;
|
||||
NET "tdi" LOC = "68" | IOSTANDARD = LVCMOS33;
|
||||
NET "tdo" LOC = "27" | IOSTANDARD = LVCMOS33;
|
||||
NET "init" LOC = "28" | IOSTANDARD = LVCMOS33;
|
||||
NET "init_b" LOC = "70" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "fd0" LOC = "32" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd1" LOC = "33" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd2" LOC = "34" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd3" LOC = "35" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd4" LOC = "36" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd5" LOC = "37" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd6" LOC = "39" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd7" LOC = "40" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "ctl0" LOC = "22" | IOSTANDARD = LVCMOS33;
|
||||
NET "ctl1" LOC = "53" | IOSTANDARD = LVCMOS33;
|
||||
NET "ctl2" LOC = "54" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "pc0" LOC = "14" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc1" LOC = "15" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc2" LOC = "16" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc3" LOC = "17" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc4" LOC = "18" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc5" LOC = "19" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc6" LOC = "29" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc7" LOC = "30" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "pd0" LOC = "41" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd1" LOC = "42" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd2" LOC = "43" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd3" LOC = "44" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd4" LOC = "46" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd5" LOC = "49" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd6" LOC = "50" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd7" LOC = "52" | IOSTANDARD = LVCMOS33;
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
module top(
|
||||
clk,
|
||||
tck, tms, tdi, tdo, init, init_b,
|
||||
fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7,
|
||||
ctl0, ctl1, ctl2,
|
||||
pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7,
|
||||
pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7
|
||||
);
|
||||
|
||||
// General Signal
|
||||
input clk;
|
||||
|
||||
// JTAG Interface
|
||||
output tck, tms, tdi, init;
|
||||
input tdo, init_b;
|
||||
|
||||
// GPIF Interface
|
||||
input fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7;
|
||||
input ctl0, ctl1, ctl2;
|
||||
|
||||
// The entire PC and PD regs for various flags
|
||||
output pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7;
|
||||
input pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7;
|
||||
|
||||
// simple direct i/o mappings
|
||||
assign pc3 = tdo;
|
||||
assign pc1 = init_b;
|
||||
assign init = pd2;
|
||||
|
||||
// checksum
|
||||
wire chksum_rst, chksum_clk;
|
||||
reg [23:0] chksum_buffer;
|
||||
always @(posedge chksum_clk) begin
|
||||
if (chksum_rst)
|
||||
chksum_buffer <=
|
||||
`include "hardware_cksum_vl.inc"
|
||||
;
|
||||
else
|
||||
chksum_buffer <= chksum_buffer << 1;
|
||||
end
|
||||
assign chksum_rst = pd0;
|
||||
assign chksum_clk = pd1;
|
||||
assign pc2 = chksum_buffer[23];
|
||||
|
||||
// main engine
|
||||
reg [3:0] sync;
|
||||
reg [7:0] lastbyte;
|
||||
reg go_exec0, go_exec1, set_sync, err;
|
||||
reg reg_tck, reg_tms, reg_tdi, reg_tdo, reg_tdo_en;
|
||||
always @(negedge clk) begin
|
||||
go_exec0 <= 0;
|
||||
go_exec1 <= 0;
|
||||
if (!ctl0) begin
|
||||
lastbyte <= { fd7, fd6, fd5, fd4, fd3, fd2, fd1, fd0 };
|
||||
go_exec0 <= 1;
|
||||
end
|
||||
if (!ctl1) begin
|
||||
lastbyte <= lastbyte >> 4;
|
||||
go_exec0 <= 1;
|
||||
end
|
||||
if (!ctl2) begin
|
||||
go_exec1 <= 1;
|
||||
end
|
||||
if (go_exec0) begin
|
||||
reg_tdo_en <= 0;
|
||||
if (set_sync) begin
|
||||
sync <= lastbyte[3:0];
|
||||
set_sync <= 0;
|
||||
end else
|
||||
if (lastbyte[3:0] == 0) begin
|
||||
/* NOP */
|
||||
end else
|
||||
if (lastbyte[3:0] == 1) begin
|
||||
/* Set sync signal in next insn */
|
||||
set_sync <= 1;
|
||||
end else
|
||||
if (lastbyte[3:1] == 1) begin
|
||||
/* reserved */
|
||||
end else
|
||||
if (lastbyte[3:2] == 1) begin
|
||||
/* transaction with or without TDO check */
|
||||
reg_tck <= 0;
|
||||
reg_tdo <= 'bx;
|
||||
reg_tms <= lastbyte[1];
|
||||
reg_tdi <= lastbyte[0];
|
||||
end else
|
||||
if (lastbyte[3] == 1) begin
|
||||
/* transaction with TDO check */
|
||||
reg_tck <= 0;
|
||||
reg_tdo <= lastbyte[2];
|
||||
reg_tms <= lastbyte[1];
|
||||
reg_tdi <= lastbyte[0];
|
||||
reg_tdo_en <= 1;
|
||||
end
|
||||
end
|
||||
if (go_exec1) begin
|
||||
reg_tck <= 1;
|
||||
if (reg_tdo_en && tdo != reg_tdo)
|
||||
err <= 1;
|
||||
end
|
||||
if (pd3) begin
|
||||
/* RESET ERR */
|
||||
err <= 0;
|
||||
end
|
||||
if (pd4) begin
|
||||
/* RESET SYNC */
|
||||
set_sync <= 0;
|
||||
sync <= 0;
|
||||
end
|
||||
end
|
||||
assign tck = reg_tck;
|
||||
assign tms = reg_tms;
|
||||
assign tdi = reg_tdi;
|
||||
assign pc7 = sync[3];
|
||||
assign pc6 = sync[2];
|
||||
assign pc5 = sync[1];
|
||||
assign pc4 = sync[0];
|
||||
assign pc0 = err;
|
||||
|
||||
endmodule
|
||||
|
@ -0,0 +1,82 @@
|
||||
// Created using Xilinx Cse Software [ISE - 13.1]
|
||||
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
FREQUENCY 1E6 HZ;
|
||||
//Operation: Erase -p 0
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (01) SMASK (ff) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6d4f093) MASK (0fff8fff) ;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (03) ;
|
||||
//Boundary Scan Chain Contents
|
||||
//Position 1: xc2c256
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (01) ;
|
||||
SDR 32 TDI (00000000) TDO (f6d4f093) ;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (03) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
// Loading devices with 'enable' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
RUNTEST 200 TCK;
|
||||
// Loading devices with 'erase' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (ed) SMASK (ff) ;
|
||||
ENDIR IDLE;
|
||||
STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE;
|
||||
RUNTEST DRPAUSE 20 TCK;
|
||||
STATE IDLE;
|
||||
RUNTEST IDLE 100000 TCK;
|
||||
STATE DRPAUSE;
|
||||
RUNTEST DRPAUSE 5000 TCK;
|
||||
RUNTEST IDLE 1 TCK;
|
||||
// Loading devices with 'init' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (f0) SMASK (ff) ;
|
||||
STATE IDLE;
|
||||
RUNTEST IDLE 20 TCK;
|
||||
// Loading devices with 'init' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (f0) SMASK (ff) ;
|
||||
STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE;
|
||||
RUNTEST 800 TCK;
|
||||
ENDIR IDLE;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (c0) ;
|
||||
RUNTEST 100 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (c0) ;
|
||||
RUNTEST 100 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 8 TDI (ff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
@ -0,0 +1,323 @@
|
||||
:03000000020008F3
|
||||
:0300610002000397
|
||||
:05000300120B4A80FE13
|
||||
:0D00640090E60174EAF090E6F574FFF0906C
|
||||
:0E0071000C58E49390E6F3F0900C59E4939051
|
||||
:0D007F00E6C3F0900C5AE49390E6C1F090B7
|
||||
:0E008C000C5BE49390E6C2F0900C5DE4939060
|
||||
:0E009A00E6C0F0900C5EE49390E6F4F075AFD3
|
||||
:0800A800077AB47B0B8B9A7AF6
|
||||
:0A00B000B47B0B7B008A9B759DE476
|
||||
:0500BA00759E007A00B4
|
||||
:0300BF00BA800004
|
||||
:0E00C200500C90E67BE0FB90E67CF00A80EFAD
|
||||
:0E00D00090E67174FFF075B4FF90E672E0FAEE
|
||||
:0E00DE004480F043B68000000090E6C4E4F0D9
|
||||
:0E00EC0000000090E6C5E4F0900C34E4939020
|
||||
:0D00FA00E6C6F0900C35E49390E6C7F09058
|
||||
:0E0107000C36E49390E6C8F0900C37E4939029
|
||||
:0D011500E6C9F0900C38E49390E6CAF09033
|
||||
:0E0122000C39E49390E6CBF0900C3AE4939005
|
||||
:0D013000E6CCF0900C3BE49390E6CDF0227D
|
||||
:0E013D000000000000000000000000000000B4
|
||||
:0B014B00000000000000000000002287
|
||||
:04015600AA82AB834B
|
||||
:09015A008A048B051ABAFF011B8F
|
||||
:08016300EC4D60297C007D00D9
|
||||
:0E016B00C3EC94E8ED940350E6C002C003C05C
|
||||
:0E01790004C00512013DD005D004D003D00211
|
||||
:0901870074032CFCE43DFD80DB57
|
||||
:01019000224C
|
||||
:0D01910090E6007410F090E61274A8F09053
|
||||
:0D019E00E613E4F090E614F090E615F09002
|
||||
:0E01AB00E6047480F000000090E6047402F098
|
||||
:0D01B90000000090E6047404F000000090C7
|
||||
:0E01C600E6047406F000000090E6047408F0F1
|
||||
:0E01D40000000090E604E4F000000090E61841
|
||||
:0E01E200E0FA54FEF000000090E619E0FA5436
|
||||
:0E01F000FEF000000090E61AE0FA54FEF00067
|
||||
:0E01FE00000090E61BE0FA54FEF00000001234
|
||||
:0E020C00006490E670E4F075B22B75800090EF
|
||||
:0E021A00E671E4F075B40075A00075B51F75AF
|
||||
:0E022800B000D28390006412015675B658756E
|
||||
:04023600B1587A0041
|
||||
:03023A00BA1000F7
|
||||
:0E023D005013C00212013D53B1F712013DD023
|
||||
:07024B000243B1080A80E83C
|
||||
:010252002289
|
||||
:0E025300C28390006412015690E6F574FFF02D
|
||||
:0D02610000000090E6007402F00000009024
|
||||
:0E026E00E6017480F000000090E61274A2F029
|
||||
:0D027C0000000090E61374A0F00000009058
|
||||
:0E028900E61474A2F000000090E61574A0F0D8
|
||||
:0D02970000000090E6187405F000000090D3
|
||||
:0E02A400E6197405F000000090E61A7405F0EB
|
||||
:0D02B20000000090E61B7405F000000090B5
|
||||
:0E02BF00E6047480F000000090E6047402F083
|
||||
:0D02CD0000000090E6047404F000000090B2
|
||||
:0E02DA00E6047406F000000090E6047408F0DC
|
||||
:0E02E80000000090E604E4F0000000758000C5
|
||||
:0E02F60075A00075B00075B10075B20075B44A
|
||||
:0D0304000075B50075B60090E670E4F0904D
|
||||
:0A031100E671F075B2017A007B007E
|
||||
:0E031B00C3EA9403EB9400504BD2807CB87D73
|
||||
:010329000BC8
|
||||
:0E032A00C002C003C004C00512013DD005D0C2
|
||||
:0A03380004D003D0021CBCFF011D1D
|
||||
:0A034200EC4D70E4C2817CB87D0B25
|
||||
:0E034C00C002C003C004C00512013DD005D0A0
|
||||
:0A035A0004D003D0021CBCFF011DFB
|
||||
:0B036400EC4D70E40ABA00AF0B80AC57
|
||||
:03036F0075B20064
|
||||
:0E03720090E6A1E0FA20E10990E68D74FFF01C
|
||||
:030380000000007A
|
||||
:0E03830090E6A3E0FA20E2E790E69174FFF026
|
||||
:0503910000000080DC0B
|
||||
:0C039600AA82740F5A900C5F93F582222B
|
||||
:0503A200AA82BA300040
|
||||
:0D03A700400BEA24C64006EA24D0F582226D
|
||||
:0303B400BA61002B
|
||||
:0D03B700400BEA2499400674A92AF5822221
|
||||
:0303C400BA41003B
|
||||
:0D03C700400BEA24B9400674C92AF58222D1
|
||||
:0403D400758200220C
|
||||
:0E03D800E582FA700B90E6C0744EF000000053
|
||||
:0203E60080197C
|
||||
:0E03E80090E6C0744AF000000090E440EAF095
|
||||
:0B03F60000000090E442EAF00000006C
|
||||
:0E04010090E7C0744FF000000090E7C1744B0C
|
||||
:0E040F00F000000090E7C27420F000000090A2
|
||||
:0E041D00E7C37428F000000090E7C47454F0A8
|
||||
:0E042B00000000EAC4540FFB740F5BF582C0A2
|
||||
:0E04390002120396AB82D00290E7C5EBF000F2
|
||||
:0D0447000000740F5AF582120396AA8290ED
|
||||
:0E045400E7C6EAF000000090E7C77429F00048
|
||||
:0C046200000090E68F7408F000000022FB
|
||||
:05046E0075B1587A0091
|
||||
:03047300BA1000BC
|
||||
:0E0476005013C00212013D53B1F712013DD0E8
|
||||
:070484000243B1080A80E801
|
||||
:0C048B0090E6C0744EF000000075080000
|
||||
:0E049700C285C281C28075B01900000043B05A
|
||||
:0904A5000200000075B0007A00AD
|
||||
:0A04AE00EA2470FBE4340CFC7D80AE
|
||||
:0E04B8008B828C838DF0120B94FB6012EA2471
|
||||
:0E04C600C0F582E434E7F583EBF00000000A95
|
||||
:0204D40080D8CE
|
||||
:0904D60090E68FEAF0000000221C
|
||||
:0E04DF00AA8290E7C0744FF000000090E7C1C1
|
||||
:0E04ED00744BF000000090E7C27420F0000095
|
||||
:0E04FB000090E7C37428F000000090E7C4747E
|
||||
:0D05090057F00000008A82120396AA82902B
|
||||
:0E051600E7C5EAF000000090E7C67429F00087
|
||||
:0C052400000090E68F7407F00000002239
|
||||
:0E053000AA8290E7C07454F000000090E7C16A
|
||||
:0E053E007449F000000090E7C2744DF0000018
|
||||
:0E054C000090E7C37445F000000090E7C4740F
|
||||
:0E055A004FF000000090E7C57455F00000005F
|
||||
:0E05680090E7C67454F000000090E7C77421BD
|
||||
:0E057600F000000090E7C87420F00000009034
|
||||
:0E058400E7C97453F000000090E7CA743DF020
|
||||
:0D059200000000E5A0C4540FF582C0021265
|
||||
:0E059F000396AB82D00290E7CBEBF000000099
|
||||
:0E05AD0090E7CC7420F000000090E7CD742899
|
||||
:0E05BB00F000000090E7CE7457F00000008AB8
|
||||
:0E05C90082120396AA8290E7CFEAF0000000AB
|
||||
:0E05D70090E7D07429F000000090E68F7411B8
|
||||
:0505E500F000000022FF
|
||||
:0605EA00AA827B007C00E8
|
||||
:0D05F000C3EB94E8EC9403504C7D007E00BA
|
||||
:0E05FD00C3ED94E8EE94035038E5A0C4540F0B
|
||||
:09060B00FFB502058A820204DF3A
|
||||
:0E06140090E6A3E0FF20E21BD280C002C003EC
|
||||
:0E062200C004C005C006120B08D006D005D0DB
|
||||
:0706300004D003D002C280D8
|
||||
:070637000DBD00C20E80BFE3
|
||||
:07063E000BBB00AE0C80AB0A
|
||||
:050645008A820205306D
|
||||
:0E064A00D2B0C2B1000000D2B1000000C2B0B8
|
||||
:04065800C2B17A00B1
|
||||
:03065C00BA0600DB
|
||||
:06065F0050477B007C0007
|
||||
:03066500BC0400D2
|
||||
:0E0668005017EB2BFDA2A2E433FE4DFB000069
|
||||
:0B06760000D2B1000000C2B10C80E413
|
||||
:0E068100EA24C0FCE434E7FD8B82C002C00412
|
||||
:0E068F00C005120396AB82D005D004D0028CB9
|
||||
:0B069D00828D83EBF00000000A80B4A7
|
||||
:0E06A80090E7C67420F000000090E7C77428A9
|
||||
:0E06B600F000000090E7C87443F000000090D0
|
||||
:0E06C400E7C97429F000000090E68F740AF078
|
||||
:0406D2000000002202
|
||||
:0E06D600E582FA24FF928590E7C0744FF00091
|
||||
:0E06E400000090E7C1744BF000000090E7C2E8
|
||||
:0E06F2007420F000000090E7C37428F00000B0
|
||||
:0E0700000090E7C47442F0000000EA60047A42
|
||||
:03070E0031800235
|
||||
:020711007A303C
|
||||
:0E07130090E7C5EAF000000090E7C67429F0F8
|
||||
:0D07210000000090E68F7407F00000002239
|
||||
:0E072E00E582FA24FF92B290E7C0744FF0000B
|
||||
:0E073C00000090E7C1744BF000000090E7C28F
|
||||
:0E074A007420F000000090E7C37428F0000057
|
||||
:0E0758000090E7C47449F0000000EA60047AE3
|
||||
:03076600318002DD
|
||||
:020769007A30E4
|
||||
:0E076B0090E7C5EAF000000090E7C67429F0A0
|
||||
:0D07790000000090E68F7407F000000022E1
|
||||
:0707860030A0047A3180026B
|
||||
:02078D007A30C0
|
||||
:0C078F0090E7C0EAF0000000E5086004FC
|
||||
:04079B007A3180022D
|
||||
:02079F007A30AE
|
||||
:0E07A10090E7C1EAF000000030A1047A318038
|
||||
:0107AF000247
|
||||
:0207B0007A309D
|
||||
:0E07B20090E7C2EAF00000003082047A318045
|
||||
:0107C0000236
|
||||
:0207C1007A308C
|
||||
:0E07C30090E7C3EAF000000030A3047A318012
|
||||
:0107D1000225
|
||||
:0207D2007A307B
|
||||
:0E07D40090E7C4EAF0000000E5B130E5047AD9
|
||||
:0307E20031800261
|
||||
:0207E5007A3068
|
||||
:0E07E70090E7C5EAF0000000E5A0C4540FF54D
|
||||
:0E07F50082120396AA8290E7C6EAF000000086
|
||||
:0E08030090E7C77420F000000090E7C874284A
|
||||
:0E081100F000000090E7C97453F00000009062
|
||||
:0E081F00E7CA7429F000000090E68F740BF019
|
||||
:0C082D0000000075080075B00800000015
|
||||
:0708390000000053B0F7229C
|
||||
:0708400030A0047A318002B0
|
||||
:020847007A3005
|
||||
:0C08490090E7C0EAF0000000E508600441
|
||||
:040855007A31800272
|
||||
:020859007A30F3
|
||||
:0E085B0090E7C1EAF000000030A1047A31807D
|
||||
:01086900028C
|
||||
:02086A007A30E2
|
||||
:0E086C0090E7C2EAF00000003082047A31808A
|
||||
:01087A00027B
|
||||
:02087B007A30D1
|
||||
:0E087D0090E7C3EAF000000030A3047A318057
|
||||
:01088B00026A
|
||||
:02088C007A30C0
|
||||
:0E088E0090E7C4EAF0000000E5B130E5047A1E
|
||||
:03089C00318002A6
|
||||
:02089F007A30AD
|
||||
:0E08A10090E7C5EAF0000000E5A0C4540FF592
|
||||
:0E08AF0082120396AA8290E7C6EAF0000000CB
|
||||
:0E08BD0090E7C77420F000000090E7C8742890
|
||||
:0E08CB00F000000090E7C97450F000000090AB
|
||||
:0E08D900E7CA7429F000000090E68F740BF05F
|
||||
:0408E70000000022EB
|
||||
:0A08EB00AA82E509600475090022E5
|
||||
:0408F500EA70012282
|
||||
:0708F900BA01047509012298
|
||||
:0E090000740C5AFBBB0428EA30E10543B11029
|
||||
:02090E00800364
|
||||
:0309100053B1EFF1
|
||||
:09091300EA30E00543B140800325
|
||||
:03091C0053B1BF15
|
||||
:0E091F0000000053B1F712013D43B108000083
|
||||
:02092D000022A6
|
||||
:0E092F0074085AFBBB0848EA30E10543B110DA
|
||||
:02093D00800335
|
||||
:03093F0053B1EFC2
|
||||
:09094200EA30E00543B1408003F6
|
||||
:03094B0053B1BFE6
|
||||
:0E094E0000000053B1F7C00212013DD0024379
|
||||
:0D095C00B108000000530204E4BA000104D9
|
||||
:0B096900FA742055B1FBE4BB00010450
|
||||
:07097400FBEAB5030280035A
|
||||
:03097B00750801FB
|
||||
:01097E002256
|
||||
:07097F00AA827509007B014B
|
||||
:0E098600C3EB9A502CEB2480F582E434E7F5A5
|
||||
:0E09940083E0FC740F5CF582C002C003C00457
|
||||
:0E09A2001208EBD004ECC4540FF5821208EBDF
|
||||
:0709B000D003D0020B80CF41
|
||||
:0109B700221D
|
||||
:0E09B80090E7C0744FF000000090E7C1744B50
|
||||
:0E09C600F000000090E7C27420F000000090E6
|
||||
:0E09D400E7C37428F000000090E7C47458F0E8
|
||||
:0D09E20000000090E7C57429F000000090AF
|
||||
:0E09EF00E68F7406F000000090E68D74FFF0B5
|
||||
:0609FD000000000202539D
|
||||
:0E0A030090E68DE0FA90E780E0FBBB542BBA42
|
||||
:0E0A1100032890E781E0F5821203A2E582C47B
|
||||
:0E0A1F0054F0FC90E782E0F582C0041203A2BE
|
||||
:0E0A2D00AD82D004ED4CF5821203D8020AFE11
|
||||
:0C0A3B00BB5209BA010612046E020AFE4A
|
||||
:0D0A4700BB5712BA020F90E781E0F5821252
|
||||
:060A540003A21205EA02F4
|
||||
:020A5A000AFE92
|
||||
:0C0A5C00BB4309BA010612064A020AFE5A
|
||||
:0E0A6800BB4215BA021290E781E0FCE4BC31FB
|
||||
:020A7600010479
|
||||
:080A7800F5821206D6020AFE07
|
||||
:0E0A8000BB4914BA021190E781E0FCE4BC31DE
|
||||
:020A8E00010461
|
||||
:070A9000F58212072E8067BA
|
||||
:0B0A9700BB5308BA0105120786805C03
|
||||
:0B0AA200BB5008BA010512084080514B
|
||||
:0A0AAD00BB4A078A8212097F8047C6
|
||||
:080AB700BB58051209B8803F8D
|
||||
:0E0ABF0090E7C07445F000000090E7C174524B
|
||||
:0E0ACD00F000000090E7C27452F000000090AC
|
||||
:0E0ADB00E7C3744FF000000090E7C47452F0BF
|
||||
:0D0AE90000000090E7C57421F000000090AF
|
||||
:080AF600E68F7406F000000019
|
||||
:0A0AFE0090E68D74FFF00000002266
|
||||
:0E0B080090E690E0FB7A0090E691E0FC7D0024
|
||||
:0E0B16004202ED4203EA4B700A90E69174FF32
|
||||
:050B2400F000000022BA
|
||||
:0E0B2900E5BB30E7FB90E690E090E6D0F09060
|
||||
:0D0B3700E691E090E6D1F090E691E4F090B8
|
||||
:060B4400E6D474FFF0226C
|
||||
:0C0B4A0075080012019190E69174FFF014
|
||||
:0D0B560000000090E69174FFF00000009098
|
||||
:0E0B6300E69174FFF000000090E69174FFF040
|
||||
:030B710000000081
|
||||
:0E0B740090E6A1E0FA20E107D281120A03C246
|
||||
:010B820081F1
|
||||
:0E0B830090E6A3E0FA20E2E9D280120B08C24D
|
||||
:030B91008080E081
|
||||
:0E0BB400010101010101010700000000000025
|
||||
:0E0BC2000000070707070707070700000000ED
|
||||
:0E0BD0000000003F010101013F010107020486
|
||||
:0E0BDE000000010000000603050307070707DB
|
||||
:0E0BEC00000000003600003FFE01FE3801014F
|
||||
:0E0BFA000107000204010000000007060703C7
|
||||
:0E0C0800030303070000002D0000003F010160
|
||||
:0E0C1600013801010107020400010000000086
|
||||
:0E0C240006030503030303070000002D000074
|
||||
:020C3200003F81
|
||||
:0E0C34000000000000000000000000000000B2
|
||||
:0E0C42000000000000000000000000000000A4
|
||||
:080C500000000000000000009C
|
||||
:070C5800E0000007EA4E0076
|
||||
:0E0C5F00303132333435363738394142434470
|
||||
:030C6D00454600F9
|
||||
:070C70004F4B202852290020
|
||||
:06003700E478FFF6D8FD9D
|
||||
:080015007900E94400601B7A48
|
||||
:05001D0000900C777853
|
||||
:030022000075A0C6
|
||||
:0A00250020E493F2A308B8000205DE
|
||||
:08002F00A0D9F4DAF275A0FF7C
|
||||
:08003D007800E84400600A7934
|
||||
:030045000075A0A3
|
||||
:0600480020E4F309D8FCDE
|
||||
:08004E007800E84400600C7921
|
||||
:0B00560000902000E4F0A3D8FCD9FAD1
|
||||
:03000800758109F6
|
||||
:0A000B00120BB0E58260030200034F
|
||||
:0E0B940020F71430F6148883A88220F507E6B7
|
||||
:060BA200A8837583002208
|
||||
:030BA800E280F7F1
|
||||
:030BAB00E49322AE
|
||||
:020BAE00E02243
|
||||
:040BB0007582002228
|
||||
:00000001FF
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Reset probe to Xilinx Firmware using 'impact'
|
||||
# (see README file for details)
|
||||
#
|
||||
|
||||
ISEDIR="/opt/Xilinx/11.3/ISE"
|
||||
|
||||
finddev() {
|
||||
for id in 03fd:0009 03fd:000d 03fd:000f 04b4:8613; do lsusb -d $id; done | \
|
||||
head -n 1 | sed -r 's,^Bus ([0-9]+) Device ([0-9]+).*,/dev/bus/usb/\1/\2,'
|
||||
}
|
||||
|
||||
v() {
|
||||
echo "+ $*"
|
||||
"$@"
|
||||
}
|
||||
|
||||
batchfile=$( mktemp )
|
||||
trap 'rm "$batchfile"' 0
|
||||
|
||||
cat << EOT > "$batchfile"
|
||||
setMode -bs
|
||||
setCable -port usb21
|
||||
# identify
|
||||
quit
|
||||
EOT
|
||||
|
||||
v fxload -t fx2 -D $(finddev) -I "$ISEDIR"/bin/lin/xusb_emb.hex
|
||||
|
||||
for x in 0 1 2 3 4 5 6 7; do
|
||||
lsusb -d "03fd:0008" && break
|
||||
echo "Waiting for probe to re-enumerate.."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo -n "Waiting for probe to settle.."
|
||||
for x in 1 2 3 4 5; do echo -n .; sleep 1; done; echo
|
||||
|
||||
v "$ISEDIR"/bin/lin/impact -batch "$batchfile"
|
||||
|
@ -0,0 +1,720 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "libxsvf.h"
|
||||
#include "fx2usb-interface.h"
|
||||
|
||||
#include "filedata.h"
|
||||
|
||||
char *correct_cksum =
|
||||
#include "hardware_cksum_c.inc"
|
||||
;
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||
|
||||
// This is to not confuse the VIM syntax highlighting
|
||||
#define CHECK_VAL_OPEN (
|
||||
#define CHECK_VAL_CLOSE )
|
||||
|
||||
#define CHECK(result, check) \
|
||||
CHECK_VAL_OPEN{ \
|
||||
typeof(result) _R = (result); \
|
||||
if (!(_R check)) { \
|
||||
fprintf(stderr, "Error from '%s' (%d %s) in %s:%d.\n", \
|
||||
#result, (int)_R, #check, __FILE__, __LINE__); \
|
||||
fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \
|
||||
abort(); \
|
||||
} \
|
||||
_R; \
|
||||
}CHECK_VAL_CLOSE
|
||||
|
||||
#define CHECK_PTR(result, check) \
|
||||
CHECK_VAL_OPEN{ \
|
||||
typeof(result) _R = (result); \
|
||||
if (!(_R check)) { \
|
||||
fprintf(stderr, "Error from '%s' (%p %s) in %s:%d.\n", \
|
||||
#result, (void*)_R, #check, __FILE__, __LINE__); \
|
||||
fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \
|
||||
abort(); \
|
||||
} \
|
||||
_R; \
|
||||
}CHECK_VAL_CLOSE
|
||||
|
||||
/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||
|
||||
FILE *file_fp = NULL;
|
||||
|
||||
int usb_vendor_id = 0;
|
||||
int usb_device_id = 0;
|
||||
char *usb_device_file = NULL;
|
||||
|
||||
int mode_frequency = 6000;
|
||||
int mode_async_check = 0;
|
||||
int mode_internal_cpld = 0;
|
||||
int mode_8bit_per_cycle = 0;
|
||||
int mode_hex_rmask = 0;
|
||||
|
||||
usb_dev_handle *fx2usb;
|
||||
int internal_jtag_scan_test = 0;
|
||||
|
||||
int sync_count;
|
||||
int tck_cycle_count;
|
||||
int blocks_without_sync;
|
||||
|
||||
int tdo_check_period_100;
|
||||
int tdo_check_thisperiod;
|
||||
|
||||
int rmask_bits = 0, rmask_bytes = 0;
|
||||
unsigned char *rmask_data = NULL;
|
||||
|
||||
/* This constant are used to determine when the error status should be synced.
|
||||
* Syncinc to often would slow things down, syncinc not often enough might cause
|
||||
* errors beeing reported by far to late.
|
||||
*/
|
||||
#define FORCE_SYNC_AFTER_N_BLOCKS 100
|
||||
#define FORCE_SYNC_MIN_PERIOD 10000
|
||||
#define FORCE_SYNC_INIT_PERIOD 100000
|
||||
|
||||
// send larger junks to USB stack and let the kernel split it up
|
||||
// #define MAXBUF() (mode_internal_cpld ? 50 : mode_8bit_per_cycle ? 500 : 1000)
|
||||
#define MAXBUF() (mode_internal_cpld ? 50 : 4000)
|
||||
|
||||
unsigned char fx2usb_retbuf[65];
|
||||
int fx2usb_retlen;
|
||||
|
||||
unsigned char commandbuf[4096];
|
||||
int commandbuf_len;
|
||||
|
||||
static void shrink_8bit_to_4bit()
|
||||
{
|
||||
int i;
|
||||
if ((commandbuf_len & 1) != 0)
|
||||
commandbuf[commandbuf_len++] = 0;
|
||||
for (i = 0; i<commandbuf_len; i++) {
|
||||
if ((i & 1) == 0)
|
||||
commandbuf[i >> 1] = (commandbuf[i >> 1] & 0xf0) | commandbuf[i];
|
||||
else
|
||||
commandbuf[i >> 1] = (commandbuf[i >> 1] & 0x0f) | (commandbuf[i] << 4);
|
||||
}
|
||||
commandbuf_len = commandbuf_len >> 1;
|
||||
}
|
||||
|
||||
void fx2usb_command(const char *cmd)
|
||||
{
|
||||
// fprintf(stderr, "Sending FX2USB Command: '%s' => ", cmd);
|
||||
fx2usb_send_chunk(fx2usb, 1, cmd, strlen(cmd));
|
||||
fx2usb_recv_chunk(fx2usb, 1, fx2usb_retbuf, sizeof(fx2usb_retbuf)-1, &fx2usb_retlen);
|
||||
fx2usb_retbuf[fx2usb_retlen] = 0;
|
||||
// fprintf(stderr, "'%s'\n", fx2usb_retbuf);
|
||||
|
||||
if (strchr((char*)fx2usb_retbuf, '!') != NULL) {
|
||||
fprintf(stderr, "Internal ERROR in communication with probe: '%s' => '%s'\n", cmd, fx2usb_retbuf);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v);
|
||||
static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask UNUSED, int sync);
|
||||
|
||||
static int xpcu_setup(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
sync_count = 0;
|
||||
blocks_without_sync = 0;
|
||||
commandbuf_len = 0;
|
||||
fx2usb_command("R");
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
fx2usb_command("B1");
|
||||
}
|
||||
|
||||
if (mode_frequency)
|
||||
xpcu_set_frequency(h, mode_frequency * 1000);
|
||||
|
||||
tdo_check_period_100 = FORCE_SYNC_INIT_PERIOD * 100;
|
||||
tdo_check_thisperiod = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpcu_shutdown(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
int rc = 0;
|
||||
if (commandbuf_len != 0) {
|
||||
fprintf(stderr, "Found %d unsynced commands in command buffer on interface shutdown!\n", commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
rc = -1;
|
||||
}
|
||||
fx2usb_command("S");
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1') {
|
||||
fprintf(stderr, "Found pending errors in interface status on shutdown!\n");
|
||||
rc = -1;
|
||||
}
|
||||
fx2usb_command("R");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void xpcu_udelay(struct libxsvf_host *h UNUSED, long usecs, int tms, long num_tck)
|
||||
{
|
||||
struct timeval tv1, tv2;
|
||||
long rem_usecs;
|
||||
|
||||
if (mode_internal_cpld)
|
||||
{
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
|
||||
fx2usb_command("P");
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
|
||||
while (num_tck > 0) {
|
||||
xpcu_pulse_tck(h, tms, 0, -1, 0, 0);
|
||||
num_tck--;
|
||||
}
|
||||
|
||||
if (mode_internal_cpld)
|
||||
{
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
|
||||
fx2usb_command("P");
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
while (usecs > 0) {
|
||||
gettimeofday(&tv2, NULL);
|
||||
rem_usecs = usecs - ((tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec));
|
||||
if (rem_usecs <= 0)
|
||||
break;
|
||||
usleep(rem_usecs);
|
||||
}
|
||||
}
|
||||
|
||||
static int xpcu_getbyte(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
return fgetc(file_fp);
|
||||
}
|
||||
|
||||
static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask, int sync)
|
||||
{
|
||||
int dummy_sync = 0;
|
||||
|
||||
tck_cycle_count++;
|
||||
|
||||
if (tdo >= 0) {
|
||||
commandbuf[commandbuf_len++] = 0x08 | ((tdo & 1) << 2) | ((tms & 1) << 1) | ((tdi & 1) << 0);
|
||||
tdo_check_period_100 = (tdo_check_period_100 * 99) / 100 + tdo_check_thisperiod;
|
||||
tdo_check_thisperiod = 0;
|
||||
} else {
|
||||
commandbuf[commandbuf_len++] = 0x04 | ((tms & 1) << 1) | ((tdi & 1) << 0);
|
||||
}
|
||||
|
||||
if (mode_async_check == 0)
|
||||
{
|
||||
if (!sync && tdo >= 0 && (blocks_without_sync > FORCE_SYNC_AFTER_N_BLOCKS || tdo_check_period_100 > FORCE_SYNC_MIN_PERIOD))
|
||||
sync = 1;
|
||||
if (!sync && !mode_internal_cpld && blocks_without_sync > 10*FORCE_SYNC_AFTER_N_BLOCKS && commandbuf_len >= (MAXBUF() - 10))
|
||||
dummy_sync = 1;
|
||||
}
|
||||
|
||||
if (rmask && !sync)
|
||||
dummy_sync = 1;
|
||||
|
||||
if ((dummy_sync || sync) && !mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (commandbuf_len >= (MAXBUF() - 4) || sync || dummy_sync) {
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
blocks_without_sync++;
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
|
||||
if ((sync || dummy_sync) && !mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
fx2usb_command("S");
|
||||
blocks_without_sync = 0;
|
||||
}
|
||||
|
||||
if (dummy_sync) {
|
||||
fx2usb_command("P");
|
||||
blocks_without_sync = 0;
|
||||
}
|
||||
|
||||
if (rmask) {
|
||||
if (rmask_bits >= 8*rmask_bytes) {
|
||||
int old_rmask_bytes = rmask_bytes;
|
||||
rmask_bytes = rmask_bytes ? rmask_bytes*2 : 64;
|
||||
rmask_data = realloc(rmask_data, rmask_bytes);
|
||||
memset(rmask_data + old_rmask_bytes, 0, rmask_bytes-old_rmask_bytes);
|
||||
}
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1')
|
||||
rmask_data[rmask_bits/8] |= 1 << (rmask_bits%8);
|
||||
rmask_bits++;
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1')
|
||||
return -1;
|
||||
return fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1';
|
||||
}
|
||||
return tdo < 0 ? 1 : tdo;
|
||||
}
|
||||
|
||||
static int xpcu_sync(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
if (!mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
commandbuf_len = 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
fx2usb_command("S");
|
||||
blocks_without_sync = 0;
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1')
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v)
|
||||
{
|
||||
int freq = 24000000, delay = 0;
|
||||
|
||||
if (mode_internal_cpld)
|
||||
return 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
commandbuf_len = 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
while (delay < 250 && v < freq) {
|
||||
delay++;
|
||||
freq = 48000000 / (2*delay + 2);
|
||||
}
|
||||
|
||||
if (v < freq)
|
||||
fprintf(stderr, "Requested FREQUENCY %dHz is to low! Using minimum value %dHz instead.\n", v, freq);
|
||||
else if (v-freq > 10)
|
||||
fprintf(stderr, "Requested FREQUENCY is %dHz. Using %dHz (24MHz/%d) instead.\n", v, freq, delay+1);
|
||||
|
||||
char cmd[4];
|
||||
snprintf(cmd, 4, "T%02x", delay);
|
||||
fx2usb_command(cmd);
|
||||
|
||||
mode_8bit_per_cycle = delay != 0;
|
||||
|
||||
if (!mode_internal_cpld)
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xpcu_report_tapstate(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
// fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state));
|
||||
}
|
||||
|
||||
static void xpcu_report_device(struct libxsvf_host *h UNUSED, unsigned long idcode)
|
||||
{
|
||||
if (internal_jtag_scan_test != 0) {
|
||||
// CPLD should be: idcode=0x16d4a093, revision=0x1, part=0x6d4a, manufactor=0x049
|
||||
if (((idcode >> 12) & 0xffff) == 0x6d4a && ((idcode >> 1) & 0x7ff) == 0x049)
|
||||
internal_jtag_scan_test += 1;
|
||||
else
|
||||
internal_jtag_scan_test += 2;
|
||||
} else {
|
||||
printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
|
||||
(idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
|
||||
}
|
||||
}
|
||||
|
||||
static void xpcu_report_status(struct libxsvf_host *h UNUSED, const char *message UNUSED)
|
||||
{
|
||||
// fprintf(stderr, "[STATUS] %s\n", message);
|
||||
}
|
||||
|
||||
static void xpcu_report_error(struct libxsvf_host *h UNUSED, const char *file, int line, const char *message)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] %s\n", file, line, message);
|
||||
}
|
||||
|
||||
static void *xpcu_realloc(struct libxsvf_host *h UNUSED, void *ptr, int size, enum libxsvf_mem which UNUSED)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static struct libxsvf_host h = {
|
||||
.udelay = xpcu_udelay,
|
||||
.setup = xpcu_setup,
|
||||
.shutdown = xpcu_shutdown,
|
||||
.getbyte = xpcu_getbyte,
|
||||
.pulse_tck = xpcu_pulse_tck,
|
||||
.sync = xpcu_sync,
|
||||
.set_frequency = xpcu_set_frequency,
|
||||
.report_tapstate = xpcu_report_tapstate,
|
||||
.report_device = xpcu_report_device,
|
||||
.report_status = xpcu_report_status,
|
||||
.report_error = xpcu_report_error,
|
||||
.realloc = xpcu_realloc
|
||||
};
|
||||
|
||||
const char *progname;
|
||||
|
||||
static void help()
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "A JTAG SVF/XSVF Player based on libxsvf for the Xilinx Platform Cable USB\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "xsvftool-xpcu, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n");
|
||||
fprintf(stderr, "Copyright (C) 2011 RIEGL Research ForschungsGmbH\n");
|
||||
fprintf(stderr, "Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>\n");
|
||||
fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [ -L | -B ] [ -d <vendor>:<device> | -D <device_file> ] [ -f kHz ] [ -A ] [ -P ]\n", progname);
|
||||
fprintf(stderr, " %*s { -E | -p | -s svf-file | -x xsvf-file | -c } ...\n", (int)strlen(progname), "");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -L, -B\n");
|
||||
fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -d <vendor>:<device>\n");
|
||||
fprintf(stderr, " Open the device with this USB vendor and device ID.\n");
|
||||
fprintf(stderr, " (default: 03fd:000d and 04b4:8613\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -D <device_file>\n");
|
||||
fprintf(stderr, " Open this USB device (usually something like /dev/bus/usb/012/345)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -f kHz\n");
|
||||
fprintf(stderr, " Run probe with the specified frequency (default=6000, max=24000)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -A\n");
|
||||
fprintf(stderr, " Use full asynchonous error checking\n");
|
||||
fprintf(stderr, " (very fast but error reporting might be delayed)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -P\n");
|
||||
fprintf(stderr, " Use CPLD on probe as target device\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -p\n");
|
||||
fprintf(stderr, " Force (re-)programming the CPLD on the probe\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -E\n");
|
||||
fprintf(stderr, " Erase the CPLD on the probe\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -s svf-file\n");
|
||||
fprintf(stderr, " Play the specified SVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -x xsvf-file\n");
|
||||
fprintf(stderr, " Play the specified XSVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -c\n");
|
||||
fprintf(stderr, " List devices in JTAG chain\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
int gotaction = 0;
|
||||
int opt, i, j;
|
||||
|
||||
int done_initialization = 0;
|
||||
|
||||
progname = argc >= 1 ? argv[0] : "xsvftool-xpcu";
|
||||
while ((opt = getopt(argc, argv, "LBd:D:f:APpEs:x:c")) != -1)
|
||||
{
|
||||
if (!done_initialization && (opt == 'p' || opt == 'E' || opt == 's' || opt == 'x' || opt == 'c'))
|
||||
{
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
fx2usb = fx2usb_open(usb_vendor_id, usb_device_id, usb_device_file);
|
||||
if (fx2usb == NULL) {
|
||||
fprintf(stderr, "Failed to find or open USB device!\n");
|
||||
exit(1);
|
||||
}
|
||||
CHECK(fx2usb_claim(fx2usb), == 0);
|
||||
|
||||
FILE *ihexf = CHECK_PTR(fmemopen(firmware_ihx, sizeof(firmware_ihx), "r"), != NULL);
|
||||
CHECK(fx2usb_upload_ihex(fx2usb, ihexf), == 0);
|
||||
CHECK(fclose(ihexf), == 0);
|
||||
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
internal_jtag_scan_test = 1;
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SCAN);
|
||||
|
||||
if (internal_jtag_scan_test != 2) {
|
||||
fprintf(stderr, "Probe (device %s on bus %s) failed internal JTAG scan test!\n",
|
||||
usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname);
|
||||
exit(1);
|
||||
}
|
||||
mode_internal_cpld = i;
|
||||
internal_jtag_scan_test = 0;
|
||||
|
||||
fprintf(stderr, "Connected to probe (device %s on bus %s) and passed internal JTAG scan test.\n",
|
||||
usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname);
|
||||
|
||||
if (opt != 'p' && opt != 'E' && !mode_internal_cpld) {
|
||||
fx2usb_command("C");
|
||||
if (memcmp(correct_cksum, fx2usb_retbuf, 6)) {
|
||||
fprintf(stderr, "Mismatch in CPLD checksum (is=%.6s, should=%s): reprogramming CPLD on probe..\n",
|
||||
fx2usb_retbuf, correct_cksum);
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL);
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SVF);
|
||||
mode_internal_cpld = i;
|
||||
fclose(file_fp);
|
||||
}
|
||||
}
|
||||
|
||||
done_initialization = 1;
|
||||
}
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 'L':
|
||||
mode_hex_rmask = 1;
|
||||
break;
|
||||
case 'B':
|
||||
mode_hex_rmask = 2;
|
||||
break;
|
||||
case 'd':
|
||||
if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb)
|
||||
help();
|
||||
if (sscanf(optarg, "%x:%x", &usb_vendor_id, &usb_device_id) != 2)
|
||||
help();
|
||||
break;
|
||||
case 'D':
|
||||
if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb)
|
||||
help();
|
||||
usb_device_file = strdup(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
mode_frequency = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
mode_internal_cpld = 1;
|
||||
break;
|
||||
case 'A':
|
||||
mode_async_check = 1;
|
||||
break;
|
||||
case 'p':
|
||||
case 'E':
|
||||
gotaction = 1;
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
if (opt == 'p') {
|
||||
file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL);
|
||||
fprintf(stderr, "(Re-)programming CPLD on the probe..\n");
|
||||
} else {
|
||||
file_fp = CHECK_PTR(fmemopen(erasecpld_svf, sizeof(erasecpld_svf), "r"), != NULL);
|
||||
fprintf(stderr, "Erasing CPLD on the probe..\n");
|
||||
}
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SVF);
|
||||
mode_internal_cpld = i;
|
||||
fclose(file_fp);
|
||||
break;
|
||||
case 'x':
|
||||
case 's':
|
||||
gotaction = 1;
|
||||
if (!strcmp(optarg, "-"))
|
||||
file_fp = stdin;
|
||||
else
|
||||
file_fp = fopen(optarg, "rb");
|
||||
if (file_fp == NULL) {
|
||||
fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "Playing %s file `%s'..\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
|
||||
fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
rc = 1;
|
||||
}
|
||||
if (strcmp(optarg, "-"))
|
||||
fclose(file_fp);
|
||||
break;
|
||||
case 'c':
|
||||
gotaction = 1;
|
||||
fprintf(stderr, "Scanning JTAG chain..\n");
|
||||
if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
|
||||
fprintf(stderr, "Error while scanning JTAG chain.\n");
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotaction)
|
||||
help();
|
||||
|
||||
if (rmask_bits > 0) {
|
||||
fprintf(stderr, "Total number of rmask bits acquired: %d\n", rmask_bits);
|
||||
if (mode_hex_rmask) {
|
||||
printf("0x");
|
||||
for (i = 0; i < rmask_bits; i += 4) {
|
||||
int val = 0;
|
||||
for (j = i; j < i + 4; j++) {
|
||||
int pos = mode_hex_rmask > 1 ? j : rmask_bits - j - 1;
|
||||
val = (val << 1) | (rmask_data[pos/8] & (1 << (pos%8)) ? 1 : 0);
|
||||
}
|
||||
printf("%x", val);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < rmask_bits; i++)
|
||||
putchar((rmask_data[i / 8] & (1 << (i % 8))) != 0 ? '1' : '0');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if (done_initialization) {
|
||||
fx2usb_command("X");
|
||||
fx2usb_release(fx2usb);
|
||||
usb_close(fx2usb);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Total number of JTAG clock cycles performed: %d\n", tck_cycle_count);
|
||||
if (rc == 0)
|
||||
fprintf(stderr, "READY.\n");
|
||||
else
|
||||
fprintf(stderr, "TERMINATED WITH ERROR(s)! (see above)\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -0,0 +1,97 @@
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
USE_PREP_FIRMWARE = 1
|
||||
USE_PREP_HARDWARE = 1
|
||||
|
||||
LIBXSVFDIR=..
|
||||
|
||||
CC = gcc
|
||||
CFLAGS = -Wall -Wextra -Werror -Os -ggdb -I$(LIBXSVFDIR) -MD
|
||||
LDFLAGS = -L$(LIBXSVFDIR)
|
||||
LDLIBS = -lusb -lreadline -lxsvf
|
||||
|
||||
SDCC = sdcc
|
||||
SDCFLAGS = -mmcs51 --xram-loc 0x2000
|
||||
|
||||
all: xsvftool-xpcu
|
||||
|
||||
xsvftool-xpcu: filedata.h hardware_cksum_c.inc $(LIBXSVFDIR)/libxsvf.a xsvftool-xpcu.o fx2usb-interface.o
|
||||
$(CC) $(LDFLAGS) xsvftool-xpcu.o fx2usb-interface.o $(LDLIBS) -o $@
|
||||
|
||||
hardware.svf erasecpld.svf: hardware.sh hardware.ucf hardware.v hardware_cksum_vl.inc
|
||||
ifeq ($(USE_PREP_HARDWARE),1)
|
||||
cp prep_hardware.svf hardware.svf
|
||||
cp prep_erasecpld.svf erasecpld.svf
|
||||
else
|
||||
bash hardware.sh
|
||||
endif
|
||||
|
||||
firmware.ihx: firmware.c
|
||||
ifeq ($(USE_PREP_FIRMWARE),1)
|
||||
cp prep_firmware.ihx firmware.ihx
|
||||
else
|
||||
cpp -MD -MF $(basename $<).d -MT $(basename $<).ihx -o /dev/null $<
|
||||
$(SDCC) $(SDCFLAGS) $<
|
||||
endif
|
||||
|
||||
firmware.ihx: gpifprog_fixed.c
|
||||
gpifprog_fixed.c: gpifprog.c
|
||||
sed 's/ xdata / /g;' < $< > $@
|
||||
|
||||
$(LIBXSVFDIR)/libxsvf.a:
|
||||
$(MAKE) -C $(LIBXSVFDIR) libxsvf.a
|
||||
|
||||
hardware_cksum_vl.inc hardware_cksum_c.inc: hardware.sh hardware.ucf hardware.v
|
||||
echo "'h$$(cat $^ | md5sum | cut -c1-6 | tr a-z A-Z)" > hardware_cksum_vl.inc
|
||||
echo "\"$$(cat $^ | md5sum | cut -c1-6 | tr a-z A-Z)\"" > hardware_cksum_c.inc
|
||||
|
||||
filedata.h: hardware.svf erasecpld.svf firmware.ihx
|
||||
{ echo "unsigned char hardware_svf[] = { " && perl -pe 's/(.)/ord($$1).","/sge' hardware.svf && echo "};" && \
|
||||
echo "unsigned char erasecpld_svf[] = { " && perl -pe 's/(.)/ord($$1).","/sge' erasecpld.svf && echo "};" && \
|
||||
echo "unsigned char firmware_ihx[] = { " && perl -pe 's/(.)/ord($$1).","/sge' firmware.ihx && echo "};"; } | \
|
||||
perl -pe 's/(.{70}.*?,)/$$1\n/g' > filedata.h_new
|
||||
mv filedata.h_new filedata.h
|
||||
|
||||
prep:
|
||||
make clean
|
||||
sed -i '/^USE_PREP_/ s/1/0/;' Makefile
|
||||
make hardware.svf firmware.ihx
|
||||
cp hardware.svf prep_hardware.svf
|
||||
cp erasecpld.svf prep_erasecpld.svf
|
||||
cp firmware.ihx prep_firmware.ihx
|
||||
sed -i '/^USE_PREP_/ s/0/1/;' Makefile
|
||||
make clean
|
||||
|
||||
clean:
|
||||
rm -f firmware.asm firmware.lnk firmware.lst firmware.map
|
||||
rm -f firmware.mem firmware.rel firmware.rst firmware.sym
|
||||
rm -f hardware.bld hardware_build.xml hardware.chk hardware.cmd
|
||||
rm -f hardware.log hardware.lso hardware.mfd hardware.ngc hardware.ngd
|
||||
rm -f hardware_ngdbuild.xrpt hardware.ngr hardware.pad hardware_pad.csv
|
||||
rm -f hardware.pnx hardware.prj hardware.rpt hardware.svf hardware.syr
|
||||
rm -f hardware.vm6 hardware.xml hardware.xst hardware_xst.xrpt
|
||||
rm -f hardware.cxt hardware.gyd hardware.jed _impactbatch.log tmperr.err
|
||||
rm -f hardware_cksum_vl.inc hardware_cksum_c.inc gpifprog_fixed.c
|
||||
rm -rf hardware_html xilinx xlnx_auto_0_xdb _xmsgs
|
||||
rm -f filedata.h firmware.ihx erasecpld.cmd erasecpld.svf
|
||||
rm -f xsvftool-xpcu core *.o *.d
|
||||
|
||||
-include *.d
|
||||
|
@ -0,0 +1,173 @@
|
||||
|
||||
xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
==================================================================
|
||||
|
||||
This program can be used to play SVF and XSVF files on the "Xilinx
|
||||
Platform Cable USB" family of JTAG probes.
|
||||
|
||||
It is based on the libxsvf library:
|
||||
http://www.clifford.at/libxsvf/
|
||||
|
||||
This tool replaces the original CPLD firmware from Xilinx when run
|
||||
on one of the probes. See the notes below on how to restore the Xilinx
|
||||
firmware on the CPLD.
|
||||
|
||||
The file 'firmware.c' also contains a brief description of the pin mappings
|
||||
between the the Cypress CY7C68013A-100AIX and the Xilinx XC2C256-7VQ100
|
||||
on the probe as used by this software, as well as a brief description of
|
||||
the USB protocol this software is using.
|
||||
|
||||
With this software it is possible to use JTAG clock speeds up to 24 MHz.
|
||||
But with the high frequencies there are "gaps" in the transmission resulting
|
||||
in an effective transfer rate of approx 6 MBit/s.
|
||||
|
||||
This tool contains firmware for the CY7C68013A-100AIX (firmware.c) and for the
|
||||
XC2C256-7VQ100 (hardware.v) on the probe. Some more exotic tools are needed to
|
||||
build these. So pre-compiled versions of this firmware images are distributed
|
||||
along with the xsvftool-xpcu source code. You need to set the USE_PREP_* config
|
||||
options in the Makefile to '0' if you prefer building the firmware yourself.
|
||||
|
||||
|
||||
xsvftool-xpcu vs. Xilinx USB cable driver
|
||||
-----------------------------------------
|
||||
|
||||
When installed, the Xilinx "USB cable driver" tries to load its own FX2 firmware
|
||||
to the probes as soon as the probe is connected to the system. Once the Xilinx
|
||||
firmware is loaded into the probe the probe can't be accessed using xsvftool-xpcu.
|
||||
|
||||
So in order to use xsvftool-xpcu with a probe you need to uninstall or disable
|
||||
the Xilinx driver. This can usually be done by commenting out the udev rules in
|
||||
the /etc/udev/rules.d/xusbdfwu.rules file.
|
||||
|
||||
A probe that shows up as 03fd:0008 in the lsusb output is running the Xilinx
|
||||
firmware. You won't be able to access this probe with xsvftool-xpcu unless you
|
||||
deactivate the Xilinx driver as explained above, disconnect the probe from the
|
||||
PC and reconnect it.
|
||||
|
||||
You can always load the Xilinx FX2 firmware in the probe manually without using
|
||||
the udev rules (see "fxload" examples below).
|
||||
|
||||
|
||||
Supported and unsupported hardware
|
||||
----------------------------------
|
||||
|
||||
This software has been tested using the following probes:
|
||||
|
||||
- A Xilinx Platform Cable USB
|
||||
- The on-board probe of a Spartan-6 development board
|
||||
- A self-built clone of the Xilinx Platform Cable USB
|
||||
|
||||
Per default the software recognizes the following USB vendor IDs and device IDs
|
||||
(VID:PID) as a supported probe:
|
||||
|
||||
03fd:0009 Xilinx Platform Cable USB
|
||||
03fd:000d Xilinx Platform Cable USB (embedded)
|
||||
03fd:000f Xilinx Platform Cable USB (low power)
|
||||
04b4:8613 Cypress FX2 without configuration PROM
|
||||
|
||||
Currently there is no support for the "Xilinx Platform Cable USB II" in this
|
||||
software.
|
||||
|
||||
|
||||
Notes on device permissions
|
||||
---------------------------
|
||||
|
||||
To run xsvftool-xpcu as unprivileged user you need to set the permissions on
|
||||
the USB device accordingly. E.g.:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 002 Device 021: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ sudo chmod 0666 /dev/bus/usb/002/021
|
||||
|
||||
$ ./xsvftool-xpcu -Pc
|
||||
Scanning JTAG chain..
|
||||
idcode=0x16d4a093, revision=0x1, part=0x6d4a, manufactor=0x049
|
||||
Total number of JTAG clock cycles performed: 79
|
||||
READY.
|
||||
|
||||
Instead of doing this manually each time the device is connected one might
|
||||
prefer to create a udev rule that does set the permissions automatically:
|
||||
|
||||
$ sudo vi /etc/udev/rules.d/xsvftool-xpcu.rules
|
||||
# Allow everyone access to the Xilinx Platform Cable USB (see 'man 7 udev' for details)
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0008", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="0009", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000d", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="03fd", ATTR{idProduct}=="000f", MODE:="0666"
|
||||
ACTION=="add", SUBSYSTEM=="usb", ATTR{idVendor}=="04b4", ATTR{idProduct}=="8613", MODE:="0666"
|
||||
|
||||
NOTE: The line for 03fd:0008 is for the re-enumerated device when the original
|
||||
Xilinx firmware is used on the probe. It is not used nor needed when using
|
||||
xsvftool-xpcu exclusively, but isn't harmful either.
|
||||
|
||||
|
||||
Restore Xilinx CPLD Firmware with "xsvftool-xpcu"
|
||||
-------------------------------------------------
|
||||
|
||||
The Xilinx ISE comes with XSVF files for programming the CPLD with the Xilinx
|
||||
firmware. You can simply use "xsvftool-xpcu" to program the CPLD to the original
|
||||
firmware:
|
||||
|
||||
$ ./xsvftool-xpcu -P -x /opt/Xilinx/13.1/ISE_DS/ISE/data/xusb_emb.fmwr
|
||||
|
||||
After that you need to disconnect and reconnect the probe before you can load
|
||||
the Xilinx FX2 firmware and use the probe with impact:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 001 Device 106: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ fxload -t fx2 -D /dev/bus/usb/001/106 -I /opt/Xilinx/13.1/ISE_DS/ISE/bin/lin/xusb_emb.hex
|
||||
|
||||
### usually you need to wait a few seconds here for the device to re-enumerate and settle ###
|
||||
$ lsusb -d 03fd:0008
|
||||
Bus 001 Device 108: ID 03fd:0008 Xilinx, Inc.
|
||||
|
||||
### just scan the JTAG chain to test the probe ###
|
||||
$ /opt/Xilinx/13.1/ISE_DS/ISE/bin/lin/impact -batch /dev/null
|
||||
> setMode -bs
|
||||
> setCable -port usb21
|
||||
> identify
|
||||
> quit
|
||||
|
||||
NOTE: Use the *.hex file from the "ISE/bin/lin/" directory! It is different
|
||||
from the one in the "ISE/data/" directory and only this one seams to work.
|
||||
|
||||
|
||||
Restore Xilinx CPLD Firmware with "impact"
|
||||
------------------------------------------
|
||||
|
||||
Up to ISE 11 the Xilinx "impact" program did automatically reprogram the CPLD on
|
||||
the probe whenever needed. Since ISE 12 this does only work when there is already
|
||||
an (older) Xilinx firmware on the probe. So in order to reprogram the CPLD on
|
||||
the probe with "impact" you need ISE 11 installed. Then it is possible to
|
||||
reprogram the CPLD just by loading the fx2 firmware and running impact on the
|
||||
probe:
|
||||
|
||||
$ lsusb -d 04b4:8613
|
||||
Bus 002 Device 021: ID 04b4:8613 Cypress Semiconductor Corp. CY7C68013 EZ-USB FX2 USB 2.0 Development Kit
|
||||
|
||||
$ fxload -t fx2 -D /dev/bus/usb/002/021 -I /opt/Xilinx/11.3/ISE/bin/lin/xusb_emb.hex
|
||||
|
||||
### usually you need to wait a few seconds here for the device to re-enumerate and settle ###
|
||||
$ lsusb -d 03fd:0008
|
||||
Bus 002 Device 022: ID 03fd:0008 Xilinx, Inc.
|
||||
|
||||
$ vi impatch_batch.cmd
|
||||
setMode -bs
|
||||
setCable -port usb21
|
||||
quit
|
||||
|
||||
### this automatically reprograms the CPLD without doing anything else with the probe ###
|
||||
$ /opt/Xilinx/11.3/ISE/bin/lin/impact -batch impatch_batch.cmd
|
||||
|
||||
The "reset-probe.sh" shell script in this directory (libxsvf/xsvftool-xpcu.src/)
|
||||
does this automatically:
|
||||
|
||||
$ bash reset-probe-impact.sh
|
||||
|
||||
WARNING: For some reason this procedure fails when the probe has been used with
|
||||
xsvftool-xpcu between being connected to USB and loading xusb_emb.hex into the
|
||||
FX2. So disconnect and reconnect the probe before running the reset-probe.sh
|
||||
script!
|
||||
|
@ -0,0 +1,782 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
/*
|
||||
* Command Reference (EP1)
|
||||
* -----------------------
|
||||
*
|
||||
* Request: T<nn>
|
||||
* Response: OK (T<nn>)
|
||||
* Configure timing for EP2/JTAG transfers
|
||||
*
|
||||
* Request: R
|
||||
* Response: OK (R)
|
||||
* Perform internal and CPLD reset
|
||||
*
|
||||
* Request: W<n>
|
||||
* Response: OK (W<n>)
|
||||
* Wait for the CPLD sync signal to become <n>
|
||||
*
|
||||
* Request: C
|
||||
* Response: <nnnnnn> (C)
|
||||
* Read out the CPLD verilog checksum
|
||||
*
|
||||
* Request: B<n>
|
||||
* Response: OK (B<n>)
|
||||
* Set BUFFER_OE to <n>
|
||||
*
|
||||
* Request: I<n>
|
||||
* Response: OK (I<n>)
|
||||
* Set INIT_INT to <n>
|
||||
*
|
||||
* Request: S
|
||||
* Response: <n><m><k><p><x><y><s> (S)
|
||||
* Read and reset status bits
|
||||
* (<n> = FX2-JTAG-ERR, <m> = CPLD-JTAG-ERR, <k> = INIT_B_INT,
|
||||
* <p> = SLOE_INT, <x> = FX2-JTAG-TDO, <y> = CPLD-JTAG-TDO, <s> = SYNC)
|
||||
*
|
||||
* Request: P
|
||||
* Response: <n><m><k><p><x><y><s> (P)
|
||||
* Peek status bits without resetting them
|
||||
*
|
||||
* Request: J<bindata>
|
||||
* Response: -- NONE --
|
||||
* Execute JTAG transaction (4bit/cycle)
|
||||
*
|
||||
* Request: X
|
||||
* Response: OK (X)
|
||||
* Exit. Restore FX2 default settings and enter endless loop
|
||||
*
|
||||
*
|
||||
* Target JTAG Programming (EP2)
|
||||
* -----------------------------
|
||||
*
|
||||
* Raw JTAG transaction codes.
|
||||
* (4bit/cycle when T=0, 8bit/cycle otherwise)
|
||||
*
|
||||
*
|
||||
* JTAG Transaction codes
|
||||
* ----------------------
|
||||
*
|
||||
* 0000:
|
||||
* NOP
|
||||
*
|
||||
* 0001 xxxx:
|
||||
* Set sync signal to 'xxxx' (engine on CPLD only)
|
||||
*
|
||||
* 001x:
|
||||
* reserved for future use
|
||||
*
|
||||
* 01xy:
|
||||
* JTAG transaction without TDO check. TMS=x, TDI=y
|
||||
*
|
||||
* 1zxy:
|
||||
* JTAG transaction with TDO check. TDO=z, TMS=x, TDI=y
|
||||
*
|
||||
*
|
||||
* FX2 <-> CPLD Interface
|
||||
* ----------------------
|
||||
*
|
||||
* FD[7:0] ---> FD[7:0]
|
||||
* CTL0 ---> STROBE_FD (neg)
|
||||
* CTL1 ---> STROBE_SHIFT (neg)
|
||||
* CTL2 ---> STROBE_PUSH (neg)
|
||||
*
|
||||
* PC[7:4] <--- SYNC
|
||||
* PC3 <--- TDO
|
||||
* PC2 <--- CKSUM
|
||||
* PC1 <--- INIT_B_INT
|
||||
* PC0 <--- ERR
|
||||
*
|
||||
* PD4 ---> RESET_SYNC
|
||||
* PD3 ---> RESET_ERR
|
||||
* PD2 ---> INIT_INT
|
||||
* PD1 ---> SHIFT_CKSUM
|
||||
* PD0 ---> RESET_CKSUM
|
||||
*
|
||||
*
|
||||
* Other FX2 Connections
|
||||
* ---------------------
|
||||
*
|
||||
* PA0 ---> LED_GREEN
|
||||
* PA1 ---> LED_RED
|
||||
* PA2 <--- SLOE_INT
|
||||
* PA3 ---> CPLD_PWR
|
||||
* PA5 ---> BUFFER_OE
|
||||
*
|
||||
* IOE[3] ---> CPLD TCK
|
||||
* IOE[4] ---> CPLD TMS
|
||||
* IOE[5] <--- CPLD TDO
|
||||
* IOE[6] ---> CPLD TDI
|
||||
*
|
||||
*/
|
||||
|
||||
// #include "fx2.h"
|
||||
// #include "fx2regs.h"
|
||||
// #include "fx2sdly.h"
|
||||
#include "gpifprog_fixed.c"
|
||||
|
||||
// set to '1' on CPLD JTAG error
|
||||
BYTE state_err;
|
||||
|
||||
// use quad buffering and larger buffers
|
||||
#define ALL_RESOURCES_ON_EP2
|
||||
|
||||
void sleep3us(void)
|
||||
{
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
}
|
||||
|
||||
void msleep(WORD ms)
|
||||
{
|
||||
WORD i;
|
||||
while (ms-- > 0) {
|
||||
for (i = 0; i < 1000; i += 3)
|
||||
sleep3us();
|
||||
}
|
||||
}
|
||||
|
||||
void setup(void)
|
||||
{
|
||||
BYTE i;
|
||||
|
||||
/* CPU: 48MHz, don't drive CLKOUT */
|
||||
CPUCS = 0x10;
|
||||
|
||||
#ifdef ALL_RESOURCES_ON_EP2
|
||||
/* Configure the Endpoints (EP2 => 4x 1kB) */
|
||||
EP2CFG = 0xA8; // VALID=1, DIR=0, TYPE=10, SIZE=1, BUF=00
|
||||
EP4CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
EP6CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
EP8CFG = 0x00; // VALID=0, DIR=0, TYPE=00, SIZE=0, BUF=00
|
||||
#else
|
||||
/* Configure the Endpoints (default config) */
|
||||
EP2CFG = 0xA2; // VALID=1, DIR=0, TYPE=10, SIZE=0, BUF=10
|
||||
EP4CFG = 0xA0; // VALID=1, DIR=0, TYPE=10, SIZE=0, BUF=00
|
||||
EP6CFG = 0xA2; // VALID=1, DIR=1, TYPE=10, SIZE=0, BUF=10
|
||||
EP8CFG = 0xA0; // VALID=1, DIR=1, TYPE=10, SIZE=0, BUF=00
|
||||
#endif
|
||||
|
||||
/* USB FIFO */
|
||||
FIFORESET = 0x80;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 2;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 4;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 6;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 8;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 0;
|
||||
SYNCDELAY;
|
||||
|
||||
/* Set WORDWIDE=0 for all FIFOs */
|
||||
EP2FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP4FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP6FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
EP8FIFOCFG &= ~bmWORDWIDE;
|
||||
SYNCDELAY;
|
||||
|
||||
/* Initialize GPIF Subsystem */
|
||||
GpifInit();
|
||||
|
||||
/* Misc signals on port A */
|
||||
PORTACFG = 0;
|
||||
OEA = bmBIT0 | bmBIT1 | bmBIT3 | bmBIT5;
|
||||
IOA = 0;
|
||||
|
||||
/* FX2 <-> CPLD signals on port C */
|
||||
PORTCCFG = 0;
|
||||
OEC = 0;
|
||||
IOC = 0;
|
||||
|
||||
/* FX2 <-> CPLD signals on port D */
|
||||
OED = bmBIT0 | bmBIT1 | bmBIT2 | bmBIT3 | bmBIT4;
|
||||
IOD = 0;
|
||||
|
||||
/* TURN ON CPLD VCC */
|
||||
PA3 = 1;
|
||||
msleep(100);
|
||||
|
||||
/* XC2S256 JTAG on port E */
|
||||
OEE = bmBIT3|bmBIT4|bmBIT6;
|
||||
IOE = bmBIT3|bmBIT4|bmBIT6;
|
||||
|
||||
/* Set TAP to logic reset state */
|
||||
for (i=0; i<16; i++) {
|
||||
// TMS is high - just generate a few TCK pulses
|
||||
sleep3us();
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
}
|
||||
|
||||
/* All set up: Let the host find out about the new EP config */
|
||||
#if 0
|
||||
USBCS |= bmDISCON;
|
||||
msleep(10);
|
||||
USBCS &= ~bmDISCON;
|
||||
#endif
|
||||
}
|
||||
|
||||
void unsetup(void)
|
||||
{
|
||||
WORD i, j;
|
||||
|
||||
/* 1st TURN OFF CPLD VCC */
|
||||
PA3 = 0;
|
||||
msleep(100);
|
||||
|
||||
/*
|
||||
* Restore default configuration as good as possible
|
||||
*
|
||||
* The idea is that one could load the xilinx firmware without
|
||||
* the need to reconnect. Unfortunately it doesn't work. Something
|
||||
* important is still different between the FX2 after reset and
|
||||
* after running this unsetup() function.
|
||||
*/
|
||||
|
||||
GPIFABORT = 0xFF;
|
||||
SYNCDELAY;
|
||||
|
||||
CPUCS = 0x02;
|
||||
SYNCDELAY;
|
||||
IFCONFIG = 0x80;
|
||||
SYNCDELAY;
|
||||
|
||||
EP2CFG = 0xA2;
|
||||
SYNCDELAY;
|
||||
EP4CFG = 0xA0;
|
||||
SYNCDELAY;
|
||||
EP6CFG = 0xA2;
|
||||
SYNCDELAY;
|
||||
EP8CFG = 0xA0;
|
||||
SYNCDELAY;
|
||||
|
||||
EP2FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP4FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP6FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
EP8FIFOCFG = 0x05;
|
||||
SYNCDELAY;
|
||||
|
||||
FIFORESET = 0x80;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 2;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 4;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 6;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 8;
|
||||
SYNCDELAY;
|
||||
FIFORESET = 0;
|
||||
SYNCDELAY;
|
||||
|
||||
IOA = 0;
|
||||
IOC = 0;
|
||||
IOD = 0;
|
||||
IOE = 0;
|
||||
|
||||
OEA = 0;
|
||||
OEC = 0;
|
||||
OED = 0;
|
||||
OEE = 0;
|
||||
|
||||
PORTACFG = 0;
|
||||
PORTCCFG = 0;
|
||||
|
||||
OEA = 1;
|
||||
for (i=0; i<3; i++) {
|
||||
PA0 = 1;
|
||||
for (j=0; j<3000; j++) sleep3us();
|
||||
PA1 = 0;
|
||||
for (j=0; j<3000; j++) sleep3us();
|
||||
}
|
||||
OEA = 0;
|
||||
|
||||
// just ack everything and wait
|
||||
while (1) {
|
||||
if((EP1OUTCS & bmBIT1) == 0) {
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
}
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
BYTE nibble2hex(BYTE v)
|
||||
{
|
||||
return "0123456789ABCDEF"[v&0x0f];
|
||||
}
|
||||
|
||||
BYTE hex2nibble(BYTE v)
|
||||
{
|
||||
if (v >= '0' && v <= '9')
|
||||
return v - '0';
|
||||
if (v >= 'a' && v <= 'f')
|
||||
return 0x0A + v - 'a';
|
||||
if (v >= 'A' && v <= 'F')
|
||||
return 0x0A + v - 'A';
|
||||
return 0;
|
||||
}
|
||||
|
||||
xdata at (0xE400 + 64) volatile BYTE GPIF_WAVE2_LEN0;
|
||||
xdata at (0xE400 + 66) volatile BYTE GPIF_WAVE2_LEN2;
|
||||
|
||||
void proc_command_t(BYTE t)
|
||||
{
|
||||
if (t == 0) {
|
||||
GPIFWFSELECT = 0x4E; SYNCDELAY;
|
||||
} else {
|
||||
GPIFWFSELECT = 0x4A; SYNCDELAY;
|
||||
GPIF_WAVE2_LEN0 = t; SYNCDELAY;
|
||||
GPIF_WAVE2_LEN2 = t; SYNCDELAY;
|
||||
}
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[5] = nibble2hex((t >> 4) & 0x0f); SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex((t >> 0) & 0x0f); SYNCDELAY;
|
||||
EP1INBUF[7] = ')'; SYNCDELAY;
|
||||
EP1INBC = 8; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_r(void)
|
||||
{
|
||||
BYTE i, *p = "OK (R)";
|
||||
|
||||
/* Reset TAP to logic reset state */
|
||||
IOE = bmBIT3|bmBIT4|bmBIT6;
|
||||
for (i=0; i<16; i++) {
|
||||
// TMS is high - just generate a few TCK pulses
|
||||
sleep3us();
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
}
|
||||
|
||||
/* Reset speed to max. */
|
||||
GPIFWFSELECT = 0x4E; SYNCDELAY;
|
||||
|
||||
/* Reset JTAG error state */
|
||||
state_err = 0;
|
||||
|
||||
/* Reset LEDs and BUFFER_OE */
|
||||
PA0 = PA1 = PA5 = 0;
|
||||
|
||||
/* Assert CPLD reset pins */
|
||||
IOD = bmBIT0 | bmBIT3 | bmBIT4;
|
||||
SYNCDELAY;
|
||||
IOD |= bmBIT1;
|
||||
SYNCDELAY;
|
||||
IOD = 0;
|
||||
|
||||
/* Send response */
|
||||
for (i = 0; p[i]; i++) {
|
||||
EP1INBUF[i] = p[i]; SYNCDELAY;
|
||||
}
|
||||
EP1INBC = i; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_bulkdata(void);
|
||||
|
||||
void proc_command_w_ok(BYTE v)
|
||||
{
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'W'; SYNCDELAY;
|
||||
EP1INBUF[5] = nibble2hex(v); SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_w_timeout(BYTE v)
|
||||
{
|
||||
EP1INBUF[0] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'I'; SYNCDELAY;
|
||||
EP1INBUF[2] = 'M'; SYNCDELAY;
|
||||
EP1INBUF[3] = 'E'; SYNCDELAY;
|
||||
EP1INBUF[4] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[5] = 'U'; SYNCDELAY;
|
||||
EP1INBUF[6] = 'T'; SYNCDELAY;
|
||||
EP1INBUF[7] = '!'; SYNCDELAY;
|
||||
EP1INBUF[8] = ' '; SYNCDELAY;
|
||||
EP1INBUF[9] = 'S'; SYNCDELAY;
|
||||
EP1INBUF[10] = '='; SYNCDELAY;
|
||||
EP1INBUF[11] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[12] = ' '; SYNCDELAY;
|
||||
EP1INBUF[13] = '('; SYNCDELAY;
|
||||
EP1INBUF[14] = 'W'; SYNCDELAY;
|
||||
EP1INBUF[15] = nibble2hex(v); SYNCDELAY;
|
||||
EP1INBUF[16] = ')'; SYNCDELAY;
|
||||
EP1INBC = 17; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_w(BYTE v)
|
||||
{
|
||||
WORD i, j;
|
||||
|
||||
for (i = 0; i < 1000; i++)
|
||||
for (j = 0; j < 1000; j++)
|
||||
{
|
||||
/* check for wait condition */
|
||||
if ((IOC >> 4) == v) {
|
||||
proc_command_w_ok(v);
|
||||
return;
|
||||
}
|
||||
|
||||
/* check for data on EP2 */
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
PA0 = 1;
|
||||
proc_bulkdata();
|
||||
PA0 = 0;
|
||||
}
|
||||
}
|
||||
|
||||
proc_command_w_timeout(v);
|
||||
}
|
||||
|
||||
void proc_command_c(void)
|
||||
{
|
||||
BYTE i, j, buf;
|
||||
|
||||
/* Reset chksum register */
|
||||
PD0 = 1;
|
||||
PD1 = 0;
|
||||
SYNCDELAY;
|
||||
PD1 = 1;
|
||||
SYNCDELAY;
|
||||
PD0 = 0;
|
||||
PD1 = 0;
|
||||
|
||||
for (i = 0; i < 6; i++) {
|
||||
buf = 0;
|
||||
for (j = 0; j < 4; j++) {
|
||||
buf = buf << 1 | PC2;
|
||||
SYNCDELAY;
|
||||
PD1 = 1;
|
||||
SYNCDELAY;
|
||||
PD1 = 0;
|
||||
}
|
||||
EP1INBUF[i] = nibble2hex(buf); SYNCDELAY;
|
||||
}
|
||||
|
||||
EP1INBUF[6] = ' '; SYNCDELAY;
|
||||
EP1INBUF[7] = '('; SYNCDELAY;
|
||||
EP1INBUF[8] = 'C'; SYNCDELAY;
|
||||
EP1INBUF[9] = ')'; SYNCDELAY;
|
||||
EP1INBC = 10; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_b(BYTE v)
|
||||
{
|
||||
PA5 = v;
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'B'; SYNCDELAY;
|
||||
EP1INBUF[5] = v ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_i(BYTE v)
|
||||
{
|
||||
PD2 = v;
|
||||
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'I'; SYNCDELAY;
|
||||
EP1INBUF[5] = v ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = ')'; SYNCDELAY;
|
||||
EP1INBC = 7; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_command_s(void)
|
||||
{
|
||||
EP1INBUF[0] = PC0 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[1] = state_err ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[2] = PC1 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[3] = PA2 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[4] = PC3 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[5] = (IOE & bmBIT5) ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[7] = ' '; SYNCDELAY;
|
||||
EP1INBUF[8] = '('; SYNCDELAY;
|
||||
EP1INBUF[9] = 'S'; SYNCDELAY;
|
||||
EP1INBUF[10] = ')'; SYNCDELAY;
|
||||
EP1INBC = 11; SYNCDELAY;
|
||||
|
||||
// reset error state
|
||||
state_err = 0;
|
||||
IOD = bmBIT3;
|
||||
SYNCDELAY;
|
||||
SYNCDELAY;
|
||||
IOD &= ~bmBIT3;
|
||||
}
|
||||
|
||||
void proc_command_p(void)
|
||||
{
|
||||
EP1INBUF[0] = PC0 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[1] = state_err ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[2] = PC1 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[3] = PA2 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[4] = PC3 ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[5] = (IOE & bmBIT5) ? '1' : '0'; SYNCDELAY;
|
||||
EP1INBUF[6] = nibble2hex(IOC >> 4); SYNCDELAY;
|
||||
EP1INBUF[7] = ' '; SYNCDELAY;
|
||||
EP1INBUF[8] = '('; SYNCDELAY;
|
||||
EP1INBUF[9] = 'P'; SYNCDELAY;
|
||||
EP1INBUF[10] = ')'; SYNCDELAY;
|
||||
EP1INBC = 11; SYNCDELAY;
|
||||
}
|
||||
|
||||
BYTE proc_command_j_exec_skip_next;
|
||||
void proc_command_j_exec(BYTE cmd)
|
||||
{
|
||||
if (proc_command_j_exec_skip_next) {
|
||||
proc_command_j_exec_skip_next = 0;
|
||||
return;
|
||||
}
|
||||
if (cmd == 0x00)
|
||||
return;
|
||||
if (cmd == 0x01) {
|
||||
// 0001 xxxx: Set sync signal to 'xxxx' (engine on CPLD only)
|
||||
proc_command_j_exec_skip_next = 1;
|
||||
return;
|
||||
}
|
||||
if ((cmd & 0x0c) == 0x04)
|
||||
{
|
||||
// 01xy: JTAG transaction without TDO check. TMS=x, TDI=y
|
||||
|
||||
/* set tms line */
|
||||
if (cmd & 0x02)
|
||||
IOE |= bmBIT4;
|
||||
else
|
||||
IOE &= ~bmBIT4;
|
||||
|
||||
/* set tdi line */
|
||||
if (cmd & 0x01)
|
||||
IOE |= bmBIT6;
|
||||
else
|
||||
IOE &= ~bmBIT6;
|
||||
|
||||
/* generate tck pulse */
|
||||
SYNCDELAY;
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
SYNCDELAY;
|
||||
|
||||
return;
|
||||
}
|
||||
if ((cmd & 0x08) == 0x08)
|
||||
{
|
||||
// 1zxy: JTAG transaction with TDO check. TDO=z, TMS=x, TDI=y
|
||||
|
||||
/* set tms line */
|
||||
if (cmd & 0x02)
|
||||
IOE |= bmBIT4;
|
||||
else
|
||||
IOE &= ~bmBIT4;
|
||||
|
||||
/* set tdi line */
|
||||
if (cmd & 0x01)
|
||||
IOE |= bmBIT6;
|
||||
else
|
||||
IOE &= ~bmBIT6;
|
||||
|
||||
/* generate tck pulse */
|
||||
SYNCDELAY;
|
||||
IOE &= ~bmBIT3;
|
||||
sleep3us();
|
||||
IOE |= bmBIT3;
|
||||
SYNCDELAY;
|
||||
|
||||
/* perform tdo check */
|
||||
if (((cmd & 0x04) == 0) != ((IOE & bmBIT5) == 0))
|
||||
state_err = 1;
|
||||
|
||||
return;
|
||||
}
|
||||
}
|
||||
|
||||
void proc_command_j(BYTE len)
|
||||
{
|
||||
BYTE i;
|
||||
proc_command_j_exec_skip_next = 0;
|
||||
for (i = 1; i < len; i++) {
|
||||
BYTE cmd = EP1OUTBUF[i];
|
||||
proc_command_j_exec(cmd & 0x0f);
|
||||
proc_command_j_exec(cmd >> 4);
|
||||
}
|
||||
}
|
||||
|
||||
void proc_command_x(void)
|
||||
{
|
||||
EP1INBUF[0] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'K'; SYNCDELAY;
|
||||
EP1INBUF[2] = ' '; SYNCDELAY;
|
||||
EP1INBUF[3] = '('; SYNCDELAY;
|
||||
EP1INBUF[4] = 'X'; SYNCDELAY;
|
||||
EP1INBUF[5] = ')'; SYNCDELAY;
|
||||
EP1INBC = 6; SYNCDELAY;
|
||||
|
||||
/* accept new data on EP1OUT */
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
|
||||
unsetup();
|
||||
}
|
||||
|
||||
void proc_command(void)
|
||||
{
|
||||
BYTE len, cmd;
|
||||
|
||||
/* process command(s) */
|
||||
len = EP1OUTBC;
|
||||
cmd = EP1OUTBUF[0];
|
||||
|
||||
if (cmd == 'T' && len == 3)
|
||||
proc_command_t((hex2nibble(EP1OUTBUF[1]) << 4) | hex2nibble(EP1OUTBUF[2]));
|
||||
else if (cmd == 'R' && len == 1)
|
||||
proc_command_r();
|
||||
else if (cmd == 'W' && len == 2)
|
||||
proc_command_w(hex2nibble(EP1OUTBUF[1]));
|
||||
else if (cmd == 'C' && len == 1)
|
||||
proc_command_c();
|
||||
else if (cmd == 'B' && len == 2)
|
||||
proc_command_b(EP1OUTBUF[1] == '1');
|
||||
else if (cmd == 'I' && len == 2)
|
||||
proc_command_i(EP1OUTBUF[1] == '1');
|
||||
else if (cmd == 'S' && len == 1)
|
||||
proc_command_s();
|
||||
else if (cmd == 'P' && len == 1)
|
||||
proc_command_p();
|
||||
else if (cmd == 'J')
|
||||
proc_command_j(len);
|
||||
else if (cmd == 'X')
|
||||
proc_command_x();
|
||||
else
|
||||
{
|
||||
/* send error response */
|
||||
EP1INBUF[0] = 'E'; SYNCDELAY;
|
||||
EP1INBUF[1] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[2] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[3] = 'O'; SYNCDELAY;
|
||||
EP1INBUF[4] = 'R'; SYNCDELAY;
|
||||
EP1INBUF[5] = '!'; SYNCDELAY;
|
||||
EP1INBC = 6; SYNCDELAY;
|
||||
}
|
||||
|
||||
/* accept new data on EP1OUT */
|
||||
EP1OUTBC = 0xff; SYNCDELAY;
|
||||
}
|
||||
|
||||
void proc_bulkdata(void)
|
||||
{
|
||||
WORD len;
|
||||
|
||||
len = (EP2BCH << 8) | EP2BCL;
|
||||
if (len == 0)
|
||||
{
|
||||
/* ignore this and accept data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
#if 0
|
||||
else if (len == 1)
|
||||
{
|
||||
while ((GPIFTRIG & 0x80) == 0) { /* GPIF is busy */ }
|
||||
|
||||
/* transfer single byte */
|
||||
XGPIFSGLDATH = 0; SYNCDELAY;
|
||||
XGPIFSGLDATLX = EP2FIFOBUF[0]; SYNCDELAY;
|
||||
|
||||
/* accept new data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY;
|
||||
}
|
||||
#endif
|
||||
else
|
||||
{
|
||||
while ((GPIFTRIG & 0x80) == 0) { /* GPIF is busy */ }
|
||||
|
||||
/* pass pkt to GPIF master */
|
||||
EP2GPIFTCH = EP2BCH;
|
||||
EP2GPIFTCL = EP2BCL;
|
||||
EP2BCL = 0x00;
|
||||
EP2GPIFTRIG = 0xff;
|
||||
}
|
||||
}
|
||||
|
||||
void main(void)
|
||||
{
|
||||
state_err = 0;
|
||||
|
||||
setup();
|
||||
|
||||
/* accept data on EP2 */
|
||||
EP2BCL = 0xff; SYNCDELAY; // 1st buffer
|
||||
EP2BCL = 0xff; SYNCDELAY; // 2nd buffer
|
||||
#ifdef ALL_RESOURCES_ON_EP2
|
||||
EP2BCL = 0xff; SYNCDELAY; // 3rd buffer
|
||||
EP2BCL = 0xff; SYNCDELAY; // 4th buffer
|
||||
#endif
|
||||
|
||||
while (1)
|
||||
{
|
||||
/* check for data on EP1 */
|
||||
if((EP1OUTCS & bmBIT1) == 0) {
|
||||
PA1 = 1;
|
||||
proc_command();
|
||||
PA1 = 0;
|
||||
}
|
||||
|
||||
/* check for data on EP2 */
|
||||
if((EP2CS & bmBIT2) == 0) {
|
||||
PA0 = 1;
|
||||
proc_bulkdata();
|
||||
PA0 = 0;
|
||||
}
|
||||
}
|
||||
}
|
||||
|
@ -0,0 +1,332 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: FX2.h
|
||||
// Contents: EZ-USB FX2/FX2LP/FX1 constants, macros, datatypes, globals, and library
|
||||
// function prototypes.
|
||||
//
|
||||
// $Archive: /USB/Target/Inc/Fx2.h $
|
||||
// $Date: 3/23/05 2:30p $
|
||||
// $Revision: 16 $
|
||||
//
|
||||
// Copyright (c) 2005 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#ifndef FX2_H //Header sentry
|
||||
#define FX2_H
|
||||
|
||||
#define INTERNAL_DSCR_ADDR 0x0080 // Relocate Descriptors to 0x80
|
||||
#define bmSTRETCH 0x07
|
||||
#define FW_STRETCH_VALUE 0x0 // Set stretch to 0 in frameworks
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Constants
|
||||
//-----------------------------------------------------------------------------
|
||||
#define TRUE 1
|
||||
#define FALSE 0
|
||||
|
||||
#define bmBIT0 0x01
|
||||
#define bmBIT1 0x02
|
||||
#define bmBIT2 0x04
|
||||
#define bmBIT3 0x08
|
||||
#define bmBIT4 0x10
|
||||
#define bmBIT5 0x20
|
||||
#define bmBIT6 0x40
|
||||
#define bmBIT7 0x80
|
||||
|
||||
#define DEVICE_DSCR 0x01 // Descriptor type: Device
|
||||
#define CONFIG_DSCR 0x02 // Descriptor type: Configuration
|
||||
#define STRING_DSCR 0x03 // Descriptor type: String
|
||||
#define INTRFC_DSCR 0x04 // Descriptor type: Interface
|
||||
#define ENDPNT_DSCR 0x05 // Descriptor type: End Point
|
||||
#define DEVQUAL_DSCR 0x06 // Descriptor type: Device Qualifier
|
||||
#define OTHERSPEED_DSCR 0x07 // Descriptor type: Other Speed Configuration
|
||||
|
||||
#define bmBUSPWR bmBIT7 // Config. attribute: Bus powered
|
||||
#define bmSELFPWR bmBIT6 // Config. attribute: Self powered
|
||||
#define bmRWU bmBIT5 // Config. attribute: Remote Wakeup
|
||||
|
||||
#define bmEPOUT bmBIT7
|
||||
#define bmEPIN 0x00
|
||||
|
||||
#define EP_CONTROL 0x00 // End Point type: Control
|
||||
#define EP_ISO 0x01 // End Point type: Isochronous
|
||||
#define EP_BULK 0x02 // End Point type: Bulk
|
||||
#define EP_INT 0x03 // End Point type: Interrupt
|
||||
|
||||
#define SUD_SIZE 8 // Setup data packet size
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
//Added for HID
|
||||
|
||||
#define SETUP_MASK 0x60 //Used to mask off request type
|
||||
#define SETUP_STANDARD_REQUEST 0 //Standard Request
|
||||
#define SETUP_CLASS_REQUEST 0x20 //Class Request
|
||||
#define SETUP_VENDOR_REQUEST 0x40 //Vendor Request
|
||||
#define SETUP_RESERVED_REQUEST 0x60 //Reserved or illegal request
|
||||
|
||||
//////////////////////////////////////////////////////////////////////////////
|
||||
|
||||
|
||||
#define SC_GET_STATUS 0x00 // Setup command: Get Status
|
||||
#define SC_CLEAR_FEATURE 0x01 // Setup command: Clear Feature
|
||||
#define SC_RESERVED 0x02 // Setup command: Reserved
|
||||
#define SC_SET_FEATURE 0x03 // Setup command: Set Feature
|
||||
#define SC_SET_ADDRESS 0x05 // Setup command: Set Address
|
||||
#define SC_GET_DESCRIPTOR 0x06 // Setup command: Get Descriptor
|
||||
#define SC_SET_DESCRIPTOR 0x07 // Setup command: Set Descriptor
|
||||
#define SC_GET_CONFIGURATION 0x08 // Setup command: Get Configuration
|
||||
#define SC_SET_CONFIGURATION 0x09 // Setup command: Set Configuration
|
||||
#define SC_GET_INTERFACE 0x0a // Setup command: Get Interface
|
||||
#define SC_SET_INTERFACE 0x0b // Setup command: Set Interface
|
||||
#define SC_SYNC_FRAME 0x0c // Setup command: Sync Frame
|
||||
#define SC_ANCHOR_LOAD 0xa0 // Setup command: Anchor load
|
||||
|
||||
#define GD_DEVICE 0x01 // Get descriptor: Device
|
||||
#define GD_CONFIGURATION 0x02 // Get descriptor: Configuration
|
||||
#define GD_STRING 0x03 // Get descriptor: String
|
||||
#define GD_INTERFACE 0x04 // Get descriptor: Interface
|
||||
#define GD_ENDPOINT 0x05 // Get descriptor: Endpoint
|
||||
#define GD_DEVICE_QUALIFIER 0x06 // Get descriptor: Device Qualifier
|
||||
#define GD_OTHER_SPEED_CONFIGURATION 0x07 // Get descriptor: Other Configuration
|
||||
#define GD_INTERFACE_POWER 0x08 // Get descriptor: Interface Power
|
||||
#define GD_HID 0x21 // Get descriptor: HID
|
||||
#define GD_REPORT 0x22 // Get descriptor: Report
|
||||
|
||||
#define GS_DEVICE 0x80 // Get Status: Device
|
||||
#define GS_INTERFACE 0x81 // Get Status: Interface
|
||||
#define GS_ENDPOINT 0x82 // Get Status: End Point
|
||||
|
||||
#define FT_DEVICE 0x00 // Feature: Device
|
||||
#define FT_ENDPOINT 0x02 // Feature: End Point
|
||||
|
||||
#define I2C_IDLE 0 // I2C Status: Idle mode
|
||||
#define I2C_SENDING 1 // I2C Status: I2C is sending data
|
||||
#define I2C_RECEIVING 2 // I2C Status: I2C is receiving data
|
||||
#define I2C_PRIME 3 // I2C Status: I2C is receiving the first byte of a string
|
||||
#define I2C_STOP 5 // I2C Status: I2C waiting for stop completion
|
||||
#define I2C_BERROR 6 // I2C Status: I2C error; Bit Error
|
||||
#define I2C_NACK 7 // I2C Status: I2C error; No Acknowledge
|
||||
#define I2C_OK 8 // I2C positive return code
|
||||
#define I2C_WAITSTOP 9 // I2C Status: Wait for STOP complete
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Macros
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
#define MSB(word) (BYTE)(((WORD)(word) >> 8) & 0xff)
|
||||
#define LSB(word) (BYTE)((WORD)(word) & 0xff)
|
||||
|
||||
#define SWAP_ENDIAN(word) ((BYTE*)&word)[0] ^= ((BYTE*)&word)[1];\
|
||||
((BYTE*)&word)[1] ^= ((BYTE*)&word)[0];\
|
||||
((BYTE*)&word)[0] ^= ((BYTE*)&word)[1]
|
||||
|
||||
#define EZUSB_IRQ_ENABLE() EUSB = 1
|
||||
#define EZUSB_IRQ_DISABLE() EUSB = 0
|
||||
#define EZUSB_IRQ_CLEAR() EXIF &= ~0x10 // IE2_
|
||||
|
||||
#define EZUSB_STALL_EP0() EP0CS |= bmEPSTALL
|
||||
|
||||
// WRITEDELAY() has been replaced by SYNCDELAY; macro in fx2sdly.h
|
||||
// ...it is here for backwards compatibility...
|
||||
|
||||
// the WRITEDELAY macro compiles to the time equivalent of 3 NOPs.
|
||||
// It is used in the frameworks to allow for write recovery time
|
||||
// requirements of certain registers. This is only necessary for
|
||||
// EZ-USB FX parts. See the EZ-USB FX TRM for
|
||||
// more information on write recovery time issues.
|
||||
#define WRITEDELAY() {char writedelaydummy = 0;}
|
||||
// if this firmware will never run on an EZ-USB FX part replace
|
||||
// with:
|
||||
// #define WRITEDELAY()
|
||||
|
||||
// macro to reset and endpoint data toggle
|
||||
#define EZUSB_RESET_DATA_TOGGLE(ep) TOGCTL = (((ep & 0x80) >> 3) + (ep & 0x0F));\
|
||||
TOGCTL |= bmRESETTOGGLE
|
||||
|
||||
|
||||
#define EZUSB_ENABLE_RSMIRQ() (EICON |= 0x20) // Enable Resume Interrupt (EPFI_)
|
||||
#define EZUSB_DISABLE_RSMIRQ() (EICON &= ~0x20) // Disable Resume Interrupt (EPFI_)
|
||||
#define EZUSB_CLEAR_RSMIRQ() (EICON &= ~0x10) // Clear Resume Interrupt Flag (PFI_)
|
||||
|
||||
#define EZUSB_GETI2CSTATUS() (I2CPckt.status)
|
||||
#define EZUSB_CLEARI2CSTATUS() if((I2CPckt.status == I2C_BERROR) || (I2CPckt.status == I2C_NACK))\
|
||||
I2CPckt.status = I2C_IDLE;
|
||||
|
||||
#define EZUSB_ENABLEBP() (BREAKPT |= bmBPEN)
|
||||
#define EZUSB_DISABLEBP() (BREAKPT &= ~bmBPEN)
|
||||
#define EZUSB_CLEARBP() (BREAKPT |= bmBREAK)
|
||||
#define EZUSB_BP(addr) BPADDRH = (BYTE)(((WORD)addr >> 8) & 0xff);\
|
||||
BPADDRL = (BYTE)addr
|
||||
|
||||
#define EZUSB_EXTWAKEUP() (((WAKEUPCS & bmWU2) && (WAKEUPCS & bmWU2EN)) ||\
|
||||
((WAKEUPCS & bmWU) && (WAKEUPCS & bmWUEN)))
|
||||
|
||||
#define EZUSB_HIGHSPEED() (USBCS & bmHSM)
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Datatypes
|
||||
//-----------------------------------------------------------------------------
|
||||
typedef unsigned char BYTE;
|
||||
typedef unsigned short WORD;
|
||||
typedef unsigned long DWORD;
|
||||
typedef bit BOOL;
|
||||
|
||||
#define INT0_VECT 0
|
||||
#define TMR0_VECT 1
|
||||
#define INT1_VECT 2
|
||||
#define TMR1_VECT 3
|
||||
#define COM0_VECT 4
|
||||
#define TMR2_VECT 5
|
||||
#define WKUP_VECT 6
|
||||
#define COM1_VECT 7
|
||||
#define USB_VECT 8
|
||||
#define I2C_VECT 9
|
||||
#define INT4_VECT 10
|
||||
#define INT5_VECT 11
|
||||
#define INT6_VECT 12
|
||||
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length;
|
||||
BYTE type;
|
||||
}DSCR;
|
||||
|
||||
typedef struct // Device Descriptor
|
||||
{
|
||||
BYTE length; // Descriptor length ( = sizeof(DEVICEDSCR) )
|
||||
BYTE type; // Decriptor type (Device = 1)
|
||||
BYTE spec_ver_minor; // Specification Version (BCD) minor
|
||||
BYTE spec_ver_major; // Specification Version (BCD) major
|
||||
BYTE dev_class; // Device class
|
||||
BYTE sub_class; // Device sub-class
|
||||
BYTE protocol; // Device sub-sub-class
|
||||
BYTE max_packet; // Maximum packet size
|
||||
WORD vendor_id; // Vendor ID
|
||||
WORD product_id; // Product ID
|
||||
WORD version_id; // Product version ID
|
||||
BYTE mfg_str; // Manufacturer string index
|
||||
BYTE prod_str; // Product string index
|
||||
BYTE serialnum_str; // Serial number string index
|
||||
BYTE configs; // Number of configurations
|
||||
}DEVICEDSCR;
|
||||
|
||||
typedef struct // Device Qualifier Descriptor
|
||||
{
|
||||
BYTE length; // Descriptor length ( = sizeof(DEVICEQUALDSCR) )
|
||||
BYTE type; // Decriptor type (Device Qualifier = 6)
|
||||
BYTE spec_ver_minor; // Specification Version (BCD) minor
|
||||
BYTE spec_ver_major; // Specification Version (BCD) major
|
||||
BYTE dev_class; // Device class
|
||||
BYTE sub_class; // Device sub-class
|
||||
BYTE protocol; // Device sub-sub-class
|
||||
BYTE max_packet; // Maximum packet size
|
||||
BYTE configs; // Number of configurations
|
||||
BYTE reserved0;
|
||||
}DEVICEQUALDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // Configuration length ( = sizeof(CONFIGDSCR) )
|
||||
BYTE type; // Descriptor type (Configuration = 2)
|
||||
WORD config_len; // Configuration + End Points length
|
||||
BYTE interfaces; // Number of interfaces
|
||||
BYTE index; // Configuration number
|
||||
BYTE config_str; // Configuration string
|
||||
BYTE attrib; // Attributes (b7 - buspwr, b6 - selfpwr, b5 - rwu
|
||||
BYTE power; // Power requirement (div 2 ma)
|
||||
}CONFIGDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // Interface descriptor length ( - sizeof(INTRFCDSCR) )
|
||||
BYTE type; // Descriptor type (Interface = 4)
|
||||
BYTE index; // Zero-based index of this interface
|
||||
BYTE alt_setting; // Alternate setting
|
||||
BYTE ep_cnt; // Number of end points
|
||||
BYTE class; // Interface class
|
||||
BYTE sub_class; // Interface sub class
|
||||
BYTE protocol; // Interface sub sub class
|
||||
BYTE interface_str; // Interface descriptor string index
|
||||
}INTRFCDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // End point descriptor length ( = sizeof(ENDPNTDSCR) )
|
||||
BYTE type; // Descriptor type (End point = 5)
|
||||
BYTE addr; // End point address
|
||||
BYTE ep_type; // End point type
|
||||
BYTE mp_L; // Maximum packet size
|
||||
BYTE mp_H;
|
||||
BYTE interval; // Interrupt polling interval
|
||||
}ENDPNTDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length; // String descriptor length
|
||||
BYTE type; // Descriptor type
|
||||
}STRINGDSCR;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE cntrl; // End point control register
|
||||
BYTE bytes; // End point buffer byte count
|
||||
}EPIOC;
|
||||
|
||||
typedef struct
|
||||
{
|
||||
BYTE length;
|
||||
BYTE *dat;
|
||||
BYTE count;
|
||||
BYTE status;
|
||||
}I2CPCKT;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Globals
|
||||
//-----------------------------------------------------------------------------
|
||||
extern code BYTE USB_AutoVector;
|
||||
|
||||
extern WORD pDeviceDscr;
|
||||
extern WORD pDeviceQualDscr;
|
||||
extern WORD pHighSpeedConfigDscr;
|
||||
extern WORD pFullSpeedConfigDscr;
|
||||
extern WORD pConfigDscr;
|
||||
extern WORD pOtherConfigDscr;
|
||||
extern WORD pStringDscr;
|
||||
|
||||
extern code DEVICEDSCR DeviceDscr;
|
||||
extern code DEVICEQUALDSCR DeviceQualDscr;
|
||||
extern code CONFIGDSCR HighSpeedConfigDscr;
|
||||
extern code CONFIGDSCR FullSpeedConfigDscr;
|
||||
extern code STRINGDSCR StringDscr;
|
||||
extern code DSCR UserDscr;
|
||||
|
||||
extern I2CPCKT I2CPckt;
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// Function Prototypes
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
extern void EZUSB_Renum(void);
|
||||
extern void EZUSB_Discon(BOOL renum);
|
||||
|
||||
extern void EZUSB_Susp(void);
|
||||
extern void EZUSB_Resume(void);
|
||||
|
||||
extern void EZUSB_Delay1ms(void);
|
||||
extern void EZUSB_Delay(WORD ms);
|
||||
|
||||
extern CONFIGDSCR xdata* EZUSB_GetConfigDscr(BYTE ConfigIdx);
|
||||
extern INTRFCDSCR xdata* EZUSB_GetIntrfcDscr(BYTE ConfigIdx, BYTE IntrfcIdx, BYTE AltSetting);
|
||||
extern STRINGDSCR xdata* EZUSB_GetStringDscr(BYTE StrIdx);
|
||||
extern DSCR xdata* EZUSB_GetDscr(BYTE index, DSCR* dscr, BYTE type);
|
||||
|
||||
extern void EZUSB_InitI2C(void);
|
||||
extern BOOL EZUSB_WriteI2C_(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_ReadI2C_(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_WriteI2C(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern BOOL EZUSB_ReadI2C(BYTE addr, BYTE length, BYTE xdata *dat);
|
||||
extern void EZUSB_WaitForEEPROMWrite(BYTE addr);
|
||||
|
||||
extern void modify_endpoint_stall(BYTE epid, BYTE stall);
|
||||
|
||||
#endif // FX2_H
|
@ -0,0 +1,687 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: FX2regs.h
|
||||
// Contents: EZ-USB FX2/FX2LP/FX1 register declarations and bit mask definitions.
|
||||
//
|
||||
// $Archive: /USB/Target/Inc/fx2regs.h $
|
||||
// $Date: 4/13/05 4:29p $
|
||||
// $Revision: 42 $
|
||||
//
|
||||
//
|
||||
// Copyright (c) 2005 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
#ifndef FX2REGS_H /* Header Sentry */
|
||||
#define FX2REGS_H
|
||||
|
||||
//-----------------------------------------------------------------------------
|
||||
// FX2/FX2LP/FX1 Related Register Assignments
|
||||
//-----------------------------------------------------------------------------
|
||||
|
||||
// The Ez-USB FX2/FX2LP/FX1 registers are defined here. We use fx2regs.h for register
|
||||
// address allocation by using "#define ALLOCATE_EXTERN".
|
||||
// When using "#define ALLOCATE_EXTERN", you get (for instance):
|
||||
// xdata volatile BYTE OUT7BUF[64] _at_ 0x7B40;
|
||||
// Such lines are created from FX2.h by using the preprocessor.
|
||||
// Incidently, these lines will not generate any space in the resulting hex
|
||||
// file; they just bind the symbols to the addresses for compilation.
|
||||
// You just need to put "#define ALLOCATE_EXTERN" in your main program file;
|
||||
// i.e. fw.c or a stand-alone C source file.
|
||||
// Without "#define ALLOCATE_EXTERN", you just get the external reference:
|
||||
// extern xdata volatile BYTE OUT7BUF[64] ;// 0x7B40;
|
||||
// This uses the concatenation operator "##" to insert a comment "//"
|
||||
// to cut off the end of the line, "_at_ 0x7B40;", which is not wanted.
|
||||
|
||||
#ifdef ALLOCATE_EXTERN
|
||||
#define EXTERN
|
||||
#define _AT_ _at_
|
||||
#else
|
||||
#define EXTERN extern
|
||||
#define _AT_ ;/ ## /
|
||||
#endif
|
||||
|
||||
xdata at 0xE400 volatile BYTE GPIF_WAVE_DATA;
|
||||
xdata at 0xE480 volatile BYTE RES_WAVEDATA_END;
|
||||
|
||||
// General Configuration
|
||||
|
||||
xdata at 0xE600 volatile BYTE CPUCS; // Control & Status
|
||||
xdata at 0xE601 volatile BYTE IFCONFIG; // Interface Configuration
|
||||
xdata at 0xE602 volatile BYTE PINFLAGSAB; // FIFO FLAGA and FLAGB Assignments
|
||||
xdata at 0xE603 volatile BYTE PINFLAGSCD; // FIFO FLAGC and FLAGD Assignments
|
||||
xdata at 0xE604 volatile BYTE FIFORESET; // Restore FIFOS to default state
|
||||
xdata at 0xE605 volatile BYTE BREAKPT; // Breakpoint
|
||||
xdata at 0xE606 volatile BYTE BPADDRH; // Breakpoint Address H
|
||||
xdata at 0xE607 volatile BYTE BPADDRL; // Breakpoint Address L
|
||||
xdata at 0xE608 volatile BYTE UART230; // 230 Kbaud clock for T0,T1,T2
|
||||
xdata at 0xE609 volatile BYTE FIFOPINPOLAR; // FIFO polarities
|
||||
xdata at 0xE60A volatile BYTE REVID; // Chip Revision
|
||||
xdata at 0xE60B volatile BYTE REVCTL; // Chip Revision Control
|
||||
|
||||
// Endpoint Configuration
|
||||
|
||||
xdata at 0xE610 volatile BYTE EP1OUTCFG; // Endpoint 1-OUT Configuration
|
||||
xdata at 0xE611 volatile BYTE EP1INCFG; // Endpoint 1-IN Configuration
|
||||
xdata at 0xE612 volatile BYTE EP2CFG; // Endpoint 2 Configuration
|
||||
xdata at 0xE613 volatile BYTE EP4CFG; // Endpoint 4 Configuration
|
||||
xdata at 0xE614 volatile BYTE EP6CFG; // Endpoint 6 Configuration
|
||||
xdata at 0xE615 volatile BYTE EP8CFG; // Endpoint 8 Configuration
|
||||
xdata at 0xE618 volatile BYTE EP2FIFOCFG; // Endpoint 2 FIFO configuration
|
||||
xdata at 0xE619 volatile BYTE EP4FIFOCFG; // Endpoint 4 FIFO configuration
|
||||
xdata at 0xE61A volatile BYTE EP6FIFOCFG; // Endpoint 6 FIFO configuration
|
||||
xdata at 0xE61B volatile BYTE EP8FIFOCFG; // Endpoint 8 FIFO configuration
|
||||
xdata at 0xE620 volatile BYTE EP2AUTOINLENH; // Endpoint 2 Packet Length H (IN only)
|
||||
xdata at 0xE621 volatile BYTE EP2AUTOINLENL; // Endpoint 2 Packet Length L (IN only)
|
||||
xdata at 0xE622 volatile BYTE EP4AUTOINLENH; // Endpoint 4 Packet Length H (IN only)
|
||||
xdata at 0xE623 volatile BYTE EP4AUTOINLENL; // Endpoint 4 Packet Length L (IN only)
|
||||
xdata at 0xE624 volatile BYTE EP6AUTOINLENH; // Endpoint 6 Packet Length H (IN only)
|
||||
xdata at 0xE625 volatile BYTE EP6AUTOINLENL; // Endpoint 6 Packet Length L (IN only)
|
||||
xdata at 0xE626 volatile BYTE EP8AUTOINLENH; // Endpoint 8 Packet Length H (IN only)
|
||||
xdata at 0xE627 volatile BYTE EP8AUTOINLENL; // Endpoint 8 Packet Length L (IN only)
|
||||
xdata at 0xE630 volatile BYTE EP2FIFOPFH; // EP2 Programmable Flag trigger H
|
||||
xdata at 0xE631 volatile BYTE EP2FIFOPFL; // EP2 Programmable Flag trigger L
|
||||
xdata at 0xE632 volatile BYTE EP4FIFOPFH; // EP4 Programmable Flag trigger H
|
||||
xdata at 0xE633 volatile BYTE EP4FIFOPFL; // EP4 Programmable Flag trigger L
|
||||
xdata at 0xE634 volatile BYTE EP6FIFOPFH; // EP6 Programmable Flag trigger H
|
||||
xdata at 0xE635 volatile BYTE EP6FIFOPFL; // EP6 Programmable Flag trigger L
|
||||
xdata at 0xE636 volatile BYTE EP8FIFOPFH; // EP8 Programmable Flag trigger H
|
||||
xdata at 0xE637 volatile BYTE EP8FIFOPFL; // EP8 Programmable Flag trigger L
|
||||
xdata at 0xE640 volatile BYTE EP2ISOINPKTS; // EP2 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE641 volatile BYTE EP4ISOINPKTS; // EP4 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE642 volatile BYTE EP6ISOINPKTS; // EP6 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE643 volatile BYTE EP8ISOINPKTS; // EP8 (if ISO) IN Packets per frame (1-3)
|
||||
xdata at 0xE648 volatile BYTE INPKTEND; // Force IN Packet End
|
||||
xdata at 0xE649 volatile BYTE OUTPKTEND; // Force OUT Packet End
|
||||
|
||||
// Interrupts
|
||||
|
||||
xdata at 0xE650 volatile BYTE EP2FIFOIE; // Endpoint 2 Flag Interrupt Enable
|
||||
xdata at 0xE651 volatile BYTE EP2FIFOIRQ; // Endpoint 2 Flag Interrupt Request
|
||||
xdata at 0xE652 volatile BYTE EP4FIFOIE; // Endpoint 4 Flag Interrupt Enable
|
||||
xdata at 0xE653 volatile BYTE EP4FIFOIRQ; // Endpoint 4 Flag Interrupt Request
|
||||
xdata at 0xE654 volatile BYTE EP6FIFOIE; // Endpoint 6 Flag Interrupt Enable
|
||||
xdata at 0xE655 volatile BYTE EP6FIFOIRQ; // Endpoint 6 Flag Interrupt Request
|
||||
xdata at 0xE656 volatile BYTE EP8FIFOIE; // Endpoint 8 Flag Interrupt Enable
|
||||
xdata at 0xE657 volatile BYTE EP8FIFOIRQ; // Endpoint 8 Flag Interrupt Request
|
||||
xdata at 0xE658 volatile BYTE IBNIE; // IN-BULK-NAK Interrupt Enable
|
||||
xdata at 0xE659 volatile BYTE IBNIRQ; // IN-BULK-NAK interrupt Request
|
||||
xdata at 0xE65A volatile BYTE NAKIE; // Endpoint Ping NAK interrupt Enable
|
||||
xdata at 0xE65B volatile BYTE NAKIRQ; // Endpoint Ping NAK interrupt Request
|
||||
xdata at 0xE65C volatile BYTE USBIE; // USB Int Enables
|
||||
xdata at 0xE65D volatile BYTE USBIRQ; // USB Interrupt Requests
|
||||
xdata at 0xE65E volatile BYTE EPIE; // Endpoint Interrupt Enables
|
||||
xdata at 0xE65F volatile BYTE EPIRQ; // Endpoint Interrupt Requests
|
||||
xdata at 0xE660 volatile BYTE GPIFIE; // GPIF Interrupt Enable
|
||||
xdata at 0xE661 volatile BYTE GPIFIRQ; // GPIF Interrupt Request
|
||||
xdata at 0xE662 volatile BYTE USBERRIE; // USB Error Interrupt Enables
|
||||
xdata at 0xE663 volatile BYTE USBERRIRQ; // USB Error Interrupt Requests
|
||||
xdata at 0xE664 volatile BYTE ERRCNTLIM; // USB Error counter and limit
|
||||
xdata at 0xE665 volatile BYTE CLRERRCNT; // Clear Error Counter EC[3..0]
|
||||
xdata at 0xE666 volatile BYTE INT2IVEC; // Interupt 2 (USB) Autovector
|
||||
xdata at 0xE667 volatile BYTE INT4IVEC; // Interupt 4 (FIFOS & GPIF) Autovector
|
||||
xdata at 0xE668 volatile BYTE INTSETUP; // Interrupt 2&4 Setup
|
||||
|
||||
// Input/Output
|
||||
|
||||
xdata at 0xE670 volatile BYTE PORTACFG; // I/O PORTA Alternate Configuration
|
||||
xdata at 0xE671 volatile BYTE PORTCCFG; // I/O PORTC Alternate Configuration
|
||||
xdata at 0xE672 volatile BYTE PORTECFG; // I/O PORTE Alternate Configuration
|
||||
xdata at 0xE678 volatile BYTE I2CS; // Control & Status
|
||||
xdata at 0xE679 volatile BYTE I2DAT; // Data
|
||||
xdata at 0xE67A volatile BYTE I2CTL; // I2C Control
|
||||
xdata at 0xE67B volatile BYTE XAUTODAT1; // Autoptr1 MOVX access
|
||||
xdata at 0xE67C volatile BYTE XAUTODAT2; // Autoptr2 MOVX access
|
||||
|
||||
#define EXTAUTODAT1 XAUTODAT1
|
||||
#define EXTAUTODAT2 XAUTODAT2
|
||||
|
||||
// USB Control
|
||||
|
||||
xdata at 0xE680 volatile BYTE USBCS; // USB Control & Status
|
||||
xdata at 0xE681 volatile BYTE SUSPEND; // Put chip into suspend
|
||||
xdata at 0xE682 volatile BYTE WAKEUPCS; // Wakeup source and polarity
|
||||
xdata at 0xE683 volatile BYTE TOGCTL; // Toggle Control
|
||||
xdata at 0xE684 volatile BYTE USBFRAMEH; // USB Frame count H
|
||||
xdata at 0xE685 volatile BYTE USBFRAMEL; // USB Frame count L
|
||||
xdata at 0xE686 volatile BYTE MICROFRAME; // Microframe count, 0-7
|
||||
xdata at 0xE687 volatile BYTE FNADDR; // USB Function address
|
||||
|
||||
// Endpoints
|
||||
|
||||
xdata at 0xE68A volatile BYTE EP0BCH; // Endpoint 0 Byte Count H
|
||||
xdata at 0xE68B volatile BYTE EP0BCL; // Endpoint 0 Byte Count L
|
||||
xdata at 0xE68D volatile BYTE EP1OUTBC; // Endpoint 1 OUT Byte Count
|
||||
xdata at 0xE68F volatile BYTE EP1INBC; // Endpoint 1 IN Byte Count
|
||||
xdata at 0xE690 volatile BYTE EP2BCH; // Endpoint 2 Byte Count H
|
||||
xdata at 0xE691 volatile BYTE EP2BCL; // Endpoint 2 Byte Count L
|
||||
xdata at 0xE694 volatile BYTE EP4BCH; // Endpoint 4 Byte Count H
|
||||
xdata at 0xE695 volatile BYTE EP4BCL; // Endpoint 4 Byte Count L
|
||||
xdata at 0xE698 volatile BYTE EP6BCH; // Endpoint 6 Byte Count H
|
||||
xdata at 0xE699 volatile BYTE EP6BCL; // Endpoint 6 Byte Count L
|
||||
xdata at 0xE69C volatile BYTE EP8BCH; // Endpoint 8 Byte Count H
|
||||
xdata at 0xE69D volatile BYTE EP8BCL; // Endpoint 8 Byte Count L
|
||||
xdata at 0xE6A0 volatile BYTE EP0CS; // Endpoint Control and Status
|
||||
xdata at 0xE6A1 volatile BYTE EP1OUTCS; // Endpoint 1 OUT Control and Status
|
||||
xdata at 0xE6A2 volatile BYTE EP1INCS; // Endpoint 1 IN Control and Status
|
||||
xdata at 0xE6A3 volatile BYTE EP2CS; // Endpoint 2 Control and Status
|
||||
xdata at 0xE6A4 volatile BYTE EP4CS; // Endpoint 4 Control and Status
|
||||
xdata at 0xE6A5 volatile BYTE EP6CS; // Endpoint 6 Control and Status
|
||||
xdata at 0xE6A6 volatile BYTE EP8CS; // Endpoint 8 Control and Status
|
||||
xdata at 0xE6A7 volatile BYTE EP2FIFOFLGS; // Endpoint 2 Flags
|
||||
xdata at 0xE6A8 volatile BYTE EP4FIFOFLGS; // Endpoint 4 Flags
|
||||
xdata at 0xE6A9 volatile BYTE EP6FIFOFLGS; // Endpoint 6 Flags
|
||||
xdata at 0xE6AA volatile BYTE EP8FIFOFLGS; // Endpoint 8 Flags
|
||||
xdata at 0xE6AB volatile BYTE EP2FIFOBCH; // EP2 FIFO total byte count H
|
||||
xdata at 0xE6AC volatile BYTE EP2FIFOBCL; // EP2 FIFO total byte count L
|
||||
xdata at 0xE6AD volatile BYTE EP4FIFOBCH; // EP4 FIFO total byte count H
|
||||
xdata at 0xE6AE volatile BYTE EP4FIFOBCL; // EP4 FIFO total byte count L
|
||||
xdata at 0xE6AF volatile BYTE EP6FIFOBCH; // EP6 FIFO total byte count H
|
||||
xdata at 0xE6B0 volatile BYTE EP6FIFOBCL; // EP6 FIFO total byte count L
|
||||
xdata at 0xE6B1 volatile BYTE EP8FIFOBCH; // EP8 FIFO total byte count H
|
||||
xdata at 0xE6B2 volatile BYTE EP8FIFOBCL; // EP8 FIFO total byte count L
|
||||
xdata at 0xE6B3 volatile BYTE SUDPTRH; // Setup Data Pointer high address byte
|
||||
xdata at 0xE6B4 volatile BYTE SUDPTRL; // Setup Data Pointer low address byte
|
||||
xdata at 0xE6B5 volatile BYTE SUDPTRCTL; // Setup Data Pointer Auto Mode
|
||||
xdata at 0xE6B8 volatile BYTE SETUPDAT[8]; // 8 bytes of SETUP data
|
||||
|
||||
// GPIF
|
||||
|
||||
xdata at 0xE6C0 volatile BYTE GPIFWFSELECT; // Waveform Selector
|
||||
xdata at 0xE6C1 volatile BYTE GPIFIDLECS; // GPIF Done, GPIF IDLE drive mode
|
||||
xdata at 0xE6C2 volatile BYTE GPIFIDLECTL; // Inactive Bus, CTL states
|
||||
xdata at 0xE6C3 volatile BYTE GPIFCTLCFG; // CTL OUT pin drive
|
||||
xdata at 0xE6C4 volatile BYTE GPIFADRH; // GPIF Address H
|
||||
xdata at 0xE6C5 volatile BYTE GPIFADRL; // GPIF Address L
|
||||
|
||||
xdata at 0xE6CE volatile BYTE GPIFTCB3; // GPIF Transaction Count Byte 3
|
||||
xdata at 0xE6CF volatile BYTE GPIFTCB2; // GPIF Transaction Count Byte 2
|
||||
xdata at 0xE6D0 volatile BYTE GPIFTCB1; // GPIF Transaction Count Byte 1
|
||||
xdata at 0xE6D1 volatile BYTE GPIFTCB0; // GPIF Transaction Count Byte 0
|
||||
|
||||
#define EP2GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP2GPIFTCL GPIFTCB0 //
|
||||
#define EP4GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP4GPIFTCL GPIFTCB0 //
|
||||
#define EP6GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP6GPIFTCL GPIFTCB0 //
|
||||
#define EP8GPIFTCH GPIFTCB1 // these are here for backwards compatibility
|
||||
#define EP8GPIFTCL GPIFTCB0 //
|
||||
|
||||
xdata at 0xE6D2 volatile BYTE EP2GPIFFLGSEL; // EP2 GPIF Flag select
|
||||
xdata at 0xE6D3 volatile BYTE EP2GPIFPFSTOP; // Stop GPIF EP2 transaction on prog. flag
|
||||
xdata at 0xE6D4 volatile BYTE EP2GPIFTRIG; // EP2 FIFO Trigger
|
||||
xdata at 0xE6DA volatile BYTE EP4GPIFFLGSEL; // EP4 GPIF Flag select
|
||||
xdata at 0xE6DB volatile BYTE EP4GPIFPFSTOP; // Stop GPIF EP4 transaction on prog. flag
|
||||
xdata at 0xE6DC volatile BYTE EP4GPIFTRIG; // EP4 FIFO Trigger
|
||||
xdata at 0xE6E2 volatile BYTE EP6GPIFFLGSEL; // EP6 GPIF Flag select
|
||||
xdata at 0xE6E3 volatile BYTE EP6GPIFPFSTOP; // Stop GPIF EP6 transaction on prog. flag
|
||||
xdata at 0xE6E4 volatile BYTE EP6GPIFTRIG; // EP6 FIFO Trigger
|
||||
xdata at 0xE6EA volatile BYTE EP8GPIFFLGSEL; // EP8 GPIF Flag select
|
||||
xdata at 0xE6EB volatile BYTE EP8GPIFPFSTOP; // Stop GPIF EP8 transaction on prog. flag
|
||||
xdata at 0xE6EC volatile BYTE EP8GPIFTRIG; // EP8 FIFO Trigger
|
||||
xdata at 0xE6F0 volatile BYTE XGPIFSGLDATH; // GPIF Data H (16-bit mode only)
|
||||
xdata at 0xE6F1 volatile BYTE XGPIFSGLDATLX; // Read/Write GPIF Data L & trigger transac
|
||||
xdata at 0xE6F2 volatile BYTE XGPIFSGLDATLNOX; // Read GPIF Data L, no transac trigger
|
||||
xdata at 0xE6F3 volatile BYTE GPIFREADYCFG; // Internal RDY,Sync/Async, RDY5CFG
|
||||
xdata at 0xE6F4 volatile BYTE GPIFREADYSTAT; // RDY pin states
|
||||
xdata at 0xE6F5 volatile BYTE GPIFABORT; // Abort GPIF cycles
|
||||
|
||||
// UDMA
|
||||
|
||||
xdata at 0xE6C6 volatile BYTE FLOWSTATE; //Defines GPIF flow state
|
||||
xdata at 0xE6C7 volatile BYTE FLOWLOGIC; //Defines flow/hold decision criteria
|
||||
xdata at 0xE6C8 volatile BYTE FLOWEQ0CTL; //CTL states during active flow state
|
||||
xdata at 0xE6C9 volatile BYTE FLOWEQ1CTL; //CTL states during hold flow state
|
||||
xdata at 0xE6CA volatile BYTE FLOWHOLDOFF;
|
||||
xdata at 0xE6CB volatile BYTE FLOWSTB; //CTL/RDY Signal to use as master data strobe
|
||||
xdata at 0xE6CC volatile BYTE FLOWSTBEDGE; //Defines active master strobe edge
|
||||
xdata at 0xE6CD volatile BYTE FLOWSTBHPERIOD; //Half Period of output master strobe
|
||||
xdata at 0xE60C volatile BYTE GPIFHOLDAMOUNT; //Data delay shift
|
||||
xdata at 0xE67D volatile BYTE UDMACRCH; //CRC Upper byte
|
||||
xdata at 0xE67E volatile BYTE UDMACRCL; //CRC Lower byte
|
||||
xdata at 0xE67F volatile BYTE UDMACRCQUAL; //UDMA In only, host terminated use only
|
||||
|
||||
|
||||
// Debug/Test
|
||||
// The following registers are for Cypress's internal testing purposes only.
|
||||
// These registers are not documented in the datasheet or the Technical Reference
|
||||
// Manual as they were not designed for end user application usage
|
||||
xdata at 0xE6F8 volatile BYTE DBUG; // Debug
|
||||
xdata at 0xE6F9 volatile BYTE TESTCFG; // Test configuration
|
||||
xdata at 0xE6FA volatile BYTE USBTEST; // USB Test Modes
|
||||
xdata at 0xE6FB volatile BYTE CT1; // Chirp Test--Override
|
||||
xdata at 0xE6FC volatile BYTE CT2; // Chirp Test--FSM
|
||||
xdata at 0xE6FD volatile BYTE CT3; // Chirp Test--Control Signals
|
||||
xdata at 0xE6FE volatile BYTE CT4; // Chirp Test--Inputs
|
||||
|
||||
// Endpoint Buffers
|
||||
|
||||
xdata at 0xE740 volatile BYTE EP0BUF[64]; // EP0 IN-OUT buffer
|
||||
xdata at 0xE780 volatile BYTE EP1OUTBUF[64]; // EP1-OUT buffer
|
||||
xdata at 0xE7C0 volatile BYTE EP1INBUF[64]; // EP1-IN buffer
|
||||
xdata at 0xF000 volatile BYTE EP2FIFOBUF[1024]; // 512/1024-byte EP2 buffer (IN or OUT)
|
||||
xdata at 0xF400 volatile BYTE EP4FIFOBUF[1024]; // 512 byte EP4 buffer (IN or OUT)
|
||||
xdata at 0xF800 volatile BYTE EP6FIFOBUF[1024]; // 512/1024-byte EP6 buffer (IN or OUT)
|
||||
xdata at 0xFC00 volatile BYTE EP8FIFOBUF[1024]; // 512 byte EP8 buffer (IN or OUT)
|
||||
|
||||
// Error Correction Code (ECC) Registers (FX2LP/FX1 only)
|
||||
|
||||
xdata at 0xE628 volatile BYTE ECCCFG; // ECC Configuration
|
||||
xdata at 0xE629 volatile BYTE ECCRESET; // ECC Reset
|
||||
xdata at 0xE62A volatile BYTE ECC1B0; // ECC1 Byte 0
|
||||
xdata at 0xE62B volatile BYTE ECC1B1; // ECC1 Byte 1
|
||||
xdata at 0xE62C volatile BYTE ECC1B2; // ECC1 Byte 2
|
||||
xdata at 0xE62D volatile BYTE ECC2B0; // ECC2 Byte 0
|
||||
xdata at 0xE62E volatile BYTE ECC2B1; // ECC2 Byte 1
|
||||
xdata at 0xE62F volatile BYTE ECC2B2; // ECC2 Byte 2
|
||||
|
||||
// Feature Registers (FX2LP/FX1 only)
|
||||
xdata at 0xE50D volatile BYTE GPCR2; // Chip Features
|
||||
|
||||
#undef EXTERN
|
||||
#undef _AT_
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Special Function Registers (SFRs)
|
||||
The byte registers and bits defined in the following list are based
|
||||
on the Synopsis definition of the 8051 Special Function Registers for EZ-USB.
|
||||
If you modify the register definitions below, please regenerate the file
|
||||
"ezregs.inc" which includes the same basic information for assembly inclusion.
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
sfr at 0x80 IOA;
|
||||
/* IOA */
|
||||
sbit at (0x80 + 0) PA0;
|
||||
sbit at (0x80 + 1) PA1;
|
||||
sbit at (0x80 + 2) PA2;
|
||||
sbit at (0x80 + 3) PA3;
|
||||
|
||||
sbit at (0x80 + 4) PA4;
|
||||
sbit at (0x80 + 5) PA5;
|
||||
sbit at (0x80 + 6) PA6;
|
||||
sbit at (0x80 + 7) PA7;
|
||||
sfr at 0x81 SP;
|
||||
sfr at 0x82 DPL;
|
||||
sfr at 0x83 DPH;
|
||||
sfr at 0x84 DPL1;
|
||||
sfr at 0x85 DPH1;
|
||||
sfr at 0x86 DPS;
|
||||
/* DPS */
|
||||
// sbit SEL = 0x86+0;
|
||||
sfr at 0x87 PCON;
|
||||
/* PCON */
|
||||
//sbit IDLE = 0x87+0;
|
||||
//sbit STOP = 0x87+1;
|
||||
//sbit GF0 = 0x87+2;
|
||||
//sbit GF1 = 0x87+3;
|
||||
//sbit SMOD0 = 0x87+7;
|
||||
sfr at 0x88 TCON;
|
||||
/* TCON */
|
||||
sbit at (0x88+0) IT0;
|
||||
sbit at (0x88+1) IE0;
|
||||
sbit at (0x88+2) IT1;
|
||||
sbit at (0x88+3) IE1;
|
||||
sbit at (0x88+4) TR0;
|
||||
sbit at (0x88+5) TF0;
|
||||
sbit at (0x88+6) TR1;
|
||||
sbit at (0x88+7) TF1;
|
||||
sfr at 0x89 TMOD;
|
||||
/* TMOD */
|
||||
//sbit M00 = 0x89+0;
|
||||
//sbit M10 = 0x89+1;
|
||||
//sbit CT0 = 0x89+2;
|
||||
//sbit GATE0 = 0x89+3;
|
||||
//sbit M01 = 0x89+4;
|
||||
//sbit M11 = 0x89+5;
|
||||
//sbit CT1 = 0x89+6;
|
||||
//sbit GATE1 = 0x89+7;
|
||||
sfr at 0x8A TL0;
|
||||
sfr at 0x8B TL1;
|
||||
sfr at 0x8C TH0;
|
||||
sfr at 0x8D TH1;
|
||||
sfr at 0x8E CKCON;
|
||||
/* CKCON */
|
||||
//sbit MD0 = 0x89+0;
|
||||
//sbit MD1 = 0x89+1;
|
||||
//sbit MD2 = 0x89+2;
|
||||
//sbit T0M = 0x89+3;
|
||||
//sbit T1M = 0x89+4;
|
||||
//sbit T2M = 0x89+5;
|
||||
sfr at 0x8F SPC_FNC; // Was WRS in Reg320
|
||||
/* CKCON */
|
||||
//sbit WRS = 0x8F+0;
|
||||
sfr at 0x90 IOB;
|
||||
/* IOB */
|
||||
sbit at (0x90 + 0) PB0;
|
||||
sbit at (0x90 + 1) PB1;
|
||||
sbit at (0x90 + 2) PB2;
|
||||
sbit at (0x90 + 3) PB3;
|
||||
|
||||
sbit at (0x90 + 4) PB4;
|
||||
sbit at (0x90 + 5) PB5;
|
||||
sbit at (0x90 + 6) PB6;
|
||||
sbit at (0x90 + 7) PB7;
|
||||
sfr at 0x91 EXIF; // EXIF Bit Values differ from Reg320
|
||||
/* EXIF */
|
||||
//sbit USBINT = 0x91+4;
|
||||
//sbit I2CINT = 0x91+5;
|
||||
//sbit IE4 = 0x91+6;
|
||||
//sbit IE5 = 0x91+7;
|
||||
sfr at 0x92 MPAGE;
|
||||
sfr at 0x98 SCON0;
|
||||
/* SCON0 */
|
||||
sbit at (0x98+0) RI;
|
||||
sbit at (0x98+1) TI;
|
||||
sbit at (0x98+2) RB8;
|
||||
sbit at (0x98+3) TB8;
|
||||
sbit at (0x98+4) REN;
|
||||
sbit at (0x98+5) SM2;
|
||||
sbit at (0x98+6) SM1;
|
||||
sbit at (0x98+7) SM0;
|
||||
sfr at 0x99 SBUF0;
|
||||
|
||||
#define AUTOPTR1H AUTOPTRH1 // for backwards compatibility with examples
|
||||
#define AUTOPTR1L AUTOPTRL1 // for backwards compatibility with examples
|
||||
#define APTR1H AUTOPTRH1 // for backwards compatibility with examples
|
||||
#define APTR1L AUTOPTRL1 // for backwards compatibility with examples
|
||||
|
||||
// this is how they are defined in the TRM
|
||||
sfr at 0x9A AUTOPTRH1;
|
||||
sfr at 0x9B AUTOPTRL1;
|
||||
sfr at 0x9D AUTOPTRH2;
|
||||
sfr at 0x9E AUTOPTRL2;
|
||||
|
||||
sfr at 0xA0 IOC;
|
||||
/* IOC */
|
||||
sbit at (0xA0 + 0) PC0;
|
||||
sbit at (0xA0 + 1) PC1;
|
||||
sbit at (0xA0 + 2) PC2;
|
||||
sbit at (0xA0 + 3) PC3;
|
||||
|
||||
sbit at (0xA0 + 4) PC4;
|
||||
sbit at (0xA0 + 5) PC5;
|
||||
sbit at (0xA0 + 6) PC6;
|
||||
sbit at (0xA0 + 7) PC7;
|
||||
sfr at 0xA1 INT2CLR;
|
||||
sfr at 0xA2 INT4CLR;
|
||||
|
||||
sfr at 0xA8 IE;
|
||||
/* IE */
|
||||
sbit at (0xA8+0) EX0;
|
||||
sbit at (0xA8+1) ET0;
|
||||
sbit at (0xA8+2) EX1;
|
||||
sbit at (0xA8+3) ET1;
|
||||
sbit at (0xA8+4) ES0;
|
||||
sbit at (0xA8+5) ET2;
|
||||
sbit at (0xA8+6) ES1;
|
||||
sbit at (0xA8+7) EA;
|
||||
|
||||
sfr at 0xAA EP2468STAT;
|
||||
/* EP2468STAT */
|
||||
//sbit EP2E = 0xAA+0;
|
||||
//sbit EP2F = 0xAA+1;
|
||||
//sbit EP4E = 0xAA+2;
|
||||
//sbit EP4F = 0xAA+3;
|
||||
//sbit EP6E = 0xAA+4;
|
||||
//sbit EP6F = 0xAA+5;
|
||||
//sbit EP8E = 0xAA+6;
|
||||
//sbit EP8F = 0xAA+7;
|
||||
|
||||
sfr at 0xAB EP24FIFOFLGS;
|
||||
sfr at 0xAC EP68FIFOFLGS;
|
||||
sfr at 0xAF AUTOPTRSETUP;
|
||||
/* AUTOPTRSETUP */
|
||||
// sbit EXTACC = 0xAF+0;
|
||||
// sbit APTR1FZ = 0xAF+1;
|
||||
// sbit APTR2FZ = 0xAF+2;
|
||||
|
||||
sfr at 0xB0 IOD;
|
||||
/* IOD */
|
||||
sbit at (0xB0 + 0) PD0;
|
||||
sbit at (0xB0 + 1) PD1;
|
||||
sbit at (0xB0 + 2) PD2;
|
||||
sbit at (0xB0 + 3) PD3;
|
||||
|
||||
sbit at (0xB0 + 4) PD4;
|
||||
sbit at (0xB0 + 5) PD5;
|
||||
sbit at (0xB0 + 6) PD6;
|
||||
sbit at (0xB0 + 7) PD7;
|
||||
sfr at 0xB1 IOE;
|
||||
sfr at 0xB2 OEA;
|
||||
sfr at 0xB3 OEB;
|
||||
sfr at 0xB4 OEC;
|
||||
sfr at 0xB5 OED;
|
||||
sfr at 0xB6 OEE;
|
||||
|
||||
sfr at 0xB8 IP;
|
||||
/* IP */
|
||||
sbit at (0xB8+0) PX0;
|
||||
sbit at (0xB8+1) PT0;
|
||||
sbit at (0xB8+2) PX1;
|
||||
sbit at (0xB8+3) PT1;
|
||||
sbit at (0xB8+4) PS0;
|
||||
sbit at (0xB8+5) PT2;
|
||||
sbit at (0xB8+6) PS1;
|
||||
|
||||
sfr at 0xBA EP01STAT;
|
||||
sfr at 0xBB GPIFTRIG;
|
||||
|
||||
sfr at 0xBD GPIFSGLDATH;
|
||||
sfr at 0xBE GPIFSGLDATLX;
|
||||
sfr at 0xBF GPIFSGLDATLNOX;
|
||||
|
||||
sfr at 0xC0 SCON1;
|
||||
/* SCON1 */
|
||||
sbit at (0xC0+0) RI1;
|
||||
sbit at (0xC0+1) TI1;
|
||||
sbit at (0xC0+2) RB81;
|
||||
sbit at (0xC0+3) TB81;
|
||||
sbit at (0xC0+4) REN1;
|
||||
sbit at (0xC0+5) SM21;
|
||||
sbit at (0xC0+6) SM11;
|
||||
sbit at (0xC0+7) SM01;
|
||||
sfr at 0xC1 SBUF1;
|
||||
sfr at 0xC8 T2CON;
|
||||
/* T2CON */
|
||||
sbit at (0xC8+0) CP_RL2;
|
||||
sbit at (0xC8+1) C_T2;
|
||||
sbit at (0xC8+2) TR2;
|
||||
sbit at (0xC8+3) EXEN2;
|
||||
sbit at (0xC8+4) TCLK;
|
||||
sbit at (0xC8+5) RCLK;
|
||||
sbit at (0xC8+6) EXF2;
|
||||
sbit at (0xC8+7) TF2;
|
||||
sfr at 0xCA RCAP2L;
|
||||
sfr at 0xCB RCAP2H;
|
||||
sfr at 0xCC TL2;
|
||||
sfr at 0xCD TH2;
|
||||
sfr at 0xD0 PSW;
|
||||
/* PSW */
|
||||
sbit at (0xD0+0) P;
|
||||
sbit at (0xD0+1) FL;
|
||||
sbit at (0xD0+2) OV;
|
||||
sbit at (0xD0+3) RS0;
|
||||
sbit at (0xD0+4) RS1;
|
||||
sbit at (0xD0+5) F0;
|
||||
sbit at (0xD0+6) AC;
|
||||
sbit at (0xD0+7) CY;
|
||||
sfr at 0xD8 EICON; // Was WDCON in DS80C320; Bit Values differ from Reg320
|
||||
/* EICON */
|
||||
sbit at (0xD8+3) INT6;
|
||||
sbit at (0xD8+4) RESI;
|
||||
sbit at (0xD8+5) ERESI;
|
||||
sbit at (0xD8+7) SMOD1;
|
||||
sfr at 0xE0 ACC;
|
||||
sfr at 0xE8 EIE; // EIE Bit Values differ from Reg320
|
||||
/* EIE */
|
||||
sbit at (0xE8+0) EUSB;
|
||||
sbit at (0xE8+1) EI2C;
|
||||
sbit at (0xE8+2) EIEX4;
|
||||
sbit at (0xE8+3) EIEX5;
|
||||
sbit at (0xE8+4) EIEX6;
|
||||
sfr at 0xF0 B;
|
||||
sfr at 0xF8 EIP; // EIP Bit Values differ from Reg320
|
||||
/* EIP */
|
||||
sbit at (0xF8+0) PUSB;
|
||||
sbit at (0xF8+1) PI2C;
|
||||
sbit at (0xF8+2) EIPX4;
|
||||
sbit at (0xF8+3) EIPX5;
|
||||
sbit at (0xF8+4) EIPX6;
|
||||
|
||||
/*-----------------------------------------------------------------------------
|
||||
Bit Masks
|
||||
-----------------------------------------------------------------------------*/
|
||||
|
||||
/* CPU Control & Status Register (CPUCS) */
|
||||
#define bmPRTCSTB bmBIT5
|
||||
#define bmCLKSPD (bmBIT4 | bmBIT3)
|
||||
#define bmCLKSPD1 bmBIT4
|
||||
#define bmCLKSPD0 bmBIT3
|
||||
#define bmCLKINV bmBIT2
|
||||
#define bmCLKOE bmBIT1
|
||||
#define bm8051RES bmBIT0
|
||||
/* Port Alternate Configuration Registers */
|
||||
/* Port A (PORTACFG) */
|
||||
#define bmFLAGD bmBIT7
|
||||
#define bmINT1 bmBIT1
|
||||
#define bmINT0 bmBIT0
|
||||
/* Port C (PORTCCFG) */
|
||||
#define bmGPIFA7 bmBIT7
|
||||
#define bmGPIFA6 bmBIT6
|
||||
#define bmGPIFA5 bmBIT5
|
||||
#define bmGPIFA4 bmBIT4
|
||||
#define bmGPIFA3 bmBIT3
|
||||
#define bmGPIFA2 bmBIT2
|
||||
#define bmGPIFA1 bmBIT1
|
||||
#define bmGPIFA0 bmBIT0
|
||||
/* Port E (PORTECFG) */
|
||||
#define bmGPIFA8 bmBIT7
|
||||
#define bmT2EX bmBIT6
|
||||
#define bmINT6 bmBIT5
|
||||
#define bmRXD1OUT bmBIT4
|
||||
#define bmRXD0OUT bmBIT3
|
||||
#define bmT2OUT bmBIT2
|
||||
#define bmT1OUT bmBIT1
|
||||
#define bmT0OUT bmBIT0
|
||||
|
||||
/* I2C Control & Status Register (I2CS) */
|
||||
#define bmSTART bmBIT7
|
||||
#define bmSTOP bmBIT6
|
||||
#define bmLASTRD bmBIT5
|
||||
#define bmID (bmBIT4 | bmBIT3)
|
||||
#define bmBERR bmBIT2
|
||||
#define bmACK bmBIT1
|
||||
#define bmDONE bmBIT0
|
||||
/* I2C Control Register (I2CTL) */
|
||||
#define bmSTOPIE bmBIT1
|
||||
#define bm400KHZ bmBIT0
|
||||
/* Interrupt 2 (USB) Autovector Register (INT2IVEC) */
|
||||
#define bmIV4 bmBIT6
|
||||
#define bmIV3 bmBIT5
|
||||
#define bmIV2 bmBIT4
|
||||
#define bmIV1 bmBIT3
|
||||
#define bmIV0 bmBIT2
|
||||
/* USB Interrupt Request & Enable Registers (USBIE/USBIRQ) */
|
||||
#define bmEP0ACK bmBIT6
|
||||
#define bmHSGRANT bmBIT5
|
||||
#define bmURES bmBIT4
|
||||
#define bmSUSP bmBIT3
|
||||
#define bmSUTOK bmBIT2
|
||||
#define bmSOF bmBIT1
|
||||
#define bmSUDAV bmBIT0
|
||||
/* Breakpoint register (BREAKPT) */
|
||||
#define bmBREAK bmBIT3
|
||||
#define bmBPPULSE bmBIT2
|
||||
#define bmBPEN bmBIT1
|
||||
/* Interrupt 2 & 4 Setup (INTSETUP) */
|
||||
#define bmAV2EN bmBIT3
|
||||
#define INT4IN bmBIT1
|
||||
#define bmAV4EN bmBIT0
|
||||
/* USB Control & Status Register (USBCS) */
|
||||
#define bmHSM bmBIT7
|
||||
#define bmDISCON bmBIT3
|
||||
#define bmNOSYNSOF bmBIT2
|
||||
#define bmRENUM bmBIT1
|
||||
#define bmSIGRESUME bmBIT0
|
||||
/* Wakeup Control and Status Register (WAKEUPCS) */
|
||||
#define bmWU2 bmBIT7
|
||||
#define bmWU bmBIT6
|
||||
#define bmWU2POL bmBIT5
|
||||
#define bmWUPOL bmBIT4
|
||||
#define bmDPEN bmBIT2
|
||||
#define bmWU2EN bmBIT1
|
||||
#define bmWUEN bmBIT0
|
||||
/* End Point 0 Control & Status Register (EP0CS) */
|
||||
#define bmHSNAK bmBIT7
|
||||
/* End Point 0-1 Control & Status Registers (EP0CS/EP1OUTCS/EP1INCS) */
|
||||
#define bmEPBUSY bmBIT1
|
||||
#define bmEPSTALL bmBIT0
|
||||
/* End Point 2-8 Control & Status Registers (EP2CS/EP4CS/EP6CS/EP8CS) */
|
||||
#define bmNPAK (bmBIT6 | bmBIT5 | bmBIT4)
|
||||
#define bmEPFULL bmBIT3
|
||||
#define bmEPEMPTY bmBIT2
|
||||
/* Endpoint Status (EP2468STAT) SFR bits */
|
||||
#define bmEP8FULL bmBIT7
|
||||
#define bmEP8EMPTY bmBIT6
|
||||
#define bmEP6FULL bmBIT5
|
||||
#define bmEP6EMPTY bmBIT4
|
||||
#define bmEP4FULL bmBIT3
|
||||
#define bmEP4EMPTY bmBIT2
|
||||
#define bmEP2FULL bmBIT1
|
||||
#define bmEP2EMPTY bmBIT0
|
||||
/* SETUP Data Pointer Auto Mode (SUDPTRCTL) */
|
||||
#define bmSDPAUTO bmBIT0
|
||||
/* Endpoint Data Toggle Control (TOGCTL) */
|
||||
#define bmQUERYTOGGLE bmBIT7
|
||||
#define bmSETTOGGLE bmBIT6
|
||||
#define bmRESETTOGGLE bmBIT5
|
||||
#define bmTOGCTLEPMASK bmBIT3 | bmBIT2 | bmBIT1 | bmBIT0
|
||||
/* IBN (In Bulk Nak) enable and request bits (IBNIE/IBNIRQ) */
|
||||
#define bmEP8IBN bmBIT5
|
||||
#define bmEP6IBN bmBIT4
|
||||
#define bmEP4IBN bmBIT3
|
||||
#define bmEP2IBN bmBIT2
|
||||
#define bmEP1IBN bmBIT1
|
||||
#define bmEP0IBN bmBIT0
|
||||
|
||||
/* PING-NAK enable and request bits (NAKIE/NAKIRQ) */
|
||||
#define bmEP8PING bmBIT7
|
||||
#define bmEP6PING bmBIT6
|
||||
#define bmEP4PING bmBIT5
|
||||
#define bmEP2PING bmBIT4
|
||||
#define bmEP1PING bmBIT3
|
||||
#define bmEP0PING bmBIT2
|
||||
#define bmIBN bmBIT0
|
||||
|
||||
/* Interface Configuration bits (IFCONFIG) */
|
||||
#define bmIFCLKSRC bmBIT7
|
||||
#define bm3048MHZ bmBIT6
|
||||
#define bmIFCLKOE bmBIT5
|
||||
#define bmIFCLKPOL bmBIT4
|
||||
#define bmASYNC bmBIT3
|
||||
#define bmGSTATE bmBIT2
|
||||
#define bmIFCFG1 bmBIT1
|
||||
#define bmIFCFG0 bmBIT0
|
||||
#define bmIFCFGMASK (bmIFCFG0 | bmIFCFG1)
|
||||
#define bmIFGPIF bmIFCFG1
|
||||
|
||||
/* EP 2468 FIFO Configuration bits (EP2FIFOCFG,EP4FIFOCFG,EP6FIFOCFG,EP8FIFOCFG) */
|
||||
#define bmINFM bmBIT6
|
||||
#define bmOEP bmBIT5
|
||||
#define bmAUTOOUT bmBIT4
|
||||
#define bmAUTOIN bmBIT3
|
||||
#define bmZEROLENIN bmBIT2
|
||||
#define bmWORDWIDE bmBIT0
|
||||
|
||||
/* Chip Revision Control Bits (REVCTL) - used to ebable/disable revision specidic
|
||||
features */
|
||||
#define bmNOAUTOARM bmBIT1
|
||||
#define bmSKIPCOMMIT bmBIT0
|
||||
|
||||
/* Fifo Reset bits (FIFORESET) */
|
||||
#define bmNAKALL bmBIT7
|
||||
|
||||
/* Chip Feature Register (GPCR2) */
|
||||
#define bmFULLSPEEDONLY bmBIT4
|
||||
|
||||
#endif /* FX2REGS_H */
|
@ -0,0 +1,241 @@
|
||||
// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers
|
||||
//-----------------------------------------------------------------------------
|
||||
// File: fx2sdly.h
|
||||
// Contents: EZ-USB FX2 Synchronization Delay (SYNCDELAY) Macro
|
||||
//
|
||||
// Enter with _IFREQ = IFCLK in kHz
|
||||
// Enter with _CFREQ = CLKOUT in kHz
|
||||
//
|
||||
// Copyright (c) 2001 Cypress Semiconductor, All rights reserved
|
||||
//-----------------------------------------------------------------------------
|
||||
#define _nop_() do { _asm nop; _endasm; } while(0)
|
||||
|
||||
// Registers which require a synchronization delay, see section 15.14
|
||||
// FIFORESET FIFOPINPOLAR
|
||||
// INPKTEND OUTPKTEND
|
||||
// EPxBCH:L REVCTL
|
||||
// GPIFTCB3 GPIFTCB2
|
||||
// GPIFTCB1 GPIFTCB0
|
||||
// EPxFIFOPFH:L EPxAUTOINLENH:L
|
||||
// EPxFIFOCFG EPxGPIFFLGSEL
|
||||
// PINFLAGSxx EPxFIFOIRQ
|
||||
// EPxFIFOIE GPIFIRQ
|
||||
// GPIFIE GPIFADRH:L
|
||||
// UDMACRCH:L EPxGPIFTRIG
|
||||
// GPIFTRIG
|
||||
|
||||
// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
|
||||
// ...these have been replaced by GPIFTC[B3:B0] registers
|
||||
|
||||
// _IFREQ can be in the range of: 5000 to 48000
|
||||
#ifndef _IFREQ
|
||||
#define _IFREQ 48000 // IFCLK frequency in kHz
|
||||
#endif
|
||||
|
||||
// CFREQ can be any one of: 48000, 24000, or 12000
|
||||
#ifndef _CFREQ
|
||||
#define _CFREQ 48000 // CLKOUT frequency in kHz
|
||||
#endif
|
||||
|
||||
#if( _IFREQ < 5000 )
|
||||
#error "_IFREQ too small! Valid Range: 5000 to 48000..."
|
||||
#endif
|
||||
|
||||
#if( _IFREQ > 48000 )
|
||||
#error "_IFREQ too large! Valid Range: 5000 to 48000..."
|
||||
#endif
|
||||
|
||||
#if( _CFREQ != 48000 )
|
||||
#if( _CFREQ != 24000 )
|
||||
#if( _CFREQ != 12000 )
|
||||
#error "_CFREQ invalid! Valid values: 48000, 24000, 12000..."
|
||||
#endif
|
||||
#endif
|
||||
#endif
|
||||
|
||||
// Synchronization Delay formula: see TRM section 15-14
|
||||
#define _SCYCL ( 3*(_CFREQ) + 5*(_IFREQ) - 1 ) / ( 2*(_IFREQ) )
|
||||
|
||||
#if( _SCYCL == 1 )
|
||||
#define SYNCDELAY _nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 2 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 3 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 4 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 5 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 6 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 7 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 8 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 9 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 10 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 11 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 12 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 13 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 14 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 15 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
||||
|
||||
#if( _SCYCL == 16 )
|
||||
#define SYNCDELAY _nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( ); \
|
||||
_nop_( )
|
||||
#endif
|
@ -0,0 +1,212 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
#include <string.h>
|
||||
#include "fx2usb-interface.h"
|
||||
|
||||
usb_dev_handle *fx2usb_open(int vendor_id, int device_id, char *dev)
|
||||
{
|
||||
struct usb_bus *b;
|
||||
struct usb_device *d;
|
||||
char *dd = NULL;
|
||||
int devlen;
|
||||
|
||||
if (dev) {
|
||||
devlen = strlen(dev);
|
||||
dd = devlen > 8 ? &dev[devlen-8] : "|xxx|xxx";
|
||||
}
|
||||
|
||||
for (b = usb_get_busses(); b; b = b->next) {
|
||||
for (d = b->devices; d; d = d->next) {
|
||||
if (dd) {
|
||||
if (dd[0] == '/' && !strncmp(dd+1, b->dirname, 3) &&
|
||||
dd[4] == '/' && !strncmp(dd+5, d->filename, 3))
|
||||
return usb_open(d);
|
||||
} else
|
||||
if (vendor_id || device_id) {
|
||||
if ((d->descriptor.idVendor == vendor_id) && (d->descriptor.idProduct == device_id))
|
||||
return usb_open(d);
|
||||
} else {
|
||||
// The Xilinx Platform Cable USB Vendor/Device IDs
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x0009))
|
||||
return usb_open(d);
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x000D))
|
||||
return usb_open(d);
|
||||
if ((d->descriptor.idVendor == 0x03FD) && (d->descriptor.idProduct == 0x000F))
|
||||
return usb_open(d);
|
||||
// The plain CY7C68013 dev kit Vendor/Device IDs
|
||||
if ((d->descriptor.idVendor == 0x04b4) && (d->descriptor.idProduct == 0x8613))
|
||||
return usb_open(d);
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
return NULL;
|
||||
}
|
||||
|
||||
static int fx2usb_fwload_ctrl_msg(usb_dev_handle *dh, int addr, const void *data, int len)
|
||||
{
|
||||
int ret = usb_control_msg(dh, 0x40, 0xA0, addr, 0, (char*)data, len, 1000);
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_fwload_ctrl_msg: usb_control_msg for addr=0x%04X, len=%d returned %d: %s\n", addr, len, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
||||
int fx2usb_upload_ihex(usb_dev_handle *dh, FILE *fp)
|
||||
{
|
||||
uint8_t on = 1, off = 0;
|
||||
|
||||
// assert reset
|
||||
if (fx2usb_fwload_ctrl_msg(dh, 0xE600, &on, 1) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: can't assert reset!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
// parse and upload ihex file
|
||||
char line[1024];
|
||||
int linecount = 0;
|
||||
while (fgets(line, sizeof(line), fp) != NULL)
|
||||
{
|
||||
linecount++;
|
||||
|
||||
if (line[0] != ':')
|
||||
continue;
|
||||
|
||||
uint8_t cksum = 0;
|
||||
uint8_t ldata[512];
|
||||
int lsize = 0;
|
||||
|
||||
while (sscanf(line+1+lsize*2, "%2hhx", &ldata[lsize]) == 1) {
|
||||
cksum += ldata[lsize];
|
||||
lsize++;
|
||||
}
|
||||
|
||||
if (lsize < 5) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: record is to short!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (ldata[0] != lsize-5) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: size does not match record length!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
cksum -= ldata[lsize-1];
|
||||
cksum = ~cksum + 1;
|
||||
|
||||
if (cksum != ldata[lsize-1]) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: cksum error!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
|
||||
if (fx2usb_fwload_ctrl_msg(dh, (ldata[1] << 8) | ldata[2], &ldata[4], ldata[0]) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: ihex line %d: error in fx2usb communication!\n", linecount);
|
||||
return -1;
|
||||
}
|
||||
}
|
||||
|
||||
// release reset
|
||||
if (fx2usb_fwload_ctrl_msg(dh, 0xE600, &off, 1) < 0) {
|
||||
fprintf(stderr, "fx2usb_upload_ihex: can't release reset!\n");
|
||||
return -1;
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
int fx2usb_claim(usb_dev_handle *dh)
|
||||
{
|
||||
#ifdef LIBUSB_HAS_DETACH_KERNEL_DRIVER_NP
|
||||
usb_detach_kernel_driver_np(dh, 0);
|
||||
#endif
|
||||
if (usb_claim_interface(dh, 0) < 0) {
|
||||
fprintf(stderr, "fx2usb_claim: claiming interface 0 failed: %s!\n", usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
if (usb_set_altinterface(dh, 1) < 0) {
|
||||
usb_release_interface(dh, 0);
|
||||
fprintf(stderr, "fx2usb_claim: setting alternate interface 1 failed: %s!\n", usb_strerror());
|
||||
return -1;
|
||||
}
|
||||
return 0;
|
||||
}
|
||||
|
||||
void fx2usb_release(usb_dev_handle *dh)
|
||||
{
|
||||
usb_release_interface(dh, 0);
|
||||
}
|
||||
|
||||
void fx2usb_flush(usb_dev_handle *dh)
|
||||
{
|
||||
while (1)
|
||||
{
|
||||
unsigned char readbuf[2] = { 0, 0 };
|
||||
int ret = usb_bulk_read(dh, 1, (char*)readbuf, 2, 10);
|
||||
if (ret <= 0)
|
||||
return;
|
||||
fprintf(stderr, "Unexpected data word from device: 0x%02x 0x%02x (%d)\n", readbuf[0], readbuf[1], ret);
|
||||
}
|
||||
}
|
||||
|
||||
int fx2usb_send_chunk(usb_dev_handle *dh, int ep, const void *data, int len)
|
||||
{
|
||||
int ret;
|
||||
#if 0
|
||||
if (ep == 2) {
|
||||
int i;
|
||||
fprintf(stderr, "<ep2:%4d bytes> ...", len);
|
||||
for (i = len-16; i < len; i++) {
|
||||
if (i < 0)
|
||||
continue;
|
||||
fprintf(stderr, " %02x", ((unsigned char*)data)[i]);
|
||||
}
|
||||
fprintf(stderr, "\n");
|
||||
}
|
||||
#endif
|
||||
retry_write:
|
||||
ret = usb_bulk_write(dh, ep, data, len, 1000);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
fprintf(stderr, "fx2usb_recv_chunk: usb write timeout -> retry\n");
|
||||
fx2usb_flush(dh);
|
||||
goto retry_write;
|
||||
}
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_send_chunk: write of %d bytes to ep %d returned %d: %s\n", len, ep, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
||||
int fx2usb_recv_chunk(usb_dev_handle *dh, int ep, void *data, int len, int *ret_len)
|
||||
{
|
||||
int ret;
|
||||
retry_read:
|
||||
ret = usb_bulk_read(dh, ep, data, len, 1000);
|
||||
if (ret == -ETIMEDOUT) {
|
||||
fprintf(stderr, "fx2usb_recv_chunk: usb read timeout -> retry\n");
|
||||
goto retry_read;
|
||||
}
|
||||
if (ret > 0 && ret_len != NULL)
|
||||
len = *ret_len = ret;
|
||||
if (ret != len)
|
||||
fprintf(stderr, "fx2usb_recv_chunk: read of %d bytes from ep %d returned %d: %s\n", len, ep, ret, ret >= 0 ? "NO ERROR" : usb_strerror());
|
||||
return ret == len ? 0 : -1;
|
||||
}
|
||||
|
@ -0,0 +1,37 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#ifndef FX2USB_INTERFACE_H
|
||||
#define FX2USB_INTERFACE_H
|
||||
|
||||
#include <usb.h>
|
||||
#include <stdio.h>
|
||||
|
||||
usb_dev_handle *fx2usb_open(int vendor_id, int device_id, char *dev);
|
||||
int fx2usb_upload_ihex(usb_dev_handle *dh, FILE *fp);
|
||||
int fx2usb_claim(usb_dev_handle *dh);
|
||||
void fx2usb_release(usb_dev_handle *dh);
|
||||
|
||||
void fx2usb_flush(usb_dev_handle *dh);
|
||||
int fx2usb_send_chunk(usb_dev_handle *dh, int ep, const void *data, int len);
|
||||
int fx2usb_recv_chunk(usb_dev_handle *dh, int ep, void *data, int len, int *ret_len);
|
||||
|
||||
#endif /* FX2USB_INTERFACE_H */
|
||||
|
@ -0,0 +1,45 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
ORIG_HDR_DIR="$HOME/.wine/drive_c/Cypress/USB/Target/Inc/"
|
||||
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed -r '
|
||||
# OLD: EXTERN xdata volatile BYTE CPUCS _AT_ 0xE600;
|
||||
# NEW: xdata at 0xE600 volatile BYTE CPUCS;
|
||||
s/^EXTERN xdata volatile BYTE ([^ ]+)( +)_AT_ +([^ ;]+);/xdata at \3 volatile BYTE \1;\2/;
|
||||
|
||||
# OLD: sfr IOA = 0x80;
|
||||
# NEW: sfr at 0x80 IOA;
|
||||
s/^sfr ([^ ]+)( +)= ([^ ;]+);/sfr at \3 \1;\2/;
|
||||
|
||||
# OLD: sbit PA0 = 0x80 + 0;
|
||||
# NEW: sbit at (0x80 + 0) IOA;
|
||||
s/^( *)sbit ([^ ]+)( +)= ([^;]+);/\1sbit at (\4) \2;\3/;
|
||||
' < "$ORIG_HDR_DIR/fx2regs.h"; } > fx2regs.h
|
||||
|
||||
# hotfix line ending in Fx2.h
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed -r 's,\\ *,\\,;' < "$ORIG_HDR_DIR/Fx2.h"; } > fx2.h
|
||||
|
||||
# we do not have intrins.h but it seams quite clear what _nop_() does..
|
||||
{ echo "// **** Auto-generated using genfx2hrd.sh from CY3684 EZ USB FX2LP Development Kit headers"
|
||||
sed 's,^#include "intrins.h",#define _nop_() do { _asm nop; _endasm; } while(0),' < "$ORIG_HDR_DIR/fx2sdly.h"; } > fx2sdly.h
|
||||
|
@ -0,0 +1,292 @@
|
||||
// This program configures the General Programmable Interface (GPIF) for FX2.
|
||||
// Please do not modify sections of text which are marked as "DO NOT EDIT ...".
|
||||
//
|
||||
// DO NOT EDIT ...
|
||||
// GPIF Initialization
|
||||
// Interface Timing Sync
|
||||
// Internal Ready Init IntRdy=1
|
||||
// CTL Out Tristate-able Binary
|
||||
// SingleWrite WF Select 1
|
||||
// SingleRead WF Select 0
|
||||
// FifoWrite WF Select 3
|
||||
// FifoRead WF Select 2
|
||||
// Data Bus Idle Drive Tristate
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
// GPIF Wave Names
|
||||
// Wave 0 = Single R
|
||||
// Wave 1 = Single W
|
||||
// Wave 2 = FIFO Slo
|
||||
// Wave 3 = FIFO Wri
|
||||
|
||||
// GPIF Ctrl Outputs Level
|
||||
// CTL 0 = CTL0 CMOS
|
||||
// CTL 1 = CTL1 CMOS
|
||||
// CTL 2 = CTL2 CMOS
|
||||
// CTL 3 = CTL3 CMOS
|
||||
// CTL 4 = CTL4 CMOS
|
||||
// CTL 5 = CTL5 CMOS
|
||||
|
||||
// GPIF Rdy Inputs
|
||||
// RDY0 = RDY0
|
||||
// RDY1 = RDY1
|
||||
// RDY2 = RDY2
|
||||
// RDY3 = RDY3
|
||||
// RDY4 = RDY4
|
||||
// RDY5 = TCXpire
|
||||
// FIFOFlag = FIFOFlag
|
||||
// IntReady = IntReady
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 0: Single R
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode NO Data NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData SameData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1 Wait 1
|
||||
// Term A
|
||||
// LFunc
|
||||
// Term B
|
||||
// Branch1
|
||||
// Branch0
|
||||
// Re-Exec
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 1 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 1 1 1 1 1 1
|
||||
// CTL2 1 1 1 1 1 1 1 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 1: Single W
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode Activate NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData NextData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 Wait 1 IF Wait 1 Wait 1
|
||||
// Term A FIFOFlag
|
||||
// LFunc AND
|
||||
// Term B FIFOFlag
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 ElseIdle
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 0 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 0 1 1 1 1 1
|
||||
// CTL2 1 0 1 0 1 1 1 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 2: FIFO Slo
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode NO Data Activate NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData SameData NextData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 254 Wait 1 Wait 254 IF Wait 1 Wait 1 Wait 1
|
||||
// Term A TCXpire
|
||||
// LFunc AND
|
||||
// Term B TCXpire
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 Else 0
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 1 0 1 1 1 1 1 1
|
||||
// CTL1 1 1 1 1 1 1 1 1
|
||||
// CTL2 1 1 1 0 0 0 0 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
// DO NOT EDIT ...
|
||||
//
|
||||
// GPIF Waveform 3: FIFO Wri
|
||||
//
|
||||
// Interval 0 1 2 3 4 5 6 Idle (7)
|
||||
// _________ _________ _________ _________ _________ _________ _________ _________
|
||||
//
|
||||
// AddrMode Same Val Same Val Same Val Same Val Same Val Same Val Same Val
|
||||
// DataMode Activate NO Data NO Data NO Data NO Data NO Data NO Data
|
||||
// NextData SameData NextData SameData SameData SameData SameData SameData
|
||||
// Int Trig No Int No Int No Int No Int No Int No Int No Int
|
||||
// IF/Wait Wait 1 Wait 1 Wait 1 IF Wait 1 Wait 1 Wait 1
|
||||
// Term A TCXpire
|
||||
// LFunc AND
|
||||
// Term B TCXpire
|
||||
// Branch1 ThenIdle
|
||||
// Branch0 Else 0
|
||||
// Re-Exec No
|
||||
// Sngl/CRC Default Default Default Default Default Default Default
|
||||
// CTL0 0 1 1 1 1 1 1 1
|
||||
// CTL1 1 1 0 1 1 1 1 1
|
||||
// CTL2 1 0 1 0 0 0 0 1
|
||||
// CTL3 0 0 0 0 0 0 0 0
|
||||
// CTL4 0 0 0 0 0 0 0 0
|
||||
// CTL5 0 0 0 0 0 0 0 0
|
||||
//
|
||||
// END DO NOT EDIT
|
||||
|
||||
// GPIF Program Code
|
||||
|
||||
// DO NOT EDIT ...
|
||||
#include "fx2.h"
|
||||
#include "fx2regs.h"
|
||||
#include "fx2sdly.h" // SYNCDELAY macro
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata WaveData[128] =
|
||||
{
|
||||
// Wave 0
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x00, 0x3F,
|
||||
// Wave 1
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x01, 0x3F, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x02, 0x04, 0x00, 0x00, 0x01, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x06, 0x03, 0x05, 0x03, 0x07, 0x07, 0x07, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x00, 0x36, 0x00, 0x00, 0x3F,
|
||||
// Wave 2
|
||||
/* LenBr */ 0xFE, 0x01, 0xFE, 0x38, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x00, 0x02, 0x04, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x07, 0x06, 0x07, 0x03, 0x03, 0x03, 0x03, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
|
||||
// Wave 3
|
||||
/* LenBr */ 0x01, 0x01, 0x01, 0x38, 0x01, 0x01, 0x01, 0x07,
|
||||
/* Opcode*/ 0x02, 0x04, 0x00, 0x01, 0x00, 0x00, 0x00, 0x00,
|
||||
/* Output*/ 0x06, 0x03, 0x05, 0x03, 0x03, 0x03, 0x03, 0x07,
|
||||
/* LFun */ 0x00, 0x00, 0x00, 0x2D, 0x00, 0x00, 0x00, 0x3F,
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata FlowStates[36] =
|
||||
{
|
||||
/* Wave 0 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 1 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 2 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
/* Wave 3 FlowStates */ 0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,0x00,
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// DO NOT EDIT ...
|
||||
const char xdata InitData[7] =
|
||||
{
|
||||
/* Regs */ 0xE0,0x00,0x00,0x07,0xEA,0x4E,0x00
|
||||
};
|
||||
// END DO NOT EDIT
|
||||
|
||||
// TO DO: You may add additional code below.
|
||||
|
||||
void GpifInit( void )
|
||||
{
|
||||
BYTE i;
|
||||
|
||||
// Registers which require a synchronization delay, see section 15.14
|
||||
// FIFORESET FIFOPINPOLAR
|
||||
// INPKTEND OUTPKTEND
|
||||
// EPxBCH:L REVCTL
|
||||
// GPIFTCB3 GPIFTCB2
|
||||
// GPIFTCB1 GPIFTCB0
|
||||
// EPxFIFOPFH:L EPxAUTOINLENH:L
|
||||
// EPxFIFOCFG EPxGPIFFLGSEL
|
||||
// PINFLAGSxx EPxFIFOIRQ
|
||||
// EPxFIFOIE GPIFIRQ
|
||||
// GPIFIE GPIFADRH:L
|
||||
// UDMACRCH:L EPxGPIFTRIG
|
||||
// GPIFTRIG
|
||||
|
||||
// Note: The pre-REVE EPxGPIFTCH/L register are affected, as well...
|
||||
// ...these have been replaced by GPIFTC[B3:B0] registers
|
||||
|
||||
// 8051 doesn't have access to waveform memories 'til
|
||||
// the part is in GPIF mode.
|
||||
|
||||
IFCONFIG = 0xEA;
|
||||
// IFCLKSRC=1 , FIFOs executes on internal clk source
|
||||
// xMHz=1 , 48MHz internal clk rate
|
||||
// IFCLKOE=0 , Don't drive IFCLK pin signal at 48MHz
|
||||
// IFCLKPOL=0 , Don't invert IFCLK pin signal from internal clk
|
||||
// ASYNC=1 , master samples asynchronous
|
||||
// GSTATE=1 , Drive GPIF states out on PORTE[2:0], debug WF
|
||||
// IFCFG[1:0]=10, FX2 in GPIF master mode
|
||||
|
||||
GPIFABORT = 0xFF; // abort any waveforms pending
|
||||
|
||||
GPIFREADYCFG = InitData[ 0 ];
|
||||
GPIFCTLCFG = InitData[ 1 ];
|
||||
GPIFIDLECS = InitData[ 2 ];
|
||||
GPIFIDLECTL = InitData[ 3 ];
|
||||
GPIFWFSELECT = InitData[ 5 ];
|
||||
GPIFREADYSTAT = InitData[ 6 ];
|
||||
|
||||
// use dual autopointer feature...
|
||||
AUTOPTRSETUP = 0x07; // inc both pointers,
|
||||
// ...warning: this introduces pdata hole(s)
|
||||
// ...at E67B (XAUTODAT1) and E67C (XAUTODAT2)
|
||||
|
||||
// source
|
||||
AUTOPTRH1 = MSB( &WaveData );
|
||||
AUTOPTRL1 = LSB( &WaveData );
|
||||
|
||||
// destination
|
||||
AUTOPTRH2 = 0xE4;
|
||||
AUTOPTRL2 = 0x00;
|
||||
|
||||
// transfer
|
||||
for ( i = 0x00; i < 128; i++ )
|
||||
{
|
||||
EXTAUTODAT2 = EXTAUTODAT1;
|
||||
}
|
||||
|
||||
// Configure GPIF Address pins, output initial value,
|
||||
PORTCCFG = 0xFF; // [7:0] as alt. func. GPIFADR[7:0]
|
||||
OEC = 0xFF; // and as outputs
|
||||
PORTECFG |= 0x80; // [8] as alt. func. GPIFADR[8]
|
||||
OEE |= 0x80; // and as output
|
||||
|
||||
// ...OR... tri-state GPIFADR[8:0] pins
|
||||
// PORTCCFG = 0x00; // [7:0] as port I/O
|
||||
// OEC = 0x00; // and as inputs
|
||||
// PORTECFG &= 0x7F; // [8] as port I/O
|
||||
// OEE &= 0x7F; // and as input
|
||||
|
||||
// GPIF address pins update when GPIFADRH/L written
|
||||
SYNCDELAY; //
|
||||
GPIFADRH = 0x00; // bits[7:1] always 0
|
||||
SYNCDELAY; //
|
||||
GPIFADRL = 0x00; // point to PERIPHERAL address 0x0000
|
||||
|
||||
// Configure GPIF FlowStates registers for Wave 0 of WaveData
|
||||
FLOWSTATE = FlowStates[ 0 ];
|
||||
FLOWLOGIC = FlowStates[ 1 ];
|
||||
FLOWEQ0CTL = FlowStates[ 2 ];
|
||||
FLOWEQ1CTL = FlowStates[ 3 ];
|
||||
FLOWHOLDOFF = FlowStates[ 4 ];
|
||||
FLOWSTB = FlowStates[ 5 ];
|
||||
FLOWSTBEDGE = FlowStates[ 6 ];
|
||||
FLOWSTBHPERIOD = FlowStates[ 7 ];
|
||||
}
|
||||
|
@ -0,0 +1,100 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
. /opt/Xilinx/13.1/ISE_DS/settings32.sh
|
||||
|
||||
cat > hardware.prj <<- EOT
|
||||
verilog work "hardware.v"
|
||||
EOT
|
||||
|
||||
cat > hardware.lso <<- EOT
|
||||
work
|
||||
EOT
|
||||
|
||||
cat > hardware.xst <<- EOT
|
||||
set -tmpdir "xilinx/projnav.tmp"
|
||||
set -xsthdpdir "xilinx"
|
||||
run
|
||||
-ifn hardware.prj
|
||||
-ifmt mixed
|
||||
-ofn hardware
|
||||
-ofmt NGC
|
||||
-p xbr
|
||||
-top top
|
||||
-opt_mode Speed
|
||||
-opt_level 1
|
||||
-iuc NO
|
||||
-lso hardware.lso
|
||||
-keep_hierarchy YES
|
||||
-netlist_hierarchy as_optimized
|
||||
-rtlview Yes
|
||||
-hierarchy_separator /
|
||||
-bus_delimiter <>
|
||||
-case maintain
|
||||
-verilog2001 YES
|
||||
-fsm_extract YES -fsm_encoding Auto
|
||||
-safe_implementation No
|
||||
-mux_extract YES
|
||||
-resource_sharing YES
|
||||
-iobuf YES
|
||||
-pld_mp YES
|
||||
-pld_xp YES
|
||||
-pld_ce YES
|
||||
-wysiwyg NO
|
||||
-equivalent_register_removal YES
|
||||
EOT
|
||||
|
||||
cat > hardware.cmd <<- EOT
|
||||
setMode -bs
|
||||
setCable -port svf -file "hardware.svf"
|
||||
addDevice -p 1 -file "hardware.jed"
|
||||
Erase -p 1
|
||||
Program -p 1 -e -v
|
||||
Verify -p 1
|
||||
quit
|
||||
EOT
|
||||
|
||||
cat > erasecpld.cmd <<- EOT
|
||||
setMode -bs
|
||||
setCable -port svf -file "erasecpld.svf"
|
||||
addDevice -p 1 -file "hardware.jed"
|
||||
Erase -p 1
|
||||
quit
|
||||
EOT
|
||||
|
||||
set -ex
|
||||
|
||||
mkdir -p xilinx/projnav.tmp/
|
||||
xst -ifn "hardware.xst" -ofn "hardware.syr"
|
||||
|
||||
mkdir -p xilinx/_ngo/
|
||||
ngdbuild -dd xilinx/_ngo -uc hardware.ucf -p xc2c256-VQ100-6 hardware.ngc hardware.ngd
|
||||
|
||||
cpldfit -p xc2c256-7-VQ100 -ofmt verilog -optimize density -htmlrpt -loc on -slew fast -init low \
|
||||
-inputs 32 -pterms 28 -unused keeper -terminate keeper -iostd LVCMOS18 hardware.ngd
|
||||
|
||||
hprep6 -i hardware
|
||||
|
||||
impact -batch hardware.cmd
|
||||
sed -i '\,^// Date:, d;' hardware.svf
|
||||
|
||||
impact -batch erasecpld.cmd
|
||||
sed -i '\,^// Date:, d;' erasecpld.svf
|
||||
|
@ -0,0 +1,59 @@
|
||||
#
|
||||
# xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
#
|
||||
# Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
# Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
#
|
||||
# Permission to use, copy, modify, and/or distribute this software for any
|
||||
# purpose with or without fee is hereby granted, provided that the above
|
||||
# copyright notice and this permission notice appear in all copies.
|
||||
#
|
||||
# THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
# WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
# MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
# ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
# WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
# ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
# OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
#
|
||||
|
||||
NET "clk" LOC = "23" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "tck" LOC = "66" | IOSTANDARD = LVCMOS33;
|
||||
NET "tms" LOC = "67" | IOSTANDARD = LVCMOS33;
|
||||
NET "tdi" LOC = "68" | IOSTANDARD = LVCMOS33;
|
||||
NET "tdo" LOC = "27" | IOSTANDARD = LVCMOS33;
|
||||
NET "init" LOC = "28" | IOSTANDARD = LVCMOS33;
|
||||
NET "init_b" LOC = "70" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "fd0" LOC = "32" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd1" LOC = "33" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd2" LOC = "34" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd3" LOC = "35" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd4" LOC = "36" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd5" LOC = "37" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd6" LOC = "39" | IOSTANDARD = LVCMOS33;
|
||||
NET "fd7" LOC = "40" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "ctl0" LOC = "22" | IOSTANDARD = LVCMOS33;
|
||||
NET "ctl1" LOC = "53" | IOSTANDARD = LVCMOS33;
|
||||
NET "ctl2" LOC = "54" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "pc0" LOC = "14" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc1" LOC = "15" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc2" LOC = "16" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc3" LOC = "17" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc4" LOC = "18" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc5" LOC = "19" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc6" LOC = "29" | IOSTANDARD = LVCMOS33;
|
||||
NET "pc7" LOC = "30" | IOSTANDARD = LVCMOS33;
|
||||
|
||||
NET "pd0" LOC = "41" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd1" LOC = "42" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd2" LOC = "43" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd3" LOC = "44" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd4" LOC = "46" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd5" LOC = "49" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd6" LOC = "50" | IOSTANDARD = LVCMOS33;
|
||||
NET "pd7" LOC = "52" | IOSTANDARD = LVCMOS33;
|
||||
|
@ -0,0 +1,141 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
module top(
|
||||
clk,
|
||||
tck, tms, tdi, tdo, init, init_b,
|
||||
fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7,
|
||||
ctl0, ctl1, ctl2,
|
||||
pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7,
|
||||
pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7
|
||||
);
|
||||
|
||||
// General Signal
|
||||
input clk;
|
||||
|
||||
// JTAG Interface
|
||||
output tck, tms, tdi, init;
|
||||
input tdo, init_b;
|
||||
|
||||
// GPIF Interface
|
||||
input fd0, fd1, fd2, fd3, fd4, fd5, fd6, fd7;
|
||||
input ctl0, ctl1, ctl2;
|
||||
|
||||
// The entire PC and PD regs for various flags
|
||||
output pc0, pc1, pc2, pc3, pc4, pc5, pc6, pc7;
|
||||
input pd0, pd1, pd2, pd3, pd4, pd5, pd6, pd7;
|
||||
|
||||
// simple direct i/o mappings
|
||||
assign pc3 = tdo;
|
||||
assign pc1 = init_b;
|
||||
assign init = pd2;
|
||||
|
||||
// checksum
|
||||
wire chksum_rst, chksum_clk;
|
||||
reg [23:0] chksum_buffer;
|
||||
always @(posedge chksum_clk) begin
|
||||
if (chksum_rst)
|
||||
chksum_buffer <=
|
||||
`include "hardware_cksum_vl.inc"
|
||||
;
|
||||
else
|
||||
chksum_buffer <= chksum_buffer << 1;
|
||||
end
|
||||
assign chksum_rst = pd0;
|
||||
assign chksum_clk = pd1;
|
||||
assign pc2 = chksum_buffer[23];
|
||||
|
||||
// main engine
|
||||
reg [3:0] sync;
|
||||
reg [7:0] lastbyte;
|
||||
reg go_exec0, go_exec1, set_sync, err;
|
||||
reg reg_tck, reg_tms, reg_tdi, reg_tdo, reg_tdo_en;
|
||||
always @(negedge clk) begin
|
||||
go_exec0 <= 0;
|
||||
go_exec1 <= 0;
|
||||
if (!ctl0) begin
|
||||
lastbyte <= { fd7, fd6, fd5, fd4, fd3, fd2, fd1, fd0 };
|
||||
go_exec0 <= 1;
|
||||
end
|
||||
if (!ctl1) begin
|
||||
lastbyte <= lastbyte >> 4;
|
||||
go_exec0 <= 1;
|
||||
end
|
||||
if (!ctl2) begin
|
||||
go_exec1 <= 1;
|
||||
end
|
||||
if (go_exec0) begin
|
||||
reg_tdo_en <= 0;
|
||||
if (set_sync) begin
|
||||
sync <= lastbyte[3:0];
|
||||
set_sync <= 0;
|
||||
end else
|
||||
if (lastbyte[3:0] == 0) begin
|
||||
/* NOP */
|
||||
end else
|
||||
if (lastbyte[3:0] == 1) begin
|
||||
/* Set sync signal in next insn */
|
||||
set_sync <= 1;
|
||||
end else
|
||||
if (lastbyte[3:1] == 1) begin
|
||||
/* reserved */
|
||||
end else
|
||||
if (lastbyte[3:2] == 1) begin
|
||||
/* transaction with or without TDO check */
|
||||
reg_tck <= 0;
|
||||
reg_tdo <= 'bx;
|
||||
reg_tms <= lastbyte[1];
|
||||
reg_tdi <= lastbyte[0];
|
||||
end else
|
||||
if (lastbyte[3] == 1) begin
|
||||
/* transaction with TDO check */
|
||||
reg_tck <= 0;
|
||||
reg_tdo <= lastbyte[2];
|
||||
reg_tms <= lastbyte[1];
|
||||
reg_tdi <= lastbyte[0];
|
||||
reg_tdo_en <= 1;
|
||||
end
|
||||
end
|
||||
if (go_exec1) begin
|
||||
reg_tck <= 1;
|
||||
if (reg_tdo_en && tdo != reg_tdo)
|
||||
err <= 1;
|
||||
end
|
||||
if (pd3) begin
|
||||
/* RESET ERR */
|
||||
err <= 0;
|
||||
end
|
||||
if (pd4) begin
|
||||
/* RESET SYNC */
|
||||
set_sync <= 0;
|
||||
sync <= 0;
|
||||
end
|
||||
end
|
||||
assign tck = reg_tck;
|
||||
assign tms = reg_tms;
|
||||
assign tdi = reg_tdi;
|
||||
assign pc7 = sync[3];
|
||||
assign pc6 = sync[2];
|
||||
assign pc5 = sync[1];
|
||||
assign pc4 = sync[0];
|
||||
assign pc0 = err;
|
||||
|
||||
endmodule
|
||||
|
@ -0,0 +1,82 @@
|
||||
// Created using Xilinx Cse Software [ISE - 13.1]
|
||||
|
||||
TRST OFF;
|
||||
ENDIR IDLE;
|
||||
ENDDR IDLE;
|
||||
STATE RESET;
|
||||
STATE IDLE;
|
||||
FREQUENCY 1E6 HZ;
|
||||
//Operation: Erase -p 0
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (01) SMASK (ff) ;
|
||||
SDR 32 TDI (00000000) SMASK (ffffffff) TDO (f6d4f093) MASK (0fff8fff) ;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (03) ;
|
||||
//Boundary Scan Chain Contents
|
||||
//Position 1: xc2c256
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
//Loading device with 'idcode' instruction.
|
||||
SIR 8 TDI (01) ;
|
||||
SDR 32 TDI (00000000) TDO (f6d4f093) ;
|
||||
//Check for Read/Write Protect.
|
||||
SIR 8 TDI (ff) TDO (01) MASK (03) ;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
HDR 0 ;
|
||||
TDR 0 ;
|
||||
// Loading devices with 'enable' or 'bypass' instruction.
|
||||
SIR 8 TDI (e8) ;
|
||||
RUNTEST 200 TCK;
|
||||
// Loading devices with 'erase' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (ed) SMASK (ff) ;
|
||||
ENDIR IDLE;
|
||||
STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRPAUSE;
|
||||
RUNTEST DRPAUSE 20 TCK;
|
||||
STATE IDLE;
|
||||
RUNTEST IDLE 100000 TCK;
|
||||
STATE DRPAUSE;
|
||||
RUNTEST DRPAUSE 5000 TCK;
|
||||
RUNTEST IDLE 1 TCK;
|
||||
// Loading devices with 'init' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (f0) SMASK (ff) ;
|
||||
STATE IDLE;
|
||||
RUNTEST IDLE 20 TCK;
|
||||
// Loading devices with 'init' or 'bypass' instruction.
|
||||
ENDIR IRPAUSE;
|
||||
SIR 8 TDI (f0) SMASK (ff) ;
|
||||
STATE IREXIT2 IRUPDATE DRSELECT DRCAPTURE DREXIT1 DRUPDATE IDLE;
|
||||
RUNTEST 800 TCK;
|
||||
ENDIR IDLE;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (c0) ;
|
||||
RUNTEST 100 TCK;
|
||||
// Loading devices with 'conld' or 'bypass' instruction.
|
||||
SIR 8 TDI (c0) ;
|
||||
RUNTEST 100 TCK;
|
||||
TIR 0 ;
|
||||
HIR 0 ;
|
||||
TDR 0 ;
|
||||
HDR 0 ;
|
||||
SIR 8 TDI (ff) ;
|
||||
SDR 1 TDI (00) SMASK (01) ;
|
@ -0,0 +1,323 @@
|
||||
:03000000020008F3
|
||||
:0300610002000397
|
||||
:05000300120B4A80FE13
|
||||
:0D00640090E60174EAF090E6F574FFF0906C
|
||||
:0E0071000C58E49390E6F3F0900C59E4939051
|
||||
:0D007F00E6C3F0900C5AE49390E6C1F090B7
|
||||
:0E008C000C5BE49390E6C2F0900C5DE4939060
|
||||
:0E009A00E6C0F0900C5EE49390E6F4F075AFD3
|
||||
:0800A800077AB47B0B8B9A7AF6
|
||||
:0A00B000B47B0B7B008A9B759DE476
|
||||
:0500BA00759E007A00B4
|
||||
:0300BF00BA800004
|
||||
:0E00C200500C90E67BE0FB90E67CF00A80EFAD
|
||||
:0E00D00090E67174FFF075B4FF90E672E0FAEE
|
||||
:0E00DE004480F043B68000000090E6C4E4F0D9
|
||||
:0E00EC0000000090E6C5E4F0900C34E4939020
|
||||
:0D00FA00E6C6F0900C35E49390E6C7F09058
|
||||
:0E0107000C36E49390E6C8F0900C37E4939029
|
||||
:0D011500E6C9F0900C38E49390E6CAF09033
|
||||
:0E0122000C39E49390E6CBF0900C3AE4939005
|
||||
:0D013000E6CCF0900C3BE49390E6CDF0227D
|
||||
:0E013D000000000000000000000000000000B4
|
||||
:0B014B00000000000000000000002287
|
||||
:04015600AA82AB834B
|
||||
:09015A008A048B051ABAFF011B8F
|
||||
:08016300EC4D60297C007D00D9
|
||||
:0E016B00C3EC94E8ED940350E6C002C003C05C
|
||||
:0E01790004C00512013DD005D004D003D00211
|
||||
:0901870074032CFCE43DFD80DB57
|
||||
:01019000224C
|
||||
:0D01910090E6007410F090E61274A8F09053
|
||||
:0D019E00E613E4F090E614F090E615F09002
|
||||
:0E01AB00E6047480F000000090E6047402F098
|
||||
:0D01B90000000090E6047404F000000090C7
|
||||
:0E01C600E6047406F000000090E6047408F0F1
|
||||
:0E01D40000000090E604E4F000000090E61841
|
||||
:0E01E200E0FA54FEF000000090E619E0FA5436
|
||||
:0E01F000FEF000000090E61AE0FA54FEF00067
|
||||
:0E01FE00000090E61BE0FA54FEF00000001234
|
||||
:0E020C00006490E670E4F075B22B75800090EF
|
||||
:0E021A00E671E4F075B40075A00075B51F75AF
|
||||
:0E022800B000D28390006412015675B658756E
|
||||
:04023600B1587A0041
|
||||
:03023A00BA1000F7
|
||||
:0E023D005013C00212013D53B1F712013DD023
|
||||
:07024B000243B1080A80E83C
|
||||
:010252002289
|
||||
:0E025300C28390006412015690E6F574FFF02D
|
||||
:0D02610000000090E6007402F00000009024
|
||||
:0E026E00E6017480F000000090E61274A2F029
|
||||
:0D027C0000000090E61374A0F00000009058
|
||||
:0E028900E61474A2F000000090E61574A0F0D8
|
||||
:0D02970000000090E6187405F000000090D3
|
||||
:0E02A400E6197405F000000090E61A7405F0EB
|
||||
:0D02B20000000090E61B7405F000000090B5
|
||||
:0E02BF00E6047480F000000090E6047402F083
|
||||
:0D02CD0000000090E6047404F000000090B2
|
||||
:0E02DA00E6047406F000000090E6047408F0DC
|
||||
:0E02E80000000090E604E4F0000000758000C5
|
||||
:0E02F60075A00075B00075B10075B20075B44A
|
||||
:0D0304000075B50075B60090E670E4F0904D
|
||||
:0A031100E671F075B2017A007B007E
|
||||
:0E031B00C3EA9403EB9400504BD2807CB87D73
|
||||
:010329000BC8
|
||||
:0E032A00C002C003C004C00512013DD005D0C2
|
||||
:0A03380004D003D0021CBCFF011D1D
|
||||
:0A034200EC4D70E4C2817CB87D0B25
|
||||
:0E034C00C002C003C004C00512013DD005D0A0
|
||||
:0A035A0004D003D0021CBCFF011DFB
|
||||
:0B036400EC4D70E40ABA00AF0B80AC57
|
||||
:03036F0075B20064
|
||||
:0E03720090E6A1E0FA20E10990E68D74FFF01C
|
||||
:030380000000007A
|
||||
:0E03830090E6A3E0FA20E2E790E69174FFF026
|
||||
:0503910000000080DC0B
|
||||
:0C039600AA82740F5A900C5F93F582222B
|
||||
:0503A200AA82BA300040
|
||||
:0D03A700400BEA24C64006EA24D0F582226D
|
||||
:0303B400BA61002B
|
||||
:0D03B700400BEA2499400674A92AF5822221
|
||||
:0303C400BA41003B
|
||||
:0D03C700400BEA24B9400674C92AF58222D1
|
||||
:0403D400758200220C
|
||||
:0E03D800E582FA700B90E6C0744EF000000053
|
||||
:0203E60080197C
|
||||
:0E03E80090E6C0744AF000000090E440EAF095
|
||||
:0B03F60000000090E442EAF00000006C
|
||||
:0E04010090E7C0744FF000000090E7C1744B0C
|
||||
:0E040F00F000000090E7C27420F000000090A2
|
||||
:0E041D00E7C37428F000000090E7C47454F0A8
|
||||
:0E042B00000000EAC4540FFB740F5BF582C0A2
|
||||
:0E04390002120396AB82D00290E7C5EBF000F2
|
||||
:0D0447000000740F5AF582120396AA8290ED
|
||||
:0E045400E7C6EAF000000090E7C77429F00048
|
||||
:0C046200000090E68F7408F000000022FB
|
||||
:05046E0075B1587A0091
|
||||
:03047300BA1000BC
|
||||
:0E0476005013C00212013D53B1F712013DD0E8
|
||||
:070484000243B1080A80E801
|
||||
:0C048B0090E6C0744EF000000075080000
|
||||
:0E049700C285C281C28075B01900000043B05A
|
||||
:0904A5000200000075B0007A00AD
|
||||
:0A04AE00EA2470FBE4340CFC7D80AE
|
||||
:0E04B8008B828C838DF0120B94FB6012EA2471
|
||||
:0E04C600C0F582E434E7F583EBF00000000A95
|
||||
:0204D40080D8CE
|
||||
:0904D60090E68FEAF0000000221C
|
||||
:0E04DF00AA8290E7C0744FF000000090E7C1C1
|
||||
:0E04ED00744BF000000090E7C27420F0000095
|
||||
:0E04FB000090E7C37428F000000090E7C4747E
|
||||
:0D05090057F00000008A82120396AA82902B
|
||||
:0E051600E7C5EAF000000090E7C67429F00087
|
||||
:0C052400000090E68F7407F00000002239
|
||||
:0E053000AA8290E7C07454F000000090E7C16A
|
||||
:0E053E007449F000000090E7C2744DF0000018
|
||||
:0E054C000090E7C37445F000000090E7C4740F
|
||||
:0E055A004FF000000090E7C57455F00000005F
|
||||
:0E05680090E7C67454F000000090E7C77421BD
|
||||
:0E057600F000000090E7C87420F00000009034
|
||||
:0E058400E7C97453F000000090E7CA743DF020
|
||||
:0D059200000000E5A0C4540FF582C0021265
|
||||
:0E059F000396AB82D00290E7CBEBF000000099
|
||||
:0E05AD0090E7CC7420F000000090E7CD742899
|
||||
:0E05BB00F000000090E7CE7457F00000008AB8
|
||||
:0E05C90082120396AA8290E7CFEAF0000000AB
|
||||
:0E05D70090E7D07429F000000090E68F7411B8
|
||||
:0505E500F000000022FF
|
||||
:0605EA00AA827B007C00E8
|
||||
:0D05F000C3EB94E8EC9403504C7D007E00BA
|
||||
:0E05FD00C3ED94E8EE94035038E5A0C4540F0B
|
||||
:09060B00FFB502058A820204DF3A
|
||||
:0E06140090E6A3E0FF20E21BD280C002C003EC
|
||||
:0E062200C004C005C006120B08D006D005D0DB
|
||||
:0706300004D003D002C280D8
|
||||
:070637000DBD00C20E80BFE3
|
||||
:07063E000BBB00AE0C80AB0A
|
||||
:050645008A820205306D
|
||||
:0E064A00D2B0C2B1000000D2B1000000C2B0B8
|
||||
:04065800C2B17A00B1
|
||||
:03065C00BA0600DB
|
||||
:06065F0050477B007C0007
|
||||
:03066500BC0400D2
|
||||
:0E0668005017EB2BFDA2A2E433FE4DFB000069
|
||||
:0B06760000D2B1000000C2B10C80E413
|
||||
:0E068100EA24C0FCE434E7FD8B82C002C00412
|
||||
:0E068F00C005120396AB82D005D004D0028CB9
|
||||
:0B069D00828D83EBF00000000A80B4A7
|
||||
:0E06A80090E7C67420F000000090E7C77428A9
|
||||
:0E06B600F000000090E7C87443F000000090D0
|
||||
:0E06C400E7C97429F000000090E68F740AF078
|
||||
:0406D2000000002202
|
||||
:0E06D600E582FA24FF928590E7C0744FF00091
|
||||
:0E06E400000090E7C1744BF000000090E7C2E8
|
||||
:0E06F2007420F000000090E7C37428F00000B0
|
||||
:0E0700000090E7C47442F0000000EA60047A42
|
||||
:03070E0031800235
|
||||
:020711007A303C
|
||||
:0E07130090E7C5EAF000000090E7C67429F0F8
|
||||
:0D07210000000090E68F7407F00000002239
|
||||
:0E072E00E582FA24FF92B290E7C0744FF0000B
|
||||
:0E073C00000090E7C1744BF000000090E7C28F
|
||||
:0E074A007420F000000090E7C37428F0000057
|
||||
:0E0758000090E7C47449F0000000EA60047AE3
|
||||
:03076600318002DD
|
||||
:020769007A30E4
|
||||
:0E076B0090E7C5EAF000000090E7C67429F0A0
|
||||
:0D07790000000090E68F7407F000000022E1
|
||||
:0707860030A0047A3180026B
|
||||
:02078D007A30C0
|
||||
:0C078F0090E7C0EAF0000000E5086004FC
|
||||
:04079B007A3180022D
|
||||
:02079F007A30AE
|
||||
:0E07A10090E7C1EAF000000030A1047A318038
|
||||
:0107AF000247
|
||||
:0207B0007A309D
|
||||
:0E07B20090E7C2EAF00000003082047A318045
|
||||
:0107C0000236
|
||||
:0207C1007A308C
|
||||
:0E07C30090E7C3EAF000000030A3047A318012
|
||||
:0107D1000225
|
||||
:0207D2007A307B
|
||||
:0E07D40090E7C4EAF0000000E5B130E5047AD9
|
||||
:0307E20031800261
|
||||
:0207E5007A3068
|
||||
:0E07E70090E7C5EAF0000000E5A0C4540FF54D
|
||||
:0E07F50082120396AA8290E7C6EAF000000086
|
||||
:0E08030090E7C77420F000000090E7C874284A
|
||||
:0E081100F000000090E7C97453F00000009062
|
||||
:0E081F00E7CA7429F000000090E68F740BF019
|
||||
:0C082D0000000075080075B00800000015
|
||||
:0708390000000053B0F7229C
|
||||
:0708400030A0047A318002B0
|
||||
:020847007A3005
|
||||
:0C08490090E7C0EAF0000000E508600441
|
||||
:040855007A31800272
|
||||
:020859007A30F3
|
||||
:0E085B0090E7C1EAF000000030A1047A31807D
|
||||
:01086900028C
|
||||
:02086A007A30E2
|
||||
:0E086C0090E7C2EAF00000003082047A31808A
|
||||
:01087A00027B
|
||||
:02087B007A30D1
|
||||
:0E087D0090E7C3EAF000000030A3047A318057
|
||||
:01088B00026A
|
||||
:02088C007A30C0
|
||||
:0E088E0090E7C4EAF0000000E5B130E5047A1E
|
||||
:03089C00318002A6
|
||||
:02089F007A30AD
|
||||
:0E08A10090E7C5EAF0000000E5A0C4540FF592
|
||||
:0E08AF0082120396AA8290E7C6EAF0000000CB
|
||||
:0E08BD0090E7C77420F000000090E7C8742890
|
||||
:0E08CB00F000000090E7C97450F000000090AB
|
||||
:0E08D900E7CA7429F000000090E68F740BF05F
|
||||
:0408E70000000022EB
|
||||
:0A08EB00AA82E509600475090022E5
|
||||
:0408F500EA70012282
|
||||
:0708F900BA01047509012298
|
||||
:0E090000740C5AFBBB0428EA30E10543B11029
|
||||
:02090E00800364
|
||||
:0309100053B1EFF1
|
||||
:09091300EA30E00543B140800325
|
||||
:03091C0053B1BF15
|
||||
:0E091F0000000053B1F712013D43B108000083
|
||||
:02092D000022A6
|
||||
:0E092F0074085AFBBB0848EA30E10543B110DA
|
||||
:02093D00800335
|
||||
:03093F0053B1EFC2
|
||||
:09094200EA30E00543B1408003F6
|
||||
:03094B0053B1BFE6
|
||||
:0E094E0000000053B1F7C00212013DD0024379
|
||||
:0D095C00B108000000530204E4BA000104D9
|
||||
:0B096900FA742055B1FBE4BB00010450
|
||||
:07097400FBEAB5030280035A
|
||||
:03097B00750801FB
|
||||
:01097E002256
|
||||
:07097F00AA827509007B014B
|
||||
:0E098600C3EB9A502CEB2480F582E434E7F5A5
|
||||
:0E09940083E0FC740F5CF582C002C003C00457
|
||||
:0E09A2001208EBD004ECC4540FF5821208EBDF
|
||||
:0709B000D003D0020B80CF41
|
||||
:0109B700221D
|
||||
:0E09B80090E7C0744FF000000090E7C1744B50
|
||||
:0E09C600F000000090E7C27420F000000090E6
|
||||
:0E09D400E7C37428F000000090E7C47458F0E8
|
||||
:0D09E20000000090E7C57429F000000090AF
|
||||
:0E09EF00E68F7406F000000090E68D74FFF0B5
|
||||
:0609FD000000000202539D
|
||||
:0E0A030090E68DE0FA90E780E0FBBB542BBA42
|
||||
:0E0A1100032890E781E0F5821203A2E582C47B
|
||||
:0E0A1F0054F0FC90E782E0F582C0041203A2BE
|
||||
:0E0A2D00AD82D004ED4CF5821203D8020AFE11
|
||||
:0C0A3B00BB5209BA010612046E020AFE4A
|
||||
:0D0A4700BB5712BA020F90E781E0F5821252
|
||||
:060A540003A21205EA02F4
|
||||
:020A5A000AFE92
|
||||
:0C0A5C00BB4309BA010612064A020AFE5A
|
||||
:0E0A6800BB4215BA021290E781E0FCE4BC31FB
|
||||
:020A7600010479
|
||||
:080A7800F5821206D6020AFE07
|
||||
:0E0A8000BB4914BA021190E781E0FCE4BC31DE
|
||||
:020A8E00010461
|
||||
:070A9000F58212072E8067BA
|
||||
:0B0A9700BB5308BA0105120786805C03
|
||||
:0B0AA200BB5008BA010512084080514B
|
||||
:0A0AAD00BB4A078A8212097F8047C6
|
||||
:080AB700BB58051209B8803F8D
|
||||
:0E0ABF0090E7C07445F000000090E7C174524B
|
||||
:0E0ACD00F000000090E7C27452F000000090AC
|
||||
:0E0ADB00E7C3744FF000000090E7C47452F0BF
|
||||
:0D0AE90000000090E7C57421F000000090AF
|
||||
:080AF600E68F7406F000000019
|
||||
:0A0AFE0090E68D74FFF00000002266
|
||||
:0E0B080090E690E0FB7A0090E691E0FC7D0024
|
||||
:0E0B16004202ED4203EA4B700A90E69174FF32
|
||||
:050B2400F000000022BA
|
||||
:0E0B2900E5BB30E7FB90E690E090E6D0F09060
|
||||
:0D0B3700E691E090E6D1F090E691E4F090B8
|
||||
:060B4400E6D474FFF0226C
|
||||
:0C0B4A0075080012019190E69174FFF014
|
||||
:0D0B560000000090E69174FFF00000009098
|
||||
:0E0B6300E69174FFF000000090E69174FFF040
|
||||
:030B710000000081
|
||||
:0E0B740090E6A1E0FA20E107D281120A03C246
|
||||
:010B820081F1
|
||||
:0E0B830090E6A3E0FA20E2E9D280120B08C24D
|
||||
:030B91008080E081
|
||||
:0E0BB400010101010101010700000000000025
|
||||
:0E0BC2000000070707070707070700000000ED
|
||||
:0E0BD0000000003F010101013F010107020486
|
||||
:0E0BDE000000010000000603050307070707DB
|
||||
:0E0BEC00000000003600003FFE01FE3801014F
|
||||
:0E0BFA000107000204010000000007060703C7
|
||||
:0E0C0800030303070000002D0000003F010160
|
||||
:0E0C1600013801010107020400010000000086
|
||||
:0E0C240006030503030303070000002D000074
|
||||
:020C3200003F81
|
||||
:0E0C34000000000000000000000000000000B2
|
||||
:0E0C42000000000000000000000000000000A4
|
||||
:080C500000000000000000009C
|
||||
:070C5800E0000007EA4E0076
|
||||
:0E0C5F00303132333435363738394142434470
|
||||
:030C6D00454600F9
|
||||
:070C70004F4B202852290020
|
||||
:06003700E478FFF6D8FD9D
|
||||
:080015007900E94400601B7A48
|
||||
:05001D0000900C777853
|
||||
:030022000075A0C6
|
||||
:0A00250020E493F2A308B8000205DE
|
||||
:08002F00A0D9F4DAF275A0FF7C
|
||||
:08003D007800E84400600A7934
|
||||
:030045000075A0A3
|
||||
:0600480020E4F309D8FCDE
|
||||
:08004E007800E84400600C7921
|
||||
:0B00560000902000E4F0A3D8FCD9FAD1
|
||||
:03000800758109F6
|
||||
:0A000B00120BB0E58260030200034F
|
||||
:0E0B940020F71430F6148883A88220F507E6B7
|
||||
:060BA200A8837583002208
|
||||
:030BA800E280F7F1
|
||||
:030BAB00E49322AE
|
||||
:020BAE00E02243
|
||||
:040BB0007582002228
|
||||
:00000001FF
|
File diff suppressed because it is too large
Load Diff
@ -0,0 +1,41 @@
|
||||
#!/bin/bash
|
||||
#
|
||||
# Reset probe to Xilinx Firmware using 'impact'
|
||||
# (see README file for details)
|
||||
#
|
||||
|
||||
ISEDIR="/opt/Xilinx/11.3/ISE"
|
||||
|
||||
finddev() {
|
||||
for id in 03fd:0009 03fd:000d 03fd:000f 04b4:8613; do lsusb -d $id; done | \
|
||||
head -n 1 | sed -r 's,^Bus ([0-9]+) Device ([0-9]+).*,/dev/bus/usb/\1/\2,'
|
||||
}
|
||||
|
||||
v() {
|
||||
echo "+ $*"
|
||||
"$@"
|
||||
}
|
||||
|
||||
batchfile=$( mktemp )
|
||||
trap 'rm "$batchfile"' 0
|
||||
|
||||
cat << EOT > "$batchfile"
|
||||
setMode -bs
|
||||
setCable -port usb21
|
||||
# identify
|
||||
quit
|
||||
EOT
|
||||
|
||||
v fxload -t fx2 -D $(finddev) -I "$ISEDIR"/bin/lin/xusb_emb.hex
|
||||
|
||||
for x in 0 1 2 3 4 5 6 7; do
|
||||
lsusb -d "03fd:0008" && break
|
||||
echo "Waiting for probe to re-enumerate.."
|
||||
sleep 1
|
||||
done
|
||||
|
||||
echo -n "Waiting for probe to settle.."
|
||||
for x in 1 2 3 4 5; do echo -n .; sleep 1; done; echo
|
||||
|
||||
v "$ISEDIR"/bin/lin/impact -batch "$batchfile"
|
||||
|
@ -0,0 +1,720 @@
|
||||
/*
|
||||
* xsvftool-xpcu - An (X)SVF player for the Xilinx Platform Cable USB
|
||||
*
|
||||
* Copyright (C) 2011 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#define _GNU_SOURCE
|
||||
|
||||
#include <stdio.h>
|
||||
#include <string.h>
|
||||
#include <errno.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#include "libxsvf.h"
|
||||
#include "fx2usb-interface.h"
|
||||
|
||||
#include "filedata.h"
|
||||
|
||||
char *correct_cksum =
|
||||
#include "hardware_cksum_c.inc"
|
||||
;
|
||||
|
||||
#define UNUSED __attribute__((unused))
|
||||
|
||||
/**** BEGIN: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||
|
||||
// This is to not confuse the VIM syntax highlighting
|
||||
#define CHECK_VAL_OPEN (
|
||||
#define CHECK_VAL_CLOSE )
|
||||
|
||||
#define CHECK(result, check) \
|
||||
CHECK_VAL_OPEN{ \
|
||||
typeof(result) _R = (result); \
|
||||
if (!(_R check)) { \
|
||||
fprintf(stderr, "Error from '%s' (%d %s) in %s:%d.\n", \
|
||||
#result, (int)_R, #check, __FILE__, __LINE__); \
|
||||
fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \
|
||||
abort(); \
|
||||
} \
|
||||
_R; \
|
||||
}CHECK_VAL_CLOSE
|
||||
|
||||
#define CHECK_PTR(result, check) \
|
||||
CHECK_VAL_OPEN{ \
|
||||
typeof(result) _R = (result); \
|
||||
if (!(_R check)) { \
|
||||
fprintf(stderr, "Error from '%s' (%p %s) in %s:%d.\n", \
|
||||
#result, (void*)_R, #check, __FILE__, __LINE__); \
|
||||
fprintf(stderr, "ERRNO(%d): %s\n", errno, strerror(errno)); \
|
||||
abort(); \
|
||||
} \
|
||||
_R; \
|
||||
}CHECK_VAL_CLOSE
|
||||
|
||||
/**** END: http://svn.clifford.at/tools/trunk/examples/check.h ****/
|
||||
|
||||
FILE *file_fp = NULL;
|
||||
|
||||
int usb_vendor_id = 0;
|
||||
int usb_device_id = 0;
|
||||
char *usb_device_file = NULL;
|
||||
|
||||
int mode_frequency = 6000;
|
||||
int mode_async_check = 0;
|
||||
int mode_internal_cpld = 0;
|
||||
int mode_8bit_per_cycle = 0;
|
||||
int mode_hex_rmask = 0;
|
||||
|
||||
usb_dev_handle *fx2usb;
|
||||
int internal_jtag_scan_test = 0;
|
||||
|
||||
int sync_count;
|
||||
int tck_cycle_count;
|
||||
int blocks_without_sync;
|
||||
|
||||
int tdo_check_period_100;
|
||||
int tdo_check_thisperiod;
|
||||
|
||||
int rmask_bits = 0, rmask_bytes = 0;
|
||||
unsigned char *rmask_data = NULL;
|
||||
|
||||
/* This constant are used to determine when the error status should be synced.
|
||||
* Syncinc to often would slow things down, syncinc not often enough might cause
|
||||
* errors beeing reported by far to late.
|
||||
*/
|
||||
#define FORCE_SYNC_AFTER_N_BLOCKS 100
|
||||
#define FORCE_SYNC_MIN_PERIOD 10000
|
||||
#define FORCE_SYNC_INIT_PERIOD 100000
|
||||
|
||||
// send larger junks to USB stack and let the kernel split it up
|
||||
// #define MAXBUF() (mode_internal_cpld ? 50 : mode_8bit_per_cycle ? 500 : 1000)
|
||||
#define MAXBUF() (mode_internal_cpld ? 50 : 4000)
|
||||
|
||||
unsigned char fx2usb_retbuf[65];
|
||||
int fx2usb_retlen;
|
||||
|
||||
unsigned char commandbuf[4096];
|
||||
int commandbuf_len;
|
||||
|
||||
static void shrink_8bit_to_4bit()
|
||||
{
|
||||
int i;
|
||||
if ((commandbuf_len & 1) != 0)
|
||||
commandbuf[commandbuf_len++] = 0;
|
||||
for (i = 0; i<commandbuf_len; i++) {
|
||||
if ((i & 1) == 0)
|
||||
commandbuf[i >> 1] = (commandbuf[i >> 1] & 0xf0) | commandbuf[i];
|
||||
else
|
||||
commandbuf[i >> 1] = (commandbuf[i >> 1] & 0x0f) | (commandbuf[i] << 4);
|
||||
}
|
||||
commandbuf_len = commandbuf_len >> 1;
|
||||
}
|
||||
|
||||
void fx2usb_command(const char *cmd)
|
||||
{
|
||||
// fprintf(stderr, "Sending FX2USB Command: '%s' => ", cmd);
|
||||
fx2usb_send_chunk(fx2usb, 1, cmd, strlen(cmd));
|
||||
fx2usb_recv_chunk(fx2usb, 1, fx2usb_retbuf, sizeof(fx2usb_retbuf)-1, &fx2usb_retlen);
|
||||
fx2usb_retbuf[fx2usb_retlen] = 0;
|
||||
// fprintf(stderr, "'%s'\n", fx2usb_retbuf);
|
||||
|
||||
if (strchr((char*)fx2usb_retbuf, '!') != NULL) {
|
||||
fprintf(stderr, "Internal ERROR in communication with probe: '%s' => '%s'\n", cmd, fx2usb_retbuf);
|
||||
abort();
|
||||
}
|
||||
}
|
||||
|
||||
static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v);
|
||||
static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask UNUSED, int sync);
|
||||
|
||||
static int xpcu_setup(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
sync_count = 0;
|
||||
blocks_without_sync = 0;
|
||||
commandbuf_len = 0;
|
||||
fx2usb_command("R");
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
fx2usb_command("B1");
|
||||
}
|
||||
|
||||
if (mode_frequency)
|
||||
xpcu_set_frequency(h, mode_frequency * 1000);
|
||||
|
||||
tdo_check_period_100 = FORCE_SYNC_INIT_PERIOD * 100;
|
||||
tdo_check_thisperiod = 0;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpcu_shutdown(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
int rc = 0;
|
||||
if (commandbuf_len != 0) {
|
||||
fprintf(stderr, "Found %d unsynced commands in command buffer on interface shutdown!\n", commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
rc = -1;
|
||||
}
|
||||
fx2usb_command("S");
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1') {
|
||||
fprintf(stderr, "Found pending errors in interface status on shutdown!\n");
|
||||
rc = -1;
|
||||
}
|
||||
fx2usb_command("R");
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void xpcu_udelay(struct libxsvf_host *h UNUSED, long usecs, int tms, long num_tck)
|
||||
{
|
||||
struct timeval tv1, tv2;
|
||||
long rem_usecs;
|
||||
|
||||
if (mode_internal_cpld)
|
||||
{
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
|
||||
fx2usb_command("P");
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
gettimeofday(&tv1, NULL);
|
||||
|
||||
while (num_tck > 0) {
|
||||
xpcu_pulse_tck(h, tms, 0, -1, 0, 0);
|
||||
num_tck--;
|
||||
}
|
||||
|
||||
if (mode_internal_cpld)
|
||||
{
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
|
||||
fx2usb_command("P");
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
else
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
while (usecs > 0) {
|
||||
gettimeofday(&tv2, NULL);
|
||||
rem_usecs = usecs - ((tv2.tv_sec - tv1.tv_sec)*1000000 + (tv2.tv_usec - tv1.tv_usec));
|
||||
if (rem_usecs <= 0)
|
||||
break;
|
||||
usleep(rem_usecs);
|
||||
}
|
||||
}
|
||||
|
||||
static int xpcu_getbyte(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
return fgetc(file_fp);
|
||||
}
|
||||
|
||||
static int xpcu_pulse_tck(struct libxsvf_host *h UNUSED, int tms, int tdi, int tdo, int rmask, int sync)
|
||||
{
|
||||
int dummy_sync = 0;
|
||||
|
||||
tck_cycle_count++;
|
||||
|
||||
if (tdo >= 0) {
|
||||
commandbuf[commandbuf_len++] = 0x08 | ((tdo & 1) << 2) | ((tms & 1) << 1) | ((tdi & 1) << 0);
|
||||
tdo_check_period_100 = (tdo_check_period_100 * 99) / 100 + tdo_check_thisperiod;
|
||||
tdo_check_thisperiod = 0;
|
||||
} else {
|
||||
commandbuf[commandbuf_len++] = 0x04 | ((tms & 1) << 1) | ((tdi & 1) << 0);
|
||||
}
|
||||
|
||||
if (mode_async_check == 0)
|
||||
{
|
||||
if (!sync && tdo >= 0 && (blocks_without_sync > FORCE_SYNC_AFTER_N_BLOCKS || tdo_check_period_100 > FORCE_SYNC_MIN_PERIOD))
|
||||
sync = 1;
|
||||
if (!sync && !mode_internal_cpld && blocks_without_sync > 10*FORCE_SYNC_AFTER_N_BLOCKS && commandbuf_len >= (MAXBUF() - 10))
|
||||
dummy_sync = 1;
|
||||
}
|
||||
|
||||
if (rmask && !sync)
|
||||
dummy_sync = 1;
|
||||
|
||||
if ((dummy_sync || sync) && !mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (commandbuf_len >= (MAXBUF() - 4) || sync || dummy_sync) {
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
blocks_without_sync++;
|
||||
commandbuf_len = 0;
|
||||
}
|
||||
|
||||
if ((sync || dummy_sync) && !mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
fx2usb_command("S");
|
||||
blocks_without_sync = 0;
|
||||
}
|
||||
|
||||
if (dummy_sync) {
|
||||
fx2usb_command("P");
|
||||
blocks_without_sync = 0;
|
||||
}
|
||||
|
||||
if (rmask) {
|
||||
if (rmask_bits >= 8*rmask_bytes) {
|
||||
int old_rmask_bytes = rmask_bytes;
|
||||
rmask_bytes = rmask_bytes ? rmask_bytes*2 : 64;
|
||||
rmask_data = realloc(rmask_data, rmask_bytes);
|
||||
memset(rmask_data + old_rmask_bytes, 0, rmask_bytes-old_rmask_bytes);
|
||||
}
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1')
|
||||
rmask_data[rmask_bits/8] |= 1 << (rmask_bits%8);
|
||||
rmask_bits++;
|
||||
}
|
||||
|
||||
if (sync) {
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1')
|
||||
return -1;
|
||||
return fx2usb_retbuf[mode_internal_cpld ? 5 : 4] == '1';
|
||||
}
|
||||
return tdo < 0 ? 1 : tdo;
|
||||
}
|
||||
|
||||
static int xpcu_sync(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
if (!mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
commandbuf_len = 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
fx2usb_command("S");
|
||||
blocks_without_sync = 0;
|
||||
if (fx2usb_retbuf[mode_internal_cpld ? 1 : 0] == '1')
|
||||
return -1;
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int xpcu_set_frequency(struct libxsvf_host *h UNUSED, int v)
|
||||
{
|
||||
int freq = 24000000, delay = 0;
|
||||
|
||||
if (mode_internal_cpld)
|
||||
return 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
}
|
||||
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
if (mode_internal_cpld) {
|
||||
unsigned char tempbuf[64];
|
||||
tempbuf[0] = 'J';
|
||||
memcpy(tempbuf+1, commandbuf, commandbuf_len);
|
||||
fx2usb_send_chunk(fx2usb, 1, tempbuf, commandbuf_len + 1);
|
||||
} else {
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
}
|
||||
commandbuf_len = 0;
|
||||
|
||||
if (!mode_internal_cpld) {
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
while (delay < 250 && v < freq) {
|
||||
delay++;
|
||||
freq = 48000000 / (2*delay + 2);
|
||||
}
|
||||
|
||||
if (v < freq)
|
||||
fprintf(stderr, "Requested FREQUENCY %dHz is to low! Using minimum value %dHz instead.\n", v, freq);
|
||||
else if (v-freq > 10)
|
||||
fprintf(stderr, "Requested FREQUENCY is %dHz. Using %dHz (24MHz/%d) instead.\n", v, freq, delay+1);
|
||||
|
||||
char cmd[4];
|
||||
snprintf(cmd, 4, "T%02x", delay);
|
||||
fx2usb_command(cmd);
|
||||
|
||||
mode_8bit_per_cycle = delay != 0;
|
||||
|
||||
if (!mode_internal_cpld)
|
||||
{
|
||||
sync_count = 0x08 | ((sync_count+1) & 0x0f);
|
||||
commandbuf[commandbuf_len++] = 0x01;
|
||||
commandbuf[commandbuf_len++] = sync_count;
|
||||
if (!mode_8bit_per_cycle)
|
||||
shrink_8bit_to_4bit();
|
||||
fx2usb_send_chunk(fx2usb, 2, commandbuf, commandbuf_len);
|
||||
commandbuf_len = 0;
|
||||
|
||||
char cmd[3];
|
||||
snprintf(cmd, 3, "W%x", sync_count);
|
||||
fx2usb_command(cmd);
|
||||
}
|
||||
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void xpcu_report_tapstate(struct libxsvf_host *h UNUSED)
|
||||
{
|
||||
// fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state));
|
||||
}
|
||||
|
||||
static void xpcu_report_device(struct libxsvf_host *h UNUSED, unsigned long idcode)
|
||||
{
|
||||
if (internal_jtag_scan_test != 0) {
|
||||
// CPLD should be: idcode=0x16d4a093, revision=0x1, part=0x6d4a, manufactor=0x049
|
||||
if (((idcode >> 12) & 0xffff) == 0x6d4a && ((idcode >> 1) & 0x7ff) == 0x049)
|
||||
internal_jtag_scan_test += 1;
|
||||
else
|
||||
internal_jtag_scan_test += 2;
|
||||
} else {
|
||||
printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
|
||||
(idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
|
||||
}
|
||||
}
|
||||
|
||||
static void xpcu_report_status(struct libxsvf_host *h UNUSED, const char *message UNUSED)
|
||||
{
|
||||
// fprintf(stderr, "[STATUS] %s\n", message);
|
||||
}
|
||||
|
||||
static void xpcu_report_error(struct libxsvf_host *h UNUSED, const char *file, int line, const char *message)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] %s\n", file, line, message);
|
||||
}
|
||||
|
||||
static void *xpcu_realloc(struct libxsvf_host *h UNUSED, void *ptr, int size, enum libxsvf_mem which UNUSED)
|
||||
{
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static struct libxsvf_host h = {
|
||||
.udelay = xpcu_udelay,
|
||||
.setup = xpcu_setup,
|
||||
.shutdown = xpcu_shutdown,
|
||||
.getbyte = xpcu_getbyte,
|
||||
.pulse_tck = xpcu_pulse_tck,
|
||||
.sync = xpcu_sync,
|
||||
.set_frequency = xpcu_set_frequency,
|
||||
.report_tapstate = xpcu_report_tapstate,
|
||||
.report_device = xpcu_report_device,
|
||||
.report_status = xpcu_report_status,
|
||||
.report_error = xpcu_report_error,
|
||||
.realloc = xpcu_realloc
|
||||
};
|
||||
|
||||
const char *progname;
|
||||
|
||||
static void help()
|
||||
{
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "A JTAG SVF/XSVF Player based on libxsvf for the Xilinx Platform Cable USB\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "xsvftool-xpcu, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n");
|
||||
fprintf(stderr, "Copyright (C) 2011 RIEGL Research ForschungsGmbH\n");
|
||||
fprintf(stderr, "Copyright (C) 2011 Clifford Wolf <clifford@clifford.at>\n");
|
||||
fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [ -L | -B ] [ -d <vendor>:<device> | -D <device_file> ] [ -f kHz ] [ -A ] [ -P ]\n", progname);
|
||||
fprintf(stderr, " %*s { -E | -p | -s svf-file | -x xsvf-file | -c } ...\n", (int)strlen(progname), "");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -L, -B\n");
|
||||
fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -d <vendor>:<device>\n");
|
||||
fprintf(stderr, " Open the device with this USB vendor and device ID.\n");
|
||||
fprintf(stderr, " (default: 03fd:000d and 04b4:8613\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -D <device_file>\n");
|
||||
fprintf(stderr, " Open this USB device (usually something like /dev/bus/usb/012/345)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -f kHz\n");
|
||||
fprintf(stderr, " Run probe with the specified frequency (default=6000, max=24000)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -A\n");
|
||||
fprintf(stderr, " Use full asynchonous error checking\n");
|
||||
fprintf(stderr, " (very fast but error reporting might be delayed)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -P\n");
|
||||
fprintf(stderr, " Use CPLD on probe as target device\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -p\n");
|
||||
fprintf(stderr, " Force (re-)programming the CPLD on the probe\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -E\n");
|
||||
fprintf(stderr, " Erase the CPLD on the probe\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -s svf-file\n");
|
||||
fprintf(stderr, " Play the specified SVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -x xsvf-file\n");
|
||||
fprintf(stderr, " Play the specified XSVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -c\n");
|
||||
fprintf(stderr, " List devices in JTAG chain\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
int gotaction = 0;
|
||||
int opt, i, j;
|
||||
|
||||
int done_initialization = 0;
|
||||
|
||||
progname = argc >= 1 ? argv[0] : "xsvftool-xpcu";
|
||||
while ((opt = getopt(argc, argv, "LBd:D:f:APpEs:x:c")) != -1)
|
||||
{
|
||||
if (!done_initialization && (opt == 'p' || opt == 'E' || opt == 's' || opt == 'x' || opt == 'c'))
|
||||
{
|
||||
usb_init();
|
||||
usb_find_busses();
|
||||
usb_find_devices();
|
||||
|
||||
fx2usb = fx2usb_open(usb_vendor_id, usb_device_id, usb_device_file);
|
||||
if (fx2usb == NULL) {
|
||||
fprintf(stderr, "Failed to find or open USB device!\n");
|
||||
exit(1);
|
||||
}
|
||||
CHECK(fx2usb_claim(fx2usb), == 0);
|
||||
|
||||
FILE *ihexf = CHECK_PTR(fmemopen(firmware_ihx, sizeof(firmware_ihx), "r"), != NULL);
|
||||
CHECK(fx2usb_upload_ihex(fx2usb, ihexf), == 0);
|
||||
CHECK(fclose(ihexf), == 0);
|
||||
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
internal_jtag_scan_test = 1;
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SCAN);
|
||||
|
||||
if (internal_jtag_scan_test != 2) {
|
||||
fprintf(stderr, "Probe (device %s on bus %s) failed internal JTAG scan test!\n",
|
||||
usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname);
|
||||
exit(1);
|
||||
}
|
||||
mode_internal_cpld = i;
|
||||
internal_jtag_scan_test = 0;
|
||||
|
||||
fprintf(stderr, "Connected to probe (device %s on bus %s) and passed internal JTAG scan test.\n",
|
||||
usb_device(fx2usb)->filename, usb_device(fx2usb)->bus->dirname);
|
||||
|
||||
if (opt != 'p' && opt != 'E' && !mode_internal_cpld) {
|
||||
fx2usb_command("C");
|
||||
if (memcmp(correct_cksum, fx2usb_retbuf, 6)) {
|
||||
fprintf(stderr, "Mismatch in CPLD checksum (is=%.6s, should=%s): reprogramming CPLD on probe..\n",
|
||||
fx2usb_retbuf, correct_cksum);
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL);
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SVF);
|
||||
mode_internal_cpld = i;
|
||||
fclose(file_fp);
|
||||
}
|
||||
}
|
||||
|
||||
done_initialization = 1;
|
||||
}
|
||||
|
||||
switch (opt)
|
||||
{
|
||||
case 'L':
|
||||
mode_hex_rmask = 1;
|
||||
break;
|
||||
case 'B':
|
||||
mode_hex_rmask = 2;
|
||||
break;
|
||||
case 'd':
|
||||
if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb)
|
||||
help();
|
||||
if (sscanf(optarg, "%x:%x", &usb_vendor_id, &usb_device_id) != 2)
|
||||
help();
|
||||
break;
|
||||
case 'D':
|
||||
if (usb_vendor_id || usb_device_id || usb_device_file || fx2usb)
|
||||
help();
|
||||
usb_device_file = strdup(optarg);
|
||||
break;
|
||||
case 'f':
|
||||
mode_frequency = atoi(optarg);
|
||||
break;
|
||||
case 'P':
|
||||
mode_internal_cpld = 1;
|
||||
break;
|
||||
case 'A':
|
||||
mode_async_check = 1;
|
||||
break;
|
||||
case 'p':
|
||||
case 'E':
|
||||
gotaction = 1;
|
||||
i = mode_internal_cpld;
|
||||
mode_internal_cpld = 1;
|
||||
if (opt == 'p') {
|
||||
file_fp = CHECK_PTR(fmemopen(hardware_svf, sizeof(hardware_svf), "r"), != NULL);
|
||||
fprintf(stderr, "(Re-)programming CPLD on the probe..\n");
|
||||
} else {
|
||||
file_fp = CHECK_PTR(fmemopen(erasecpld_svf, sizeof(erasecpld_svf), "r"), != NULL);
|
||||
fprintf(stderr, "Erasing CPLD on the probe..\n");
|
||||
}
|
||||
libxsvf_play(&h, LIBXSVF_MODE_SVF);
|
||||
mode_internal_cpld = i;
|
||||
fclose(file_fp);
|
||||
break;
|
||||
case 'x':
|
||||
case 's':
|
||||
gotaction = 1;
|
||||
if (!strcmp(optarg, "-"))
|
||||
file_fp = stdin;
|
||||
else
|
||||
file_fp = fopen(optarg, "rb");
|
||||
if (file_fp == NULL) {
|
||||
fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
fprintf(stderr, "Playing %s file `%s'..\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
|
||||
fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
rc = 1;
|
||||
}
|
||||
if (strcmp(optarg, "-"))
|
||||
fclose(file_fp);
|
||||
break;
|
||||
case 'c':
|
||||
gotaction = 1;
|
||||
fprintf(stderr, "Scanning JTAG chain..\n");
|
||||
if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
|
||||
fprintf(stderr, "Error while scanning JTAG chain.\n");
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotaction)
|
||||
help();
|
||||
|
||||
if (rmask_bits > 0) {
|
||||
fprintf(stderr, "Total number of rmask bits acquired: %d\n", rmask_bits);
|
||||
if (mode_hex_rmask) {
|
||||
printf("0x");
|
||||
for (i = 0; i < rmask_bits; i += 4) {
|
||||
int val = 0;
|
||||
for (j = i; j < i + 4; j++) {
|
||||
int pos = mode_hex_rmask > 1 ? j : rmask_bits - j - 1;
|
||||
val = (val << 1) | (rmask_data[pos/8] & (1 << (pos%8)) ? 1 : 0);
|
||||
}
|
||||
printf("%x", val);
|
||||
}
|
||||
} else {
|
||||
for (i = 0; i < rmask_bits; i++)
|
||||
putchar((rmask_data[i / 8] & (1 << (i % 8))) != 0 ? '1' : '0');
|
||||
}
|
||||
putchar('\n');
|
||||
}
|
||||
|
||||
if (done_initialization) {
|
||||
fx2usb_command("X");
|
||||
fx2usb_release(fx2usb);
|
||||
usb_close(fx2usb);
|
||||
}
|
||||
|
||||
fprintf(stderr, "Total number of JTAG clock cycles performed: %d\n", tck_cycle_count);
|
||||
if (rc == 0)
|
||||
fprintf(stderr, "READY.\n");
|
||||
else
|
||||
fprintf(stderr, "TERMINATED WITH ERROR(s)! (see above)\n");
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
@ -0,0 +1,542 @@
|
||||
/*
|
||||
* Lib(X)SVF - A library for implementing SVF and XSVF JTAG players
|
||||
*
|
||||
* Copyright (C) 2009 RIEGL Research ForschungsGmbH
|
||||
* Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>
|
||||
*
|
||||
* Permission to use, copy, modify, and/or distribute this software for any
|
||||
* purpose with or without fee is hereby granted, provided that the above
|
||||
* copyright notice and this permission notice appear in all copies.
|
||||
*
|
||||
* THE SOFTWARE IS PROVIDED "AS IS" AND THE AUTHOR DISCLAIMS ALL WARRANTIES
|
||||
* WITH REGARD TO THIS SOFTWARE INCLUDING ALL IMPLIED WARRANTIES OF
|
||||
* MERCHANTABILITY AND FITNESS. IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR
|
||||
* ANY SPECIAL, DIRECT, INDIRECT, OR CONSEQUENTIAL DAMAGES OR ANY DAMAGES
|
||||
* WHATSOEVER RESULTING FROM LOSS OF USE, DATA OR PROFITS, WHETHER IN AN
|
||||
* ACTION OF CONTRACT, NEGLIGENCE OR OTHER TORTIOUS ACTION, ARISING OUT OF
|
||||
* OR IN CONNECTION WITH THE USE OR PERFORMANCE OF THIS SOFTWARE.
|
||||
*
|
||||
*/
|
||||
|
||||
#include "libxsvf.h"
|
||||
|
||||
#include <sys/time.h>
|
||||
#include <unistd.h>
|
||||
#include <string.h>
|
||||
#include <stdlib.h>
|
||||
#include <stdio.h>
|
||||
#include <errno.h>
|
||||
|
||||
|
||||
/** BEGIN: Low-Level I/O Implementation **/
|
||||
|
||||
#ifdef XSVFTOOL_RLMS_VLINE
|
||||
|
||||
// Simple example with MPC8349E GPIO pins
|
||||
// (RIEGL LMS V-Line motherboard)
|
||||
|
||||
#include <sys/types.h>
|
||||
#include <sys/stat.h>
|
||||
#include <sys/mman.h>
|
||||
#include <fcntl.h>
|
||||
|
||||
#define IO_PORT_ADDR 0xE0000C00
|
||||
|
||||
struct io_layout {
|
||||
unsigned long tdi:1;
|
||||
unsigned long tdo:1;
|
||||
unsigned long tms:1;
|
||||
unsigned long tck:1;
|
||||
unsigned long reserved:28;
|
||||
};
|
||||
|
||||
static volatile struct io_layout *io_direction;
|
||||
static volatile struct io_layout *io_opendrain;
|
||||
static volatile struct io_layout *io_data;
|
||||
|
||||
static void io_setup(void)
|
||||
{
|
||||
/* open /dev/mem device file */
|
||||
int fd = open("/dev/mem", O_RDWR);
|
||||
if (fd < 0) {
|
||||
fprintf(stderr, "Can't open /dev/mem: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* calculate offsets to page and within page */
|
||||
unsigned long psize = getpagesize();
|
||||
unsigned long off_inpage = IO_PORT_ADDR % psize;
|
||||
unsigned long off_topage = IO_PORT_ADDR - off_inpage;
|
||||
unsigned long mapsize = off_inpage + sizeof(struct io_layout) * 3;
|
||||
|
||||
/* map it into logical memory */
|
||||
void *io_addr_map = mmap(0, mapsize, PROT_WRITE, MAP_SHARED, fd, off_topage);
|
||||
if (io_addr_map == MAP_FAILED) {
|
||||
fprintf(stderr, "Can't map physical memory: %s\n", strerror(errno));
|
||||
exit(1);
|
||||
}
|
||||
|
||||
/* calculate register addresses */
|
||||
io_direction = io_addr_map + off_inpage;
|
||||
io_opendrain = io_addr_map + off_inpage + 4;
|
||||
io_data = io_addr_map + off_inpage + 8;
|
||||
|
||||
/* set direction reg */
|
||||
io_direction->tms = 1;
|
||||
io_direction->tck = 1;
|
||||
io_direction->tdo = 0;
|
||||
io_direction->tdi = 1;
|
||||
|
||||
/* set open drain reg */
|
||||
io_opendrain->tms = 0;
|
||||
io_opendrain->tck = 0;
|
||||
io_opendrain->tdo = 0;
|
||||
io_opendrain->tdi = 0;
|
||||
|
||||
#ifdef HAVE_TRST
|
||||
/* for boards with TRST, must be driven high */
|
||||
io_data->trst = 1;
|
||||
io_direction->trst = 1;
|
||||
io_opendrain->trst = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void io_shutdown(void)
|
||||
{
|
||||
/* set all to z-state */
|
||||
io_direction->tms = 0;
|
||||
io_direction->tck = 0;
|
||||
io_direction->tdo = 0;
|
||||
io_direction->tdi = 0;
|
||||
|
||||
#ifdef HAVE_TRST
|
||||
/* for boards with TRST, assuming there is a pull-down resistor */
|
||||
io_direction->trst = 0;
|
||||
#endif
|
||||
}
|
||||
|
||||
static void io_tms(int val)
|
||||
{
|
||||
io_data->tms = val;
|
||||
}
|
||||
|
||||
static void io_tdi(int val)
|
||||
{
|
||||
io_data->tdi = val;
|
||||
}
|
||||
|
||||
static void io_tck(int val)
|
||||
{
|
||||
io_data->tck = val;
|
||||
// usleep(1);
|
||||
}
|
||||
|
||||
static void io_sck(int val)
|
||||
{
|
||||
/* not available */
|
||||
}
|
||||
|
||||
static void io_trst(int val)
|
||||
{
|
||||
/* not available */
|
||||
}
|
||||
|
||||
static int io_tdo()
|
||||
{
|
||||
return io_data->tdo ? 1 : 0;
|
||||
}
|
||||
|
||||
#else
|
||||
|
||||
static void io_setup(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_shutdown(void)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tms(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tdi(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_tck(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_sck(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static void io_trst(int val)
|
||||
{
|
||||
}
|
||||
|
||||
static int io_tdo()
|
||||
{
|
||||
return -1;
|
||||
}
|
||||
|
||||
#endif
|
||||
|
||||
/** END: Low-Level I/O Implementation **/
|
||||
|
||||
|
||||
struct udata_s {
|
||||
FILE *f;
|
||||
int verbose;
|
||||
int clockcount;
|
||||
int bitcount_tdi;
|
||||
int bitcount_tdo;
|
||||
int retval_i;
|
||||
int retval[256];
|
||||
};
|
||||
|
||||
static int h_setup(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[SETUP]\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
io_setup();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static int h_shutdown(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[SHUTDOWN]\n");
|
||||
fflush(stderr);
|
||||
}
|
||||
io_shutdown();
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h_udelay(struct libxsvf_host *h, long usecs, int tms, long num_tck)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[DELAY:%ld, TMS:%d, NUM_TCK:%ld]\n", usecs, tms, num_tck);
|
||||
fflush(stderr);
|
||||
}
|
||||
if (num_tck > 0) {
|
||||
struct timeval tv1, tv2;
|
||||
gettimeofday(&tv1, NULL);
|
||||
io_tms(tms);
|
||||
while (num_tck > 0) {
|
||||
io_tck(0);
|
||||
io_tck(1);
|
||||
num_tck--;
|
||||
}
|
||||
gettimeofday(&tv2, NULL);
|
||||
if (tv2.tv_sec > tv1.tv_sec) {
|
||||
usecs -= (1000000 - tv1.tv_usec) + (tv2.tv_sec - tv1.tv_sec - 1) * 1000000;
|
||||
tv1.tv_usec = 0;
|
||||
}
|
||||
usecs -= tv2.tv_usec - tv1.tv_usec;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[DELAY_AFTER_TCK:%ld]\n", usecs > 0 ? usecs : 0);
|
||||
fflush(stderr);
|
||||
}
|
||||
}
|
||||
if (usecs > 0) {
|
||||
usleep(usecs);
|
||||
}
|
||||
}
|
||||
|
||||
static int h_getbyte(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
return fgetc(u->f);
|
||||
}
|
||||
|
||||
static int h_pulse_tck(struct libxsvf_host *h, int tms, int tdi, int tdo, int rmask, int sync)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
|
||||
io_tms(tms);
|
||||
|
||||
if (tdi >= 0) {
|
||||
u->bitcount_tdi++;
|
||||
io_tdi(tdi);
|
||||
}
|
||||
|
||||
io_tck(0);
|
||||
io_tck(1);
|
||||
|
||||
int line_tdo = io_tdo();
|
||||
int rc = line_tdo >= 0 ? line_tdo : 0;
|
||||
|
||||
if (rmask == 1 && u->retval_i < 256)
|
||||
u->retval[u->retval_i++] = line_tdo;
|
||||
|
||||
if (tdo >= 0 && line_tdo >= 0) {
|
||||
u->bitcount_tdo++;
|
||||
if (tdo != line_tdo)
|
||||
rc = -1;
|
||||
}
|
||||
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[TMS:%d, TDI:%d, TDO_ARG:%d, TDO_LINE:%d, RMASK:%d, RC:%d]\n", tms, tdi, tdo, line_tdo, rmask, rc);
|
||||
}
|
||||
|
||||
u->clockcount++;
|
||||
return rc;
|
||||
}
|
||||
|
||||
static void h_pulse_sck(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[SCK]\n");
|
||||
}
|
||||
io_sck(0);
|
||||
io_sck(1);
|
||||
}
|
||||
|
||||
static void h_set_trst(struct libxsvf_host *h, int v)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 4) {
|
||||
fprintf(stderr, "[TRST:%d]\n", v);
|
||||
}
|
||||
io_trst(v);
|
||||
}
|
||||
|
||||
static int h_set_frequency(struct libxsvf_host *h, int v)
|
||||
{
|
||||
fprintf(stderr, "WARNING: Setting JTAG clock frequency to %d ignored!\n", v);
|
||||
return 0;
|
||||
}
|
||||
|
||||
static void h_report_tapstate(struct libxsvf_host *h)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[%s]\n", libxsvf_state2str(h->tap_state));
|
||||
}
|
||||
}
|
||||
|
||||
static void h_report_device(struct libxsvf_host *h, unsigned long idcode)
|
||||
{
|
||||
// struct udata_s *u = h->user_data;
|
||||
printf("idcode=0x%08lx, revision=0x%01lx, part=0x%04lx, manufactor=0x%03lx\n", idcode,
|
||||
(idcode >> 28) & 0xf, (idcode >> 12) & 0xffff, (idcode >> 1) & 0x7ff);
|
||||
}
|
||||
|
||||
static void h_report_status(struct libxsvf_host *h, const char *message)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (u->verbose >= 2) {
|
||||
fprintf(stderr, "[STATUS] %s\n", message);
|
||||
}
|
||||
}
|
||||
|
||||
static void h_report_error(struct libxsvf_host *h, const char *file, int line, const char *message)
|
||||
{
|
||||
fprintf(stderr, "[%s:%d] %s\n", file, line, message);
|
||||
}
|
||||
|
||||
static int realloc_maxsize[LIBXSVF_MEM_NUM];
|
||||
|
||||
static void *h_realloc(struct libxsvf_host *h, void *ptr, int size, enum libxsvf_mem which)
|
||||
{
|
||||
struct udata_s *u = h->user_data;
|
||||
if (size > realloc_maxsize[which])
|
||||
realloc_maxsize[which] = size;
|
||||
if (u->verbose >= 3) {
|
||||
fprintf(stderr, "[REALLOC:%s:%d]\n", libxsvf_mem2str(which), size);
|
||||
}
|
||||
return realloc(ptr, size);
|
||||
}
|
||||
|
||||
static struct udata_s u;
|
||||
|
||||
static struct libxsvf_host h = {
|
||||
.udelay = h_udelay,
|
||||
.setup = h_setup,
|
||||
.shutdown = h_shutdown,
|
||||
.getbyte = h_getbyte,
|
||||
.pulse_tck = h_pulse_tck,
|
||||
.pulse_sck = h_pulse_sck,
|
||||
.set_trst = h_set_trst,
|
||||
.set_frequency = h_set_frequency,
|
||||
.report_tapstate = h_report_tapstate,
|
||||
.report_device = h_report_device,
|
||||
.report_status = h_report_status,
|
||||
.report_error = h_report_error,
|
||||
.realloc = h_realloc,
|
||||
.user_data = &u
|
||||
};
|
||||
|
||||
const char *progname;
|
||||
|
||||
static void copyleft()
|
||||
{
|
||||
static int already_printed = 0;
|
||||
if (already_printed)
|
||||
return;
|
||||
fprintf(stderr, "xsvftool-gpio, part of Lib(X)SVF (http://www.clifford.at/libxsvf/).\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 RIEGL Research ForschungsGmbH\n");
|
||||
fprintf(stderr, "Copyright (C) 2009 Clifford Wolf <clifford@clifford.at>\n");
|
||||
fprintf(stderr, "Lib(X)SVF is free software licensed under the ISC license.\n");
|
||||
already_printed = 1;
|
||||
}
|
||||
|
||||
static void help()
|
||||
{
|
||||
copyleft();
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, "Usage: %s [ -r funcname ] [ -v ... ] [ -L | -B ] { -s svf-file | -x xsvf-file | -c } ...\n", progname);
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -r funcname\n");
|
||||
fprintf(stderr, " Dump C-code for pseudo-allocator based on example files\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -v, -vv, -vvv, -vvvv\n");
|
||||
fprintf(stderr, " Verbose, more verbose and even more verbose\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -L, -B\n");
|
||||
fprintf(stderr, " Print RMASK bits as hex value (little or big endian)\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -s svf-file\n");
|
||||
fprintf(stderr, " Play the specified SVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -x xsvf-file\n");
|
||||
fprintf(stderr, " Play the specified XSVF file\n");
|
||||
fprintf(stderr, "\n");
|
||||
fprintf(stderr, " -c\n");
|
||||
fprintf(stderr, " List devices in JTAG chain\n");
|
||||
fprintf(stderr, "\n");
|
||||
exit(1);
|
||||
}
|
||||
|
||||
int main(int argc, char **argv)
|
||||
{
|
||||
int rc = 0;
|
||||
int gotaction = 0;
|
||||
int hex_mode = 0;
|
||||
const char *realloc_name = NULL;
|
||||
int opt, i, j;
|
||||
|
||||
progname = argc >= 1 ? argv[0] : "xvsftool";
|
||||
while ((opt = getopt(argc, argv, "r:vLBx:s:c")) != -1)
|
||||
{
|
||||
switch (opt)
|
||||
{
|
||||
case 'r':
|
||||
realloc_name = optarg;
|
||||
break;
|
||||
case 'v':
|
||||
copyleft();
|
||||
u.verbose++;
|
||||
break;
|
||||
case 'x':
|
||||
case 's':
|
||||
gotaction = 1;
|
||||
if (u.verbose)
|
||||
fprintf(stderr, "Playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
if (!strcmp(optarg, "-"))
|
||||
u.f = stdin;
|
||||
else
|
||||
u.f = fopen(optarg, "rb");
|
||||
if (u.f == NULL) {
|
||||
fprintf(stderr, "Can't open %s file `%s': %s\n", opt == 's' ? "SVF" : "XSVF", optarg, strerror(errno));
|
||||
rc = 1;
|
||||
break;
|
||||
}
|
||||
if (libxsvf_play(&h, opt == 's' ? LIBXSVF_MODE_SVF : LIBXSVF_MODE_XSVF) < 0) {
|
||||
fprintf(stderr, "Error while playing %s file `%s'.\n", opt == 's' ? "SVF" : "XSVF", optarg);
|
||||
rc = 1;
|
||||
}
|
||||
if (strcmp(optarg, "-"))
|
||||
fclose(u.f);
|
||||
break;
|
||||
case 'c':
|
||||
gotaction = 1;
|
||||
if (libxsvf_play(&h, LIBXSVF_MODE_SCAN) < 0) {
|
||||
fprintf(stderr, "Error while scanning JTAG chain.\n");
|
||||
rc = 1;
|
||||
}
|
||||
break;
|
||||
case 'L':
|
||||
hex_mode = 1;
|
||||
break;
|
||||
case 'B':
|
||||
hex_mode = 2;
|
||||
break;
|
||||
default:
|
||||
help();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (!gotaction)
|
||||
help();
|
||||
|
||||
if (u.verbose) {
|
||||
fprintf(stderr, "Total number of clock cycles: %d\n", u.clockcount);
|
||||
fprintf(stderr, "Number of significant TDI bits: %d\n", u.bitcount_tdi);
|
||||
fprintf(stderr, "Number of significant TDO bits: %d\n", u.bitcount_tdo);
|
||||
if (rc == 0) {
|
||||
fprintf(stderr, "Finished without errors.\n");
|
||||
} else {
|
||||
fprintf(stderr, "Finished with errors!\n");
|
||||
}
|
||||
}
|
||||
|
||||
if (u.retval_i) {
|
||||
if (hex_mode) {
|
||||
printf("0x");
|
||||
for (i=0; i < u.retval_i; i+=4) {
|
||||
int val = 0;
|
||||
for (j=i; j<i+4; j++)
|
||||
val = val << 1 | u.retval[hex_mode > 1 ? j : u.retval_i - j - 1];
|
||||
printf("%x", val);
|
||||
}
|
||||
} else {
|
||||
printf("%d rmask bits:", u.retval_i);
|
||||
for (i=0; i < u.retval_i; i++)
|
||||
printf(" %d", u.retval[i]);
|
||||
}
|
||||
printf("\n");
|
||||
}
|
||||
|
||||
if (realloc_name) {
|
||||
int num = 0;
|
||||
for (i = 0; i < LIBXSVF_MEM_NUM; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
num = i+1;
|
||||
}
|
||||
printf("void *%s(void *h, void *ptr, int size, int which) {\n", realloc_name);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("\tstatic unsigned char buf_%s[%d];\n", libxsvf_mem2str(i), realloc_maxsize[i]);
|
||||
}
|
||||
printf("\tstatic unsigned char *buflist[%d] = {", num);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("%sbuf_%s", i ? ", " : " ", libxsvf_mem2str(i));
|
||||
else
|
||||
printf("%s(void*)0", i ? ", " : " ");
|
||||
}
|
||||
printf(" };\n\tstatic int sizelist[%d] = {", num);
|
||||
for (i = 0; i < num; i++) {
|
||||
if (realloc_maxsize[i] > 0)
|
||||
printf("%ssizeof(buf_%s)", i ? ", " : " ", libxsvf_mem2str(i));
|
||||
else
|
||||
printf("%s0", i ? ", " : " ");
|
||||
}
|
||||
printf(" };\n");
|
||||
printf("\treturn which < %d && size <= sizelist[which] ? buflist[which] : (void*)0;\n", num);
|
||||
printf("};\n");
|
||||
}
|
||||
|
||||
return rc;
|
||||
}
|
||||
|
Loading…
Reference in new issue