Main Page   Class Hierarchy   Alphabetical List   Compound List   File List   Compound Members   File Members  

pp_jtag.cpp

Go to the documentation of this file.
00001 /*
00002  * This file is part of Jelie,
00003  * (c) 2002 Julien Pilet <julien.pilet@epfl.ch> and
00004  * Stephane Magnenat <stephane.magnenat@epfl.ch>
00005  *
00006  * Jelie is free software; you can redistribute it
00007  * and/or modify it under the terms of the GNU General Public License as
00008  * published by the Free Software Foundation; either version 2 of the License,
00009  * or (at your option) any later version.
00010  *
00011  * Jelie is distributed in the hope that it will be useful,
00012  * but WITHOUT ANY WARRANTY; without even the implied warranty of
00013  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
00014  * GNU General Public License for more details.
00015  *
00016  * You should have received a copy of the GNU General Public License
00017  * along with Foobar; if not, write to the Free Software
00018  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
00019  */
00020 
00031 #include <unistd.h> /* for libc5 */
00032 #include <sys/io.h> /* for glibc */
00033 #include <stdio.h>
00034 #include "pp_jtag.h"
00035 
00036 #include <assert.h>
00037 
00038 //#define ALTERAPROG
00039 #define OCDEMON_WIGGLER
00040 
00041 #ifdef OCDEMON_WIGGLER
00042 
00043 /* output */
00044 #define JTAG_TMS (0x2)
00045 #define JTAG_CLK (0x4)
00046 #define JTAG_TDI (0x8)
00047 #define JTAG_PWR (0x80)
00048 #define JTAG_TRST (0x10)
00049 /* input */
00050 #define JTAG_TDO (1<<7)
00051 #define JTAG_CPURESET (1)
00052 
00053 #endif
00054 
00055 #ifdef ALTERAPROG
00056 
00057 /* output */
00058 #define JTAG_TMS (1 << 1)
00059 #define JTAG_CLK (1 << 0)
00060 #define JTAG_TDI (1 << 6)
00061 #define JTAG_PWR (0)
00062 #define JTAG_TRST (0)
00063 /* input */
00064 #define JTAG_TDO (1<<7)
00065 #define JTAG_CPURESET (0)
00066 
00067 #endif 
00068 
00069 PPJTAG::PPJTAG() : port(0x378), permBits(0x80), jtagRestarted(0) { 
00070 }
00071 
00072 bool PPJTAG::init(int argc, char **argv) {
00073         static bool first=true;
00074         assert(first);
00075         first=false;
00076         int r = ioperm(port, 3, 1)==0;
00077 
00078 #ifdef ALTERAPROG
00079         // activate autofeed to enable output.
00080         if (r>=0) {
00081                 outb(2, port + 2);
00082         } else {
00083                 perror("ioperm");
00084         }
00085 #endif
00086 
00087         //trst(true);
00088         return r;
00089 }
00090 
00091 unsigned char PPJTAG::readJTAG() { 
00092         return ~inb(port+1); 
00093 }
00094 
00095 void PPJTAG::writeJTAG(unsigned char data) { 
00096         portVal = data; 
00097         outb(data | permBits, port); 
00098 }
00099 
00100 void PPJTAG::jtagReg(unsigned char *_data, unsigned char length)
00101 {
00102         unsigned char *input_pointer;
00103         unsigned char *output_pointer;
00104         unsigned char count;
00105         unsigned char input=0, value;
00106         unsigned char output = 0;
00107 
00108         input_pointer = _data;
00109         output_pointer = _data;
00110 
00111         /* select -> capture */
00112         writeJTAG(JTAG_PWR);
00113         writeJTAG(JTAG_PWR | JTAG_CLK);
00114 
00115         /* capture -> shift */
00116         writeJTAG(JTAG_PWR);
00117         writeJTAG(JTAG_PWR | JTAG_CLK);
00118 
00119         /* read/writing */
00120         for (count = 0; count < length; count ++)
00121         {
00122                 if ((count & 0x7) == 0)
00123                 {
00124                         /* fetch next word of data */
00125                         input = *input_pointer;
00126                         input_pointer ++;
00127                 }
00128 
00129                 value = JTAG_PWR;
00130 
00131                 if (input & 0x01)
00132                         value = value | JTAG_TDI;
00133 
00134                 if (count == (length -1))
00135                 {
00136                         /* shift ->  exit, as it's the last bit */
00137                         value = value | JTAG_TMS;
00138                 }
00139 
00140                 writeJTAG(value);
00141                 writeJTAG(value | JTAG_CLK);
00142 
00143                 if ((readJTAG() & JTAG_TDO) != 0)
00144                         output = output | (1 << (count & 0x7));
00145 
00146                 input = input >> 1;
00147 
00148                 if ((count & 0x7) == 0x7)
00149                 {
00150                         /* store recieved word of data */
00151                         *output_pointer = output;
00152                         output_pointer ++;
00153                         output = 0;
00154                 }
00155         }
00156         /* ensure that the output is captured if less than whole long word */
00157         if (length & 0x7)
00158                 *output_pointer = output;
00159 
00160         /* exit -> update */
00161         writeJTAG(JTAG_PWR | JTAG_TMS);
00162         writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00163 
00164 #ifdef _FORCE_IDLE_RUN_
00165         if (jtagRestarted)
00166         {
00167 #endif
00168                 /* update -> Idle/Run */
00169                 writeJTAG(JTAG_PWR);
00170                 writeJTAG(JTAG_PWR | JTAG_CLK);
00171                 writeJTAG(JTAG_PWR);
00172 #ifdef _FORCE_IDLE_RUN_
00173         }
00174         else
00175         {
00176                 /* update -> select DR */
00177                 writeJTAG(JTAG_PWR | JTAG_TMS);
00178                 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00179                 writeJTAG(JTAG_PWR | JTAG_TMS);
00180         }
00181 #endif
00182 }
00183 
00184 void PPJTAG::ireg(unsigned char *_data)
00185 {
00186 #ifdef _FORCE_IDLE_RUN_
00187         if (jtagRestarted == 1)
00188         {
00189                 /* this is only output if you have come from IDLE/RUN */
00190                 jtagRestarted = 0;
00191 #endif
00192 
00193                 /* idle -> select DR */
00194                 writeJTAG(JTAG_PWR | JTAG_TMS);
00195                 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00196 #ifdef _FORCE_IDLE_RUN_
00197         }
00198 #endif
00199 
00200         /* select DR -> select IR */
00201         writeJTAG(JTAG_PWR | JTAG_TMS);
00202         writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00203 
00204         jtagReg(_data, JTAG_IRLENGTH);
00205 }
00206 
00207 void PPJTAG::dreg(unsigned char *data, unsigned char length, bool wonly)
00208 {
00209 #ifdef _FORCE_IDLE_RUN_
00210         if (jtagRestarted == 1)
00211         {
00212                 /* this is only output if you have come from IDLE/RUN */
00213                 jtagRestarted = 0;
00214 #endif
00215 
00216                 /* idle -> select DR */
00217                 writeJTAG(JTAG_PWR | JTAG_TMS);
00218                 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00219 #ifdef _FORCE_IDLE_RUN_
00220         }
00221 #endif
00222 
00223         /* we always go via Idle/Run for data register stuff */
00224         jtagRestarted = 1;
00225         jtagReg(data, length);
00226         // state is now run test / Idle.
00227 }
00228 
00229 void PPJTAG::jtagReset(void)
00230 {
00231         unsigned char loop_count;
00232 
00233         trst(true);
00234         trst(false);
00235 
00236         /* Go out of nTRST if in it */
00237         writeJTAG(JTAG_PWR);
00238         writeJTAG(JTAG_PWR | JTAG_CLK);
00239 
00240         for(loop_count = 0; loop_count < 5; loop_count++)
00241         {
00242                 /* goto Test Logic Reset and stay there */
00243                 writeJTAG(JTAG_PWR | JTAG_TMS);
00244                 writeJTAG(JTAG_PWR | JTAG_TMS | JTAG_CLK);
00245         }
00246 
00247         /* Test Logic Reset -> Idle */
00248         writeJTAG(JTAG_PWR);
00249         writeJTAG(JTAG_PWR | JTAG_CLK);
00250         writeJTAG(JTAG_PWR);
00251         writeJTAG(JTAG_PWR | JTAG_CLK);
00252         writeJTAG(JTAG_PWR);
00253 
00254         jtagRestarted = 1;
00255 }
00256 
00257 void PPJTAG::cpuReset(bool state) {
00258         if (state) {
00259                 /* put cpu_reset line to 0 (ouput and zero) */
00260                 permBits |= JTAG_CPURESET;
00261                 writeJTAG(portVal);
00262         }
00263         else {
00264                 /* put cpu_reset line high Z (input) */
00265                 permBits &= ~JTAG_CPURESET;
00266                 writeJTAG(portVal);
00267         }
00268 }
00269 
00270 void PPJTAG::trst(bool state) {
00271         if (!state)
00272         {
00273                 /* put trst line to 0 (ouput and zero) */
00274                 //OUTB&=~JTAG_TRST;
00275                 permBits|=JTAG_TRST;
00276                 writeJTAG(portVal);
00277         }
00278         else
00279         {
00280                 /* put trst line high Z (input) */
00281                 permBits&=~JTAG_TRST;
00282                 writeJTAG(portVal);
00283         }
00284 }
00285 
00286 void PPJTAG::idle(unsigned int nbTCK)
00287 {
00288         unsigned int i;
00289         for (i=0; i<nbTCK; i++)
00290         {
00291                 writeJTAG(JTAG_PWR);
00292                 writeJTAG(JTAG_PWR | JTAG_CLK);
00293         }
00294         writeJTAG(JTAG_PWR);
00295 }
00296 

Generated on Fri May 16 13:01:45 2003 for Jelie by doxygen1.2.15