You can not select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.
kpicosim/src/jtagprogrammer.cpp

234 lines
6.1 KiB

/***************************************************************************
* Copyright (C) 2005 by Mark Six *
* marksix@xs4all.nl *
* *
* This program is free software; you can redistribute it and/or modify *
* it under the terms of the GNU General Public License as published by *
* the Free Software Foundation; either version 2 of the License, or *
* (at your option) any later version. *
* *
* This program is distributed in the hope that it will be useful, *
* but WITHOUT ANY WARRANTY; without even the implied warranty of *
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the *
* GNU General Public License for more details. *
* *
* You should have received a copy of the GNU General Public License *
* along with this program; if not, write to the *
* Free Software Foundation, Inc., *
* 51 Franklin Street, Fifth Floor, Boston, MA 02110-1301, USA. *
***************************************************************************/
/* FIXME
*
* This source is still a mess.
* I will clean it in the (near?) future.
*
*/
#include "jtagprogrammer.h"
#include <iostream>
#include <tqapplication.h>
#include <tqeventloop.h>
bool IDCODE_PROM[] = { 0, 1, 1, 1, 1, 1, 1, 1 } ;
bool BYPASS_PROM[] = { 1, 1, 1, 1, 1, 1, 1, 1 } ;
bool IDCODE[] = { 1, 0, 0, 1, 0, 0 } ;
bool CFG_IN[] = { 1, 0, 1, 0, 0, 0 } ;
bool JSTART[] = { 0, 0, 1, 1, 0, 0 } ;
bool JPROGRAM[] = { 1, 1, 0, 1, 0, 0 } ;
bool JSHUTDOWN[] = { 1, 0, 1, 1, 0, 0 } ;
bool USER1[] = { 0, 1, 0, 0, 0, 0 } ;
bool USER2[] = { 1, 1, 0, 0, 0, 0 } ;
#define XCF02S 0x05045093
#define XC3S50 0x0140C093
#define XC3S200 0x01414093
#define XC3S400 0x0141C093
#define XC3S1000 0x01428093
#define XC3S1500 0x01434093
#define XC3S2000 0x01440093
#define XC3S4000 0x01448093
#define XC3S5000 0x01450093
#define ID_LEN 32
const char *id_string[] =
{
"XS3S50", "XS3S200", "XS3S400", "XS3S1000", "XS3S1500", "XS3S2000", "XS3S4000", "XS3S5000",
"XCF02S"
} ;
const unsigned int id_code[] =
{
XC3S50, XC3S200, XC3S400, XC3S1000, XC3S1500, XC3S2000, XC3S4000, XC3S5000,
XCF02S
} ;
#define MAX_IDS ( sizeof( id_code ) / sizeof( int ) )
JTAGProgrammer::JTAGProgrammer( TQObject *parent )
{
m_parent = parent ;
m_bitFilename = "" ;
m_dev = new CJTAG ;
}
JTAGProgrammer::~JTAGProgrammer()
{
m_dev->close() ;
delete m_dev ;
}
int JTAGProgrammer::getDevice( bool *id ) {
unsigned int j, dev_id ;
for ( j = 0, dev_id = 0 ; j < ID_LEN ; j++ ) {
dev_id |= id[ j ] << j ;
}
for ( j = 0 ; j < MAX_IDS ; j++ ) {
if ( id_code[j] == dev_id ) {
std::string s ;
s = std::string( "Found Device : ") + id_string[j] + std::string( "\n" );
emit message( s.c_str() ) ;
return dev_id ;
}
}
std::cout << "Unknown ID: " << std::hex << dev_id << "\n" ;
return 0 ;
}
void JTAGProgrammer::program()
{
if ( m_bitFilename == "" ) {
emit message( "No filename given\n" ) ;
return ;
}
bool id[ ID_LEN], ones[ ID_LEN ], dummy[ 32 ] ;
int device0, device1 ;
bool prom_present = true ;
for ( int i = 0 ; i < ID_LEN ; i++ )
ones[i] = 1 ;
if ( m_dev->isOpen() )
return ;
if ( !m_dev->open( (char*) "/dev/parport0" ) ) {
emit message( "/dev/parport0 could not be opened; check permissions\n" ) ;
return ;
}
/* ...Get device(s)... */
m_dev->selectIR() ;
m_dev->setIR( IDCODE_PROM, 8 ) ;
m_dev->setIR( IDCODE, 5 ) ;
m_dev->exitIR( IDCODE[5] ) ;
m_dev->selectDR() ;
m_dev->setDR( ones, id, ID_LEN ) ;
device0 = getDevice( id ) ;
if ( !device0 ) {
emit message( "Unknown device in JTAG chain\n" ) ;
goto exit ;
}
m_dev->setDR( ones, id, ID_LEN-1 ) ;
id[ 31 ] = m_dev->exitDR( 1 ) ;
device1 = getDevice( id ) ;
if ( !device1 ) {
emit message( "Second device is unknown (I will try to continue)\n" ) ;
prom_present = false ;
}
/* ....Setup for configuration..... */
m_dev->selectIR() ;
m_dev->setIR( JPROGRAM, 5 ) ; /* Clear configuration memory */
m_dev->exitIR( JPROGRAM[5] ) ; /* Although this is not documented?? */
m_dev->selectIR();
if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
m_dev->setIR( JSHUTDOWN, 5 ) ;
m_dev->exitIR( JSHUTDOWN[5] ) ;
m_dev->selectRunTestIdle() ;
for ( int i = 0 ; i < 20 ; i++ ) /* Shutdown sequence */
m_dev->execute( 0, 0 ) ;
m_dev->selectIR() ;
if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
m_dev->setIR( CFG_IN, 5 ) ;
m_dev->exitIR( CFG_IN[5] ) ;
/* ....Send bit file.....*/
FILE *bit_file ;
bit_file = fopen( m_bitFilename.c_str(), "r" ) ;
if ( bit_file == NULL ) {
emit message( "Could not read bit file\n" ) ;
goto exit ;
}
int size ;
bool frame[ 8 ] ;
unsigned int cur, next ;
size = 0 ;
m_dev->selectDR() ;
fread( &cur, 1, 1, bit_file ) ;
int prog, prev_prog, total ;
fseek( bit_file, 0, SEEK_END ) ;
total = ftell( bit_file ) ;
rewind( bit_file ) ;
emit message( "Programming..." ) ;
for (prog=prev_prog=0;;) {
for ( int i = 0 ; i < 8; i++, cur <<= 1 )
frame[i] = (cur & 0x80 ) != 0 ;
size += 1;
emit progress( size*100/total ) ;
if ( fread( &next, 1, 1, bit_file ) == 0 )
break ;
m_dev->setDR( frame, dummy, 8 ) ;
cur = next ;
TQApplication::eventLoop()->processEvents( TQEventLoop::AllEvents ) ;
}
std::cout << std::endl ;
m_dev->setDR( frame, dummy, 7 ) ;
m_dev->exitDR( frame[7] ) ;
fclose( bit_file ) ;
/*....Start FPGA.....*/
m_dev->selectTestLogicReset() ;
m_dev->selectIR() ;
if ( prom_present ) m_dev->setIR( BYPASS_PROM, 8 ) ;
m_dev->setIR( JSTART, 5 ) ;
m_dev->exitIR( JSTART[5] ) ;
m_dev->selectRunTestIdle() ;
for ( int i = 0 ; i < 20 ; i++ ) /* Start up sequence */
m_dev->execute( 0, 0 ) ;
emit message( "done.\n" ) ;
exit:
m_dev->close() ;
}
void JTAGProgrammer::setBitFile( std::string filename )
{
m_bitFilename = filename ;
}