diff options
author | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-19 18:45:49 +0000 |
---|---|---|
committer | tpearson <tpearson@283d02a7-25f6-0310-bc7c-ecb5cbfe19da> | 2010-02-19 18:45:49 +0000 |
commit | 09a528fd59d3ea5f69575a92574f7a87898dc068 (patch) | |
tree | 9e465c49fbbe65f70d4feca3fcfb2ab3a7cf00d4 /src/jtag.cpp | |
download | kpicosim-09a528fd59d3ea5f69575a92574f7a87898dc068.tar.gz kpicosim-09a528fd59d3ea5f69575a92574f7a87898dc068.zip |
Added old abandoned (but very good!) KDE3 KPicoSim application
git-svn-id: svn://anonsvn.kde.org/home/kde/branches/trinity/applications/kpicosim@1092928 283d02a7-25f6-0310-bc7c-ecb5cbfe19da
Diffstat (limited to 'src/jtag.cpp')
-rw-r--r-- | src/jtag.cpp | 326 |
1 files changed, 326 insertions, 0 deletions
diff --git a/src/jtag.cpp b/src/jtag.cpp new file mode 100644 index 0000000..461b511 --- /dev/null +++ b/src/jtag.cpp @@ -0,0 +1,326 @@ +#include "jtag.h" +#include <errno.h> +#include <string.h> +#include <iostream> +#include <linux/lp.h> +#include <sys/ioctl.h> +#include <errno.h> +#include <unistd.h> + +#include <linux/ppdev.h> +#include <linux/parport.h> + +using namespace std ; + + +#define JTAG_TDO PARPORT_STATUS_SELECT +#define JTAG_TDI ( 1 << 0 ) +#define JTAG_CLK ( 1 << 1 ) +#define JTAG_TMS ( 1 << 2 ) +#define XILINX_PROG ( 1 << 4 ) + +const char *jtag_states[] = { + "UNDEFINED", "TEST_LOGIC_RESET", "RUN_TEST_IDLE", "SELECT_DR_SCAN", "CAPTURE_DR", "SHIFT_DR", "EXIT_DR", "PAUSE_DR", + "EXIT2_DR", "UPDATE_DR", "SELECT_IR_SCAN", "CAPTURE_IR", "SHIFT_IR", "EXIT_IR", "PAUSE_IR", "EXIT2_IR", "UPDATE_IR" +} ; + +CJTAG::CJTAG() +{ + m_state = ST_UNDEFINED ; + m_fd = -1 ; + m_open = false ; + m_verbose = false ; + +} + +CJTAG::~CJTAG() +{ + if ( m_open ) + close() ; +} + +void CJTAG::error( char *str ) +{ + cout << "JTAG ERROR: " << str << "\r\n" ; +} + +bool CJTAG::open( char *dev ) +{ + if ( m_open ) + close() ; + +// m_fd = ::open( dev, O_WRONLY | O_NONBLOCK ) ; + + m_fd = ::open( dev, O_RDWR ) ; + if ( m_fd < 0 ) { + cerr << "Please check if you have read/write right to device '" << dev << "'" << endl ; + error( strerror( errno ) ) ; + return false ; + } + +// cout << "Successfully opened \"" << dev << "\"\r\n" ; + + if ( ioctl( m_fd, PPCLAIM ) ) + cout << "Unable to claim parallel port" << endl ; + +// if ( ioctl( m_fd, LPRESET, 0 ) ) +// cout << "reset returned non-zero" << endl ; + + int i ; + for ( i = 0 ; i < 10 ; i++ ) + execute( 1, 0 ) ; + + m_state = ST_TEST_LOGIC_RESET ; + + execute( 0, 0 ) ; + + m_open = true ; + + return true ; +} + +bool CJTAG::isOpen() +{ + return m_open ; +} + +void CJTAG::close() +{ + if ( m_open && m_fd >= 0 ) { + char c = 0 ; + ioctl( m_fd, PPWDATA, &c ) ; + ioctl( m_fd, PPRELEASE ) ; + ::close( m_fd ) ; + m_open = false ; + } +} + +void CJTAG::selectIR() +{ + if ( m_state == ST_TEST_LOGIC_RESET ) + execute( 0, 0 ) ; + + while ( m_state != ST_SELECT_IR_SCAN ) + execute( 1, 0 ) ; + + // capture ir + execute( 0, 0 ) ; + + // shift ir + execute( 0, 0 ) ; +} + +void CJTAG::setIR( bool *instruction, int len ) +{ + while ( len-- ) + execute( 0, *instruction++ ) ; + +} + +void CJTAG::exitIR( bool b ) +{ + // exit ir + execute( 1, b ) ; + + // update ir + execute( 1, 0 ) ; +} + +void CJTAG::selectRunTestIdle() +{ + if ( m_state != ST_RUN_TEST_IDLE ) { + if ( m_state == ST_SELECT_IR_SCAN || m_state == ST_SELECT_DR_SCAN ) + execute( 0, 0 ) ; + while ( m_state != ST_UPDATE_DR && m_state != ST_UPDATE_IR ) + execute( 1, 0 ) ; + execute( 0, 0 ) ; + } +} + +void CJTAG::selectTestLogicReset() +{ + while ( m_state != ST_TEST_LOGIC_RESET ) + execute( 1, 0 ) ; +} + +void CJTAG::selectDR() +{ + if ( m_state == ST_TEST_LOGIC_RESET ) + execute( 0, 0 ) ; + + while ( m_state != ST_SELECT_DR_SCAN ) + execute( 1, 0 ) ; + + // capture dr + execute( 0, 0 ) ; + + // shift dr + execute( 0, 0 ) ; +} + +void CJTAG::setDR( bool *data, bool *out, int len ) +{ + // shift dr in, and get data + if ( m_verbose ) { + while ( len-- ) { + cout << (*data ? "1" : "0") ; + *out++ = execute( 0, *data++ ) ; + } + cout << endl ; + } else { + while ( len-- ) + *out++ = execute( 0, *data++ ) ; + } +} + +void CJTAG::setVerbose( bool verbose ) +{ + m_verbose = verbose ; +} + +bool CJTAG::exitDR( bool data ) +{ + // exit dr + return execute( 1, data ) ; +} + + +inline bool CJTAG::step( bool TMS, bool TDI ) +{ + uint8_t c ; + int status ; + + c = XILINX_PROG ; // output enable + if ( TMS ) c |= JTAG_TMS ; + if ( TDI ) c |= JTAG_TDI ; + + c |= JTAG_CLK ; + ioctl( m_fd, PPWDATA, &c ) ; + c &= ~JTAG_CLK ; + ioctl( m_fd, PPWDATA, &c ) ; + + // read TDO + ioctl( m_fd, PPRSTATUS, &status ) ; + + c |= JTAG_CLK ; + ioctl( m_fd, PPWDATA, &c ) ; + + return (status & JTAG_TDO) != 0 ; +} + +bool CJTAG::execute( bool TMS, bool TDI ) +{ + bool TDO ; + + TDO = step( TMS , TDI ) ; + + switch ( m_state ) { + case ST_TEST_LOGIC_RESET: + if ( TMS ) + m_state = ST_TEST_LOGIC_RESET ; + else + m_state = ST_RUN_TEST_IDLE ; + break ; + case ST_RUN_TEST_IDLE: + if ( TMS ) + m_state = ST_SELECT_DR_SCAN ; + else + m_state = ST_RUN_TEST_IDLE ; + break ; + case ST_SELECT_DR_SCAN: + if ( TMS ) + m_state = ST_SELECT_IR_SCAN ; + else + m_state = ST_CAPTURE_DR ; + break ; + case ST_CAPTURE_DR: + if ( TMS ) + m_state = ST_EXIT_DR ; + else + m_state = ST_SHIFT_DR ; + break ; + case ST_SHIFT_DR: + if ( TMS ) + m_state = ST_EXIT_DR ; + else + m_state = ST_SHIFT_DR ; + break ; + case ST_EXIT_DR: + if ( TMS ) + m_state = ST_UPDATE_DR ; + else + m_state = ST_PAUSE_DR ; + break ; + case ST_PAUSE_DR: + if ( TMS ) + m_state = ST_EXIT2_DR ; + else + m_state = ST_PAUSE_DR ; + break ; + case ST_EXIT2_DR: + if ( TMS ) + m_state = ST_UPDATE_DR ; + else + m_state = ST_SHIFT_DR ; + break ; + case ST_UPDATE_DR: + if ( TMS ) + m_state = ST_SELECT_DR_SCAN ; + else + m_state = ST_RUN_TEST_IDLE ; + break ; + case ST_SELECT_IR_SCAN: + if ( TMS ) + m_state = ST_TEST_LOGIC_RESET ; + else + m_state = ST_CAPTURE_IR ; + break ; + case ST_CAPTURE_IR: + if ( TMS ) + m_state = ST_EXIT_IR ; + else + m_state = ST_SHIFT_IR ; + break ; + case ST_SHIFT_IR: + if ( TMS ) + m_state = ST_EXIT_IR ; + else + m_state = ST_SHIFT_IR ; + break ; + case ST_EXIT_IR: + if ( TMS ) + m_state = ST_UPDATE_IR ; + else + m_state = ST_PAUSE_IR ; + break ; + case ST_PAUSE_IR: + if ( TMS ) + m_state = ST_EXIT2_IR ; + else + m_state = ST_PAUSE_IR ; + break ; + case ST_EXIT2_IR: + if ( TMS ) + m_state = ST_UPDATE_IR ; + else + m_state = ST_SHIFT_IR ; + break ; + case ST_UPDATE_IR: + if ( TMS ) + m_state = ST_SELECT_DR_SCAN ; + else + m_state = ST_RUN_TEST_IDLE ; + break ; + default: + break ; + } + +// cout << "state( " << (TMS != 0) << ", " << (TDI != 0) << "): " << jtag_states[ m_state ] << "\r\n" ; + + return TDO ; +} + +void CJTAG::printState() +{ + cout << "State = " << jtag_states[ m_state ] << endl ; +} |