NAXJP とは、パラレルポートを使って、XC9500 シリーズの JTAG を 操作するもの。 config はもとより、バウンダリスキャンもできる。
現状の 0.7.3b では、XC9572XL-VQ64 には対応していない。 この対応は、わりと機械的にできた。
次は、電子工作/XC9572XLと8U245AMで作るUSBシリアルIO を NAXJP に対応 させる。
その前にコードを見てみる。
prnprt.cpp の関数群 void ClockTCK(void) TCK を ~~|_|~~ void OutputTMS(unsigned char tms) TMS 信号を出力 unsigned char TDIClkOut(unsigned char d); TDO 信号をよみ TDI を出力 した後に ClockTCK TCK ------------------+ +----------- | | +----------+ TDO o TDI --------------<XXXXX DATA XXXXXXXXX>----
なんかこんな感じ。
ianjtag の存在を忘れていた。
こいつをみると
TCK +-----------+ | | +----------+ +------------------------------- TDO o TDI ---------------<XXXXXXXX DATA XXXXXXXXXXXXXXXXXX>----- TMS ---------------<XXXXXXXX DATA XXXXXXXXXXXXXXXXXX>----- こんな風にみえる。
ううむ。TCK は正論理だったのかぁ。 となると NAXJP は、読みこむときに 次のデータを用意して渡していく。 という構造だ。
最後のビットはTMS=1で送り出すとあるが、たぶんそう言う意味だろう。
ちなみに、電子工作/XC9572XLと8U245AMで作るUSBシリアルIO はどうなるかというと..... 内部レジスタの bit 3 を 0 にすると、正論理になり、
TCK +-----------+ | | ------+----------+ +-----------+-------------------- TDO o TDI -------------------------<XXXXXXXX DATA XXXXXXXXX>----- こんな風にビットを出力できる。... 一応 OK だ。 ちょっと不安だったので、TDI と TDO をつないで ModelSIM で シミュレーションしてみた。ちゃんと出力したデータを受け取れたことを 確認できた。
1 bit づつの出力なので、もっと上位層を改造しないといけなさ そうだ。 そうすると jtagprt.cpp を見ることになる。
void JTAGReset(){ OutputTMS(1); ClockTCK(); ClockTCK(); ClockTCK(); ClockTCK(); ClockTCK(); // ->TEST_LOGIC_RESET OutputTMS(0); ClockTCK(); // ->RUN_TEST/IDLE } --------- これはサポートできる。 void JTAGReset(){ ms2 に 1 を設定 する。 write (0x1c,0x01,0xf0) ck2 に 5 bit clk を出す write (0x0d,0x01,0x00) ms2 に 0 を設定 する。 write (0x1c,0x01,0xd0) ck2 に 1 bit clk を出す write (0x09,0x01,0x00) } こんなかんじ JTAGSIRHead() JTAGSDRHead() JTAGSIRTrail(), JTAGSDRTrail(), も同様に処理できる。 ---------
さて、これ以外に重要なものは、
unsigned char JTAGDataClk(unsigned char d){ return TDIClkOut(d); }
のようだ。これも 1bit だけの処理だから... さらに上位層を見てみる。
bool ChainSVF::ShiftOutput(bool CheckTDO,bool Fill); bool ShiftOutput(bool CheckTDO,unsigned char *TDI ,unsigned char *SMASK ,unsigned char *TDO ,unsigned char *MASK ,unsigned char *IVALUE,int Bitlen; ここは処理をかえないといけない。 for(int i=iMaxChain-1;i>=0;i--){ for(int j=0;j<BitLength[i];j++){ //最後のビットはTMS=1で送り出す if(i==0 && p==0) JTAGTMSOn(); JTAGDataClk(*psma-- & *ptdi--); } } とか for(int i=0;i<Bitlen;i++){ //最後のビットはTMS=1で送り出す if(i==Bitlen - 1) JTAGTMSOn(); *IVALUE++ = JTAGDataClk(*TDI++ & *SMASK++); } こういう bit 単位の ループの処理全体で書かれるデータを全部 write で処理して、同じバイト数だけ読みこみ。それを解析する。 という 処理にしないといけない。 そうしないと、レイテンシのためにすごく遅くなってしまう。 Bitlen がいったいいくつなのか というのが 問題だが、8 などという小さな ケースの方が少ないと思っている。 (確かめないといけないけど) XC9572XL とかでも 72 bit ?