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

jtag_usb.c

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 
00027 #include "ezusb.h"
00028 #include "jtag_order.h"
00029 
00030 /* output */
00031 #define JTAG_TMS (1<<2)
00032 #define JTAG_CLK (1<<0)
00033 #define JTAG_TDI (1<<5)
00034 #define JTAG_PWR (1<<7)
00035 /* input */
00036 #define JTAG_TDO (1<<1)
00037 #define JTAG_CPURESET (1<<4)
00038 #define JTAG_TRST (1<<3)
00039 
00040 // 5 bits JTAG commands for the Intel PXA250.
00041 #define JTAG_IRLENGTH 5
00042 
00043 #define JTAG_REG_MAX_BIT 64
00044 #define JTAG_REG_MAX_BYTE (JTAG_REG_MAX_BIT>>3)
00045 #define JTAG_CMD_MAX_BYTE JTAG_REG_MAX_BYTE+1
00046 
00047 #define assert(expr) if (!(expr)) Error()
00048 
00049 /*#define GETBIT(s, i) (((s)[(i)>>3])&(1<<((i)&0x7)))
00050 #define SETBIT(s, i) (((s)[(i)>>3])|=(1<<((i)&0x7)))
00051 #define CLRBIT(s, i) (((s)[(i)>>3])&=~(1<<((i)&0x7)))*/
00052 
00053 BOOL jtagRestarted;
00054 BOOL dregWriteOnly;
00055 
00056 void memcpy(unsigned char *_dest, unsigned char *_src, unsigned int size)
00057 {
00058         unsigned int counter=size;
00059         while (counter--)
00060                 *_dest++=*_src++;
00061 }
00062 
00063 void jtagReg(unsigned char *_data, unsigned char length)
00064 {
00065         unsigned char *input_pointer;
00066         unsigned char *output_pointer;
00067         unsigned char count;
00068         unsigned char input, value;
00069         unsigned char output = 0;
00070 
00071         input_pointer = _data;
00072         output_pointer = _data;
00073 
00074         /* select -> capture */
00075         OUTB=JTAG_PWR;
00076         OUTB=JTAG_PWR | JTAG_CLK;
00077 
00078         /* capture -> shift */
00079         OUTB=JTAG_PWR;
00080         OUTB=JTAG_PWR | JTAG_CLK;
00081 
00082         /* read/writing */
00083         if (dregWriteOnly) {
00084 #ifndef BROKEN
00085                 for (count = 0; count < length; count ++)
00086                 {
00087                         if ((count & 0x7) == 0)
00088                         {
00089                                 /* fetch next word of data */
00090                                 input = *input_pointer;
00091                                 input_pointer ++;
00092                         }
00093 
00094                         value = JTAG_PWR;
00095 
00096                         if (input & 0x01)
00097                                 value = value | JTAG_TDI;
00098 
00099                         if (count == (length -1))
00100                         {
00101                                 /* shift ->  exit, as it's the last bit */
00102                                 value = value | JTAG_TMS;
00103                         }
00104 
00105                         OUTB=value;
00106                         OUTB=value | JTAG_CLK;
00107 
00108                         input = input >> 1;
00109 
00110                         // aucune idee de pourquoi il y a besoin de ca !
00111                         if ((count & 0x7))// != 0x7*/)
00112                         {
00113                                 _asm
00114                                         nop
00115                                 _endasm;
00116                         }
00117                 }
00118 
00119 #else
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                         OUTB=value;
00141                         OUTB=value | JTAG_CLK;
00142 
00143                         if ((PINSB & 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 #endif
00157         } else {
00158                 for (count = 0; count < length; count ++)
00159                 {
00160                         if ((count & 0x7) == 0)
00161                         {
00162                                 /* fetch next word of data */
00163                                 input = *input_pointer;
00164                                 input_pointer ++;
00165                         }
00166 
00167                         value = JTAG_PWR;
00168 
00169                         if (input & 0x01)
00170                                 value = value | JTAG_TDI;
00171 
00172                         if (count == (length -1))
00173                         {
00174                                 /* shift ->  exit, as it's the last bit */
00175                                 value = value | JTAG_TMS;
00176                         }
00177 
00178                         OUTB=value;
00179                         OUTB=value | JTAG_CLK;
00180 
00181                         if ((PINSB & JTAG_TDO) != 0)
00182                                 output = output | (1 << (count & 0x7));
00183 
00184                         input = input >> 1;
00185 
00186                         if ((count & 0x7) == 0x7)
00187                         {
00188                                 /* store recieved word of data */
00189                                 *output_pointer = output;
00190                                 output_pointer ++;
00191                                 output = 0;
00192                         }
00193                 }
00194                 /* ensure that the output is captured if less than whole long word */
00195                 if (length & 0x7)
00196                         *output_pointer = output;
00197         }
00198 
00199         /* exit -> update */
00200         OUTB=JTAG_PWR | JTAG_TMS;
00201         OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00202 
00203 #ifdef _FORCE_IDLE_RUN_
00204         if (jtagRestarted)
00205         {
00206 #endif
00207                 /* update -> Idle/Run */
00208                 OUTB=JTAG_PWR;
00209                 OUTB=JTAG_PWR | JTAG_CLK;
00210                 OUTB=JTAG_PWR;
00211 #ifdef _FORCE_IDLE_RUN_
00212         }
00213         else
00214         {
00215                 /* update -> select DR */
00216                 OUTB=JTAG_PWR | JTAG_TMS;
00217                 OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00218                 OUTB=JTAG_PWR | JTAG_TMS;
00219         }
00220 #endif
00221 }
00222 
00223 void ireg(unsigned char *_data)
00224 {
00225 #ifdef _FORCE_IDLE_RUN_
00226         if (jtagRestarted == 1)
00227         {
00228                 /* this is only output if you have come from IDLE/RUN */
00229                 jtagRestarted = 0;
00230 #endif
00231 
00232                 /* idle -> select DR */
00233                 OUTB=JTAG_PWR | JTAG_TMS;
00234                 OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00235 #ifdef _FORCE_IDLE_RUN_
00236         }
00237 #endif
00238 
00239         /* select DR -> select IR */
00240         OUTB=JTAG_PWR | JTAG_TMS;
00241         OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00242 
00243         jtagReg(_data, JTAG_IRLENGTH);
00244 }
00245 
00246 void dreg(unsigned char *_data, unsigned char length)
00247 {
00248 #ifdef _FORCE_IDLE_RUN_
00249         if (jtagRestarted == 1)
00250         {
00251                 /* this is only output if you have come from IDLE/RUN */
00252                 jtagRestarted = 0;
00253 #endif
00254 
00255                 /* idle -> select DR */
00256                 OUTB=JTAG_PWR | JTAG_TMS;
00257                 OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00258 #ifdef _FORCE_IDLE_RUN_
00259         }
00260 #endif
00261 
00262         /* we always go via Idle/Run for data register stuff */
00263         jtagRestarted = 1;
00264         jtagReg(_data, length);
00265         // state is now run test / Idle.
00266 }
00267 
00268 void jtagReset(void)
00269 {
00270         unsigned char loop_count;
00271 
00272         /* Go out of nTRST if in it */
00273         OUTB=JTAG_PWR;
00274         OUTB=JTAG_PWR | JTAG_CLK;
00275 
00276         for(loop_count = 0; loop_count < 5; loop_count++)
00277         {
00278                 /* goto Test Logic Reset and stay there */
00279                 OUTB=JTAG_PWR | JTAG_TMS;
00280                 OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;
00281         }
00282 
00283         /* Test Logic Reset -> Idle */
00284         OUTB=JTAG_PWR;
00285         OUTB=JTAG_PWR | JTAG_CLK;
00286         OUTB=JTAG_PWR;
00287         OUTB=JTAG_PWR | JTAG_CLK;
00288         OUTB=JTAG_PWR;
00289 
00290         jtagRestarted = 1;
00291 }
00292 
00293 void cpuReset(BOOL state)
00294 {
00295         if (state)
00296         {
00297                 /* put cpu_reset line to 0 (ouput and zero) */
00298                 //OUTB&=~JTAG_CPURESET;
00299                 OEB|=JTAG_CPURESET;
00300         }
00301         else
00302         {
00303                 /* put cpu_reset line high Z (input) */
00304                 OEB&=~JTAG_CPURESET;
00305         }
00306 }
00307 
00308 void trst(BOOL state)
00309 {
00310         if (state)
00311         {
00312                 /* put trst line to 0 (ouput and zero) */
00313                 //OUTB&=~JTAG_TRST;
00314                 OEB|=JTAG_TRST;
00315         }
00316         else
00317         {
00318                 /* put trst line high Z (input) */
00319                 OEB&=~JTAG_TRST;
00320         }
00321 }
00322 
00323 void idle(unsigned int nbTCK)
00324 {
00325         unsigned int i;
00326         for (i=0; i<nbTCK; i++)
00327         {
00328                 OUTB=JTAG_PWR;
00329                 OUTB=JTAG_PWR | JTAG_CLK;
00330         }
00331         OUTB=JTAG_PWR;
00332 }
00333 
00334 void selfTest(void)
00335 {
00336         unsigned char c=1;
00337         unsigned short i;
00338         while (c!=0x80)
00339         {
00340                 i=0;
00341                 while (i<0x8000)
00342                         i++;
00343                 c<<=1;
00344                 OUTC=c;
00345         }
00346         while (c!=0x00)
00347         {
00348                 i=0;
00349                 while (i<0x8000)
00350                         i++;
00351                 c>>=1;
00352                 OUTC=c;
00353         }
00354 }
00355 
00356 void Error(void)
00357 {
00358         unsigned short i=0;
00359         while(1)
00360         {
00361                 if ((i&0xFFFF)<0x8000)
00362                         OUTC=0xFF;
00363                 else
00364                         OUTC=0x00;
00365                 i++;
00366         }
00367 }
00368 
00369 void interpreteJtagCommand(void)
00370 {
00371         unsigned char buffer[8];
00372 
00373         unsigned char bufferPos=0;
00374 
00375         // Loop while there is jtag command in the buffer
00376         while (bufferPos<OUT2BC)
00377         {
00378 
00379                 switch (OUT2BUF[bufferPos])
00380                 {
00381                         case JO_SELF_TEST:
00382                                 {
00383                                         //assert(OUT2BC==1);
00384                                         selfTest();
00385                                         IN2BUF[0]=0xBC;
00386                                         IN2BC=1;
00387                                         bufferPos++;
00388                                 }
00389                                 break;
00390 
00391                         case JO_IREG:
00392                                 {
00393                                         //assert(OUT2BC==2);
00394                                         memcpy(buffer, OUT2BUF+bufferPos+1, 1);
00395                                         ireg(buffer);
00396                                         memcpy(IN2BUF, buffer, 1);
00397                                         IN2BC=1;
00398                                         bufferPos+=2;
00399                                 }
00400                                 break;
00401 
00402                         case JO_DREG:
00403                                 {
00404                                         unsigned char dataLength=(OUT2BUF[bufferPos+1]>>3)+(OUT2BUF[bufferPos+1] & 7 ? 1 : 0);
00405                                         memcpy(buffer, OUT2BUF+bufferPos+2, dataLength);
00406                                         dreg(buffer, OUT2BUF[bufferPos+1]);
00407                                         memcpy(IN2BUF, buffer, dataLength);
00408                                         IN2BC=dataLength;
00409                                         bufferPos+=2+dataLength;
00410                                 }
00411                                 break;
00412 
00413                         case JO_DREG_WRITE_ONLY:
00414                                 {
00415                                         unsigned char dataLength=(OUT2BUF[bufferPos+1]>>3)+(OUT2BUF[bufferPos+1] & 7 ? 1 : 0);
00416                                         dregWriteOnly = 1;
00417                                         dreg(OUT2BUF+bufferPos+2, OUT2BUF[bufferPos+1]);
00418                                         bufferPos+=2+dataLength;
00419                                         dregWriteOnly = 0;
00420                                 }
00421                                 break;
00422 
00423                         case JO_JTAG_RESET:
00424                                 {
00425                                         //assert(OUT2BC==1);
00426                                         jtagReset();
00427                                         bufferPos++;
00428                                 }
00429                                 break;
00430 
00431                         case JO_CPU_RESET:
00432                                 {
00433                                         //assert(OUT2BC==2);
00434                                         cpuReset(OUT2BUF[bufferPos+1]);
00435                                         bufferPos+=2;
00436                                 }
00437                                 break;
00438 
00439                         case JO_TRST:
00440                                 {
00441                                         //assert(OUT2BC==2);
00442                                         trst(OUT2BUF[bufferPos+1]);
00443                                         bufferPos+=2;
00444                                 }
00445                                 break;
00446 
00447                         case JO_IDLE:
00448                                 {
00449                                         unsigned int v2, v1;
00450                                         //assert(OUT2BC==3);
00451                                         v2 = OUT2BUF[bufferPos+2];
00452                                         v1 = OUT2BUF[bufferPos+1];
00453                                         idle( (v2<<8) + v1 );
00454                                         bufferPos+=3;
00455                                 }
00456                                 break;
00457 
00458                         default:
00459                                 break;
00460                 }
00461 
00462         }
00463 }
00464 
00465 void initPorts(void)
00466 {
00467         /*
00468         Port C output
00469         Port B is JTAG, mixed output input
00470         Port A input
00471         */
00472         OUTC=0x00;
00473         OEC=0xff;
00474         PORTCCFG=0x00;
00475 
00476         OUTB=0x00;
00477         OEB=JTAG_TMS|JTAG_CLK|JTAG_TDI|JTAG_PWR;
00478         PORTBCFG=0x00;
00479         
00480         OEA=0x00;
00481         PORTACFG=0x00;
00482 }
00483 
00484 void main(void)
00485 {
00486         dregWriteOnly = 0;
00487         initPorts();
00488         while(1)
00489         {
00490                 if (!(OUT2CS & bmEPBUSY))
00491                 {
00492                         if (OUT2BC>0)
00493                         {
00494                                 interpreteJtagCommand();
00495                                 OUT2BC=0;
00496                         }
00497                 }
00498         }
00499 }
00500 
00501 /*void main(void)
00502 {
00503         initPorts();
00504         int i=0;
00505 
00506         OEC=0xff;                       // Port C est tout en sorties
00507         PORTCCFG=0x00;
00508         OEB=JTAG_TMS|JTAG_CLK|JTAG_TDI|JTAG_PWR; //Port B for JTAG
00509         PORTBCFG=0x00;
00510         OEA=0x00;                       // Port A est tout en entrées
00511         PORTACFG=0x00;
00512         OUTC=0x00;                      // Mettre toutes les sorties à zéro
00513 
00514         while(1)
00515         {
00516                 idle(3);
00517                 if ((i&0xFFFF)<0x8000)
00518                         OUTC=0xFF;
00519                 else
00520                         OUTC=0x00;
00521                 i++;
00522         }
00523 }*/
00524 /*
00525 void main(void)
00526 {
00527         int i=0;
00528 
00529         OEC=0xff;                       // Port C est tout en sorties
00530         PORTCCFG=0x00;
00531         OEB=0xff;                       // Port B est tout en sorties
00532         PORTBCFG=0x00;
00533         OEA=0x00;                       // Port A est tout en entrées
00534         PORTACFG=0x00;
00535         OUTC=0x00;                      // Mettre toutes les sorties à zéro
00536 
00537         //EA=1;
00538 
00539         // On peut y aller!
00540 
00541         while(1)
00542         {
00543                 if (!(OUT2CS & bmEPBUSY))
00544                 {
00545                         if (OUT2BC>0)
00546                                 OUTC=OUT2BUF[0];
00547                         OUT2BC=0;
00548                 }
00549                 if ((i&0xFFFF)<0x8000)
00550                         OUTB=0xFF;
00551                 else
00552                         OUTB=0x00;
00553                 i++;
00554         }
00555 }*/
00556 

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