00001
00002
00003
00004
00005
00006
00007
00008
00009
00010
00011
00012
00013
00014
00015
00016
00017
00018
00019
00020
00030 #include "ezusb_jtag.h"
00031 #include "jtag_order.h"
00032 #include <string.h>
00033 #include <assert.h>
00034 #include <unistd.h>
00035 #include <signal.h>
00036
00037 #ifdef HAVE_CONFIG_H
00038 #include <config.h>
00039 #else
00040 #define RETSIGTYPE void
00041 #endif
00042
00043
00044
00045 EzUSBJTAG *ezusb_jtag_ptr=NULL;
00046
00048 RETSIGTYPE criticalStop(int i)
00049 {
00050 fprintf(stderr, "Received unexpected critical stop, resetting USB and quitting\n");
00051 if (ezusb_jtag_ptr)
00052 ezusb_jtag_ptr->forceClose();
00053 exit(-1);
00054 }
00055
00056
00057 EzUSBJTAG::EzUSBJTAG()
00058 :EzUSB(0)
00059 {
00060 queuePos=0;
00061
00062 signal(SIGTERM, criticalStop);
00063 signal(SIGINT, criticalStop);
00064 signal(SIGQUIT, criticalStop);
00065 signal(SIGSEGV, criticalStop);
00066 signal(SIGPIPE, criticalStop);
00067 }
00068
00069 EzUSBJTAG::~EzUSBJTAG()
00070 {
00071
00072 signal(SIGTERM, SIG_DFL);
00073 signal(SIGINT, SIG_DFL);
00074 signal(SIGQUIT, SIG_DFL);
00075 signal(SIGSEGV, SIG_DFL);
00076 signal(SIGPIPE, SIG_DFL);
00077 }
00078
00079 void EzUSBJTAG::writeAndReadBuffer(unsigned char *buffer, int toWrite, int toRead, unsigned long delay)
00080 {
00081 if (toWrite)
00082 {
00083 int wReturn=usb_bulk_write(devHandle, 2, (char *)buffer, toWrite, 50);
00084 if (wReturn<0)
00085 fprintf(stderr, "USB : WRITE ERROR : %s\n", usb_strerror());
00086 }
00087 if (delay)
00088 usleep(delay);
00089 if (toRead)
00090 {
00091 int rReturn=usb_bulk_read(devHandle, 2, (char *)buffer, toRead, 50);
00092 if (rReturn<0)
00093 fprintf(stderr, "USB : READ ERROR : %s\n", usb_strerror());
00094 }
00095 }
00096
00097 bool EzUSBJTAG::init(int argc, char **argv)
00098 {
00099 parseCmdLine(argc, argv);
00100 if (!findDevice())
00101 return false;
00102
00103 ezusb_jtag_ptr = this;
00104
00105 if (!downloadFirmware("jtag_usb.ihx")) {
00106 return false;
00107 }
00108 if (usb_set_altinterface(devHandle, 1)<0)
00109 {
00110 fprintf(stderr, "USB : SET ALT ERROR : %s\n", usb_strerror());
00111 return false;
00112 }
00113
00114 unsigned char c=JO_SELF_TEST;
00115
00116 #ifdef VERBOSE_JTAG_CMD
00117 printf("JTAG : Sending JO_SELF_TEST\n");
00118 #endif
00119
00120 writeAndReadBuffer(&c, 1, 1, 2000000);
00121 if (c!=0xBC)
00122 {
00123 fprintf(stderr, "SELF TEST FAILURE (received 0x%02x instead of 0xBC) !!!\n", c);
00124 return false;
00125 }
00126 return true;
00127 }
00128
00129 void EzUSBJTAG::ireg(unsigned char *data)
00130 {
00131 unsigned char buffer[2];
00132
00133 buffer[0]=JO_IREG;
00134 buffer[1]=data[0];
00135
00136 #ifdef VERBOSE_JTAG_CMD
00137 printf("JTAG : Sending JO_IREG\n");
00138 #endif
00139
00140 flushQueue();
00141 writeAndReadBuffer(buffer, 2, 1);
00142
00143 data[0]=buffer[0];
00144 }
00145
00146 void EzUSBJTAG::dreg(unsigned char *data, unsigned char length, bool writeOnly=false)
00147 {
00148 unsigned char buffer[10];
00149 unsigned char dataLength=(length>>3)+(length & 7 ? 1 : 0);
00150
00151 assert(length<=64);
00152
00153 #ifdef VERBOSE_JTAG_CMD
00154 printf("JTAG : Sending JO_DREG\n");
00155 #endif
00156
00157 if (writeOnly)
00158 {
00159
00160 int dregSize=2+dataLength;
00161 if (queuePos+dregSize>64)
00162 flushQueue();
00163
00164 queue[queuePos]=JO_DREG_WRITE_ONLY;
00165 queue[queuePos+1]=length;
00166 memcpy(queue+queuePos+2, data, dataLength);
00167
00168 queuePos+=dregSize;
00169 }
00170 else
00171 {
00172 buffer[0]=JO_DREG;
00173 buffer[1]=length;
00174 memcpy(buffer+2, data, dataLength);
00175
00176 flushQueue();
00177 writeAndReadBuffer(buffer, dataLength+2, (writeOnly ? 0 : dataLength));
00178
00179 memcpy(data, buffer, dataLength);
00180 }
00181 }
00182
00183 void EzUSBJTAG::jtagReset(void)
00184 {
00185 unsigned char buffer[1];
00186
00187 buffer[0]=JO_JTAG_RESET;
00188
00189 #ifdef VERBOSE_JTAG_CMD
00190 printf("JTAG : Sending JO_JTAG_RESET\n");
00191 #endif
00192
00193 flushQueue();
00194 writeAndReadBuffer(buffer, 1, 0);
00195 }
00196
00197 void EzUSBJTAG::cpuReset(bool state)
00198 {
00199 unsigned char buffer[2];
00200
00201 buffer[0]=JO_CPU_RESET;
00202 buffer[1]=state ? 1 : 0;
00203
00204 #ifdef VERBOSE_JTAG_CMD
00205 printf("JTAG : Sending JO_CPU_RESET\n");
00206 #endif
00207
00208 flushQueue();
00209 writeAndReadBuffer(buffer, 2, 0);
00210 }
00211
00212 void EzUSBJTAG::trst(bool state)
00213 {
00214 unsigned char buffer[2];
00215
00216 buffer[0]=JO_TRST;
00217 buffer[1]=state ? 1 : 0;
00218
00219 #ifdef VERBOSE_JTAG_CMD
00220 printf("JTAG : Sending JO_TRST\n");
00221 #endif
00222
00223 flushQueue();
00224 writeAndReadBuffer(buffer, 2, 0);
00225 }
00226
00227 void EzUSBJTAG::idle(unsigned int nbTCK)
00228 {
00229 unsigned char buffer[3];
00230
00231 buffer[0]=JO_IDLE;
00232 buffer[1]=nbTCK&0xFF;
00233 buffer[2]=(nbTCK>>8)&0xFF;
00234
00235 #ifdef VERBOSE_JTAG_CMD
00236 printf("JTAG : Sending JO_IDLE\n");
00237 #endif
00238
00239 flushQueue();
00240 writeAndReadBuffer(buffer, 3, 0);
00241 }
00242
00243 void EzUSBJTAG::flushQueue(void)
00244 {
00245 assert(queuePos<=64);
00246 if (queuePos>0)
00247 {
00248 writeAndReadBuffer(queue, queuePos, 0);
00249 queuePos=0;
00250 }
00251 }