📄 jtag_usb.c
字号:
/* * This file is part of Jelie, * (c) 2002 Julien Pilet <julien.pilet@epfl.ch> and * Stephane Magnenat <stephane.magnenat@epfl.ch> * * Jelie 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. * * Jelie 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 Foobar; if not, write to the Free Software * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA 02111-1307 USA *//*! This is the program that goes on the EzUSB microcontroller * * \author Julien Pilet <julien.pilet@epfl.ch> * \author Stephane Magnenat <stephane.magnenat@epfl.ch> */#include "ezusb.h"#include "jtag_order.h"/* output */#define JTAG_TMS (1<<2)#define JTAG_CLK (1<<0)#define JTAG_TDI (1<<5)#define JTAG_PWR (1<<7)/* input */#define JTAG_TDO (1<<1)#define JTAG_CPURESET (1<<4)#define JTAG_TRST (1<<3)// 5 bits JTAG commands for the Intel PXA250.#define JTAG_IRLENGTH 5#define JTAG_REG_MAX_BIT 64#define JTAG_REG_MAX_BYTE (JTAG_REG_MAX_BIT>>3)#define JTAG_CMD_MAX_BYTE JTAG_REG_MAX_BYTE+1#define assert(expr) if (!(expr)) Error()/*#define GETBIT(s, i) (((s)[(i)>>3])&(1<<((i)&0x7)))#define SETBIT(s, i) (((s)[(i)>>3])|=(1<<((i)&0x7)))#define CLRBIT(s, i) (((s)[(i)>>3])&=~(1<<((i)&0x7)))*/BOOL jtagRestarted;BOOL dregWriteOnly;void memcpy(unsigned char *_dest, unsigned char *_src, unsigned int size){ unsigned int counter=size; while (counter--) *_dest++=*_src++;}void jtagReg(unsigned char *_data, unsigned char length){ unsigned char *input_pointer; unsigned char *output_pointer; unsigned char count; unsigned char input, value; unsigned char output = 0; input_pointer = _data; output_pointer = _data; /* select -> capture */ OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; /* capture -> shift */ OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; /* read/writing */ if (dregWriteOnly) {#ifndef BROKEN for (count = 0; count < length; count ++) { if ((count & 0x7) == 0) { /* fetch next word of data */ input = *input_pointer; input_pointer ++; } value = JTAG_PWR; if (input & 0x01) value = value | JTAG_TDI; if (count == (length -1)) { /* shift -> exit, as it's the last bit */ value = value | JTAG_TMS; } OUTB=value; OUTB=value | JTAG_CLK; input = input >> 1; // aucune idee de pourquoi il y a besoin de ca ! if ((count & 0x7))// != 0x7*/) { _asm nop _endasm; } }#else for (count = 0; count < length; count ++) { if ((count & 0x7) == 0) { /* fetch next word of data */ input = *input_pointer; input_pointer ++; } value = JTAG_PWR; if (input & 0x01) value = value | JTAG_TDI; if (count == (length -1)) { /* shift -> exit, as it's the last bit */ value = value | JTAG_TMS; } OUTB=value; OUTB=value | JTAG_CLK; if ((PINSB & JTAG_TDO) != 0) output = output | (1 << (count & 0x7)); input = input >> 1; if ((count & 0x7) == 0x7) { /* store recieved word of data */ *output_pointer = output; output_pointer ++; output = 0; } }#endif } else { for (count = 0; count < length; count ++) { if ((count & 0x7) == 0) { /* fetch next word of data */ input = *input_pointer; input_pointer ++; } value = JTAG_PWR; if (input & 0x01) value = value | JTAG_TDI; if (count == (length -1)) { /* shift -> exit, as it's the last bit */ value = value | JTAG_TMS; } OUTB=value; OUTB=value | JTAG_CLK; if ((PINSB & JTAG_TDO) != 0) output = output | (1 << (count & 0x7)); input = input >> 1; if ((count & 0x7) == 0x7) { /* store recieved word of data */ *output_pointer = output; output_pointer ++; output = 0; } } /* ensure that the output is captured if less than whole long word */ if (length & 0x7) *output_pointer = output; } /* exit -> update */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;#ifdef _FORCE_IDLE_RUN_ if (jtagRestarted) {#endif /* update -> Idle/Run */ OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; OUTB=JTAG_PWR;#ifdef _FORCE_IDLE_RUN_ } else { /* update -> select DR */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK; OUTB=JTAG_PWR | JTAG_TMS; }#endif}void ireg(unsigned char *_data){#ifdef _FORCE_IDLE_RUN_ if (jtagRestarted == 1) { /* this is only output if you have come from IDLE/RUN */ jtagRestarted = 0;#endif /* idle -> select DR */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;#ifdef _FORCE_IDLE_RUN_ }#endif /* select DR -> select IR */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK; jtagReg(_data, JTAG_IRLENGTH);}void dreg(unsigned char *_data, unsigned char length){#ifdef _FORCE_IDLE_RUN_ if (jtagRestarted == 1) { /* this is only output if you have come from IDLE/RUN */ jtagRestarted = 0;#endif /* idle -> select DR */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK;#ifdef _FORCE_IDLE_RUN_ }#endif /* we always go via Idle/Run for data register stuff */ jtagRestarted = 1; jtagReg(_data, length); // state is now run test / Idle.}void jtagReset(void){ unsigned char loop_count; /* Go out of nTRST if in it */ OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; for(loop_count = 0; loop_count < 5; loop_count++) { /* goto Test Logic Reset and stay there */ OUTB=JTAG_PWR | JTAG_TMS; OUTB=JTAG_PWR | JTAG_TMS | JTAG_CLK; } /* Test Logic Reset -> Idle */ OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; OUTB=JTAG_PWR; jtagRestarted = 1;}void cpuReset(BOOL state){ if (state) { /* put cpu_reset line to 0 (ouput and zero) */ //OUTB&=~JTAG_CPURESET; OEB|=JTAG_CPURESET; } else { /* put cpu_reset line high Z (input) */ OEB&=~JTAG_CPURESET; }}void trst(BOOL state){ if (state) { /* put trst line to 0 (ouput and zero) */ //OUTB&=~JTAG_TRST; OEB|=JTAG_TRST; } else { /* put trst line high Z (input) */ OEB&=~JTAG_TRST; }}void idle(unsigned int nbTCK){ unsigned int i; for (i=0; i<nbTCK; i++) { OUTB=JTAG_PWR; OUTB=JTAG_PWR | JTAG_CLK; } OUTB=JTAG_PWR;}void selfTest(void){ unsigned char c=1; unsigned short i; while (c!=0x80) { i=0; while (i<0x8000) i++; c<<=1; OUTC=c; } while (c!=0x00) { i=0; while (i<0x8000) i++; c>>=1; OUTC=c; }}void Error(void){ unsigned short i=0; while(1) { if ((i&0xFFFF)<0x8000) OUTC=0xFF; else OUTC=0x00; i++; }}void interpreteJtagCommand(void){ unsigned char buffer[8]; unsigned char bufferPos=0; // Loop while there is jtag command in the buffer while (bufferPos<OUT2BC) { switch (OUT2BUF[bufferPos]) { case JO_SELF_TEST: { //assert(OUT2BC==1); selfTest(); IN2BUF[0]=0xBC; IN2BC=1; bufferPos++; } break; case JO_IREG: { //assert(OUT2BC==2); memcpy(buffer, OUT2BUF+bufferPos+1, 1); ireg(buffer); memcpy(IN2BUF, buffer, 1); IN2BC=1; bufferPos+=2; } break; case JO_DREG: { unsigned char dataLength=(OUT2BUF[bufferPos+1]>>3)+(OUT2BUF[bufferPos+1] & 7 ? 1 : 0); memcpy(buffer, OUT2BUF+bufferPos+2, dataLength); dreg(buffer, OUT2BUF[bufferPos+1]); memcpy(IN2BUF, buffer, dataLength); IN2BC=dataLength; bufferPos+=2+dataLength; } break; case JO_DREG_WRITE_ONLY: { unsigned char dataLength=(OUT2BUF[bufferPos+1]>>3)+(OUT2BUF[bufferPos+1] & 7 ? 1 : 0); dregWriteOnly = 1; dreg(OUT2BUF+bufferPos+2, OUT2BUF[bufferPos+1]); bufferPos+=2+dataLength; dregWriteOnly = 0; } break; case JO_JTAG_RESET: { //assert(OUT2BC==1); jtagReset(); bufferPos++; } break; case JO_CPU_RESET: { //assert(OUT2BC==2); cpuReset(OUT2BUF[bufferPos+1]); bufferPos+=2; } break; case JO_TRST: { //assert(OUT2BC==2); trst(OUT2BUF[bufferPos+1]); bufferPos+=2; } break; case JO_IDLE: { unsigned int v2, v1; //assert(OUT2BC==3); v2 = OUT2BUF[bufferPos+2]; v1 = OUT2BUF[bufferPos+1]; idle( (v2<<8) + v1 ); bufferPos+=3; } break; default: break; } }}void initPorts(void){ /* Port C output Port B is JTAG, mixed output input Port A input */ OUTC=0x00; OEC=0xff; PORTCCFG=0x00; OUTB=0x00; OEB=JTAG_TMS|JTAG_CLK|JTAG_TDI|JTAG_PWR; PORTBCFG=0x00; OEA=0x00; PORTACFG=0x00;}void main(void){ dregWriteOnly = 0; initPorts(); while(1) { if (!(OUT2CS & bmEPBUSY)) { if (OUT2BC>0) { interpreteJtagCommand(); OUT2BC=0; } } }}/*void main(void){ initPorts(); int i=0; OEC=0xff; // Port C est tout en sorties PORTCCFG=0x00; OEB=JTAG_TMS|JTAG_CLK|JTAG_TDI|JTAG_PWR; //Port B for JTAG PORTBCFG=0x00; OEA=0x00; // Port A est tout en entr閑s PORTACFG=0x00; OUTC=0x00; // Mettre toutes les sorties
⌨️ 快捷键说明
复制代码
Ctrl + C
搜索代码
Ctrl + F
全屏模式
F11
切换主题
Ctrl + Shift + D
显示快捷键
?
增大字号
Ctrl + =
减小字号
Ctrl + -