void cable::tms_transition(u32 seq, int cnt) { while (cnt--) { set_tms((seq & 1) ? 1 : 0); tck_cycle(); seq >>= 1; } }
void cable::shift(int num_bits, void* ptdi, void* ptdo, int last) { u8 tdi_byte, tdo_byte; int i; u8* _ptdi = (u8*)ptdi; u8* _ptdo = (u8*)ptdo; while (num_bits) { // Process on a byte-basis, LSB bytes and bits first if (_ptdi == ALL_ZEROS) tdi_byte = 0; else if (_ptdi == ALL_ONES) tdi_byte = 0xFF; else tdi_byte = *_ptdi++; tdo_byte = 0; for (i = 0; (num_bits && (i < 8)); i++) { num_bits--; if (last && !num_bits) // Exit Shift-DR state set_tms(1); // Set the new TDI value set_tdi(tdi_byte & 1); tdi_byte >>= 1; if (_ptdo) // Save TDO bit tdo_byte |= get_tdo() << i; // Clock cycle tck_cycle(1); } //* Save TDO byte if (_ptdo) *_ptdo++ = tdo_byte; } }
// LSB first. void jtag_command() { uchar *p = &PacketFromPC.raw[1]; // jtag ストリーム(for WRITE) uchar *q = &PacketToPC.raw[0]; // jtag ストリーム(for READ) uchar cnt,c; // 処理するビット数. uchar bitcnt=0; // cnt のmod 7 が入る. uchar tdi_byte=0; uchar tdo_byte=0; uchar jcmd; // jtag command uchar maxcnt; uchar mask_bit=1; // 初期値=1 、毎回 左シフト、8bit処理したら 1に戻る. while(1) { jcmd =*p++; // jtag command if(jcmd==0) return; maxcnt=jcmd & JCMD_BITCOUNT_MASK; if(jcmd & JCMD_INIT_TMS) { for(cnt=0; cnt<maxcnt; cnt++) { c = *p++; set_bit(MCLR,c & 0x80); set_bit(PGM ,c & 0x40); set_bit(PGC ,c & 0x10); wait_ums(0); set_bit(MCLR,c & 0x08); set_bit(PGM ,c & 0x04); set_bit(PGC ,c & 0x01); wait_ums(0); #if 0 // ポート出力データ. // ISP_OUT = tdi_byte & 0xf0; if( (c & 0x80)) MCLR = 1; if(!(c & 0x80)) MCLR = 0; if( (c & 0x40)) PGM = 1; if(!(c & 0x40)) PGM = 0; if( (c & 0x10)) PGC = 1; if(!(c & 0x10)) PGC = 0; wait_ums(0); // tdi_byte <<=4; // ISP_OUT = tdi_byte; if( (c & 0x08)) MCLR = 1; if(!(c & 0x08)) MCLR = 0; if( (c & 0x04)) PGM = 1; if(!(c & 0x04)) PGM = 0; if( (c & 0x01)) PGC = 1; if(!(c & 0x01)) PGC = 0; wait_ums(0); #endif } } else { bitcnt=0; // cnt のmod 7 が入る. tdi_byte=0; tdo_byte=0; mask_bit=1; // 初期値=1 、毎回 左シフト、8bit処理したら 1に戻る. set_tms(0); for(cnt=0; cnt<maxcnt; cnt++) { // ==== TCK = LOW ==== // ISP_OUT &= ~(1 << TCK); /* TCK low */ // TCK=0; set_bit(TCK ,0); if( bitcnt ==0 ) { // fetch data. tdi_byte = *p++; tdo_byte = 0; mask_bit = 1; } set_bit(TDI ,tdi_byte & mask_bit); #if 0 if(tdi_byte & mask_bit) { // ISP_OUT |= (1 << TDI); /* TDI High */ TDI=1; } else { // ISP_OUT &= ~(1 << TDI); /* TDI low */ TDI=0; } #endif if(cnt == (maxcnt-1)) { set_tms(jcmd & JCMD_LAST_TMS); } // if( inTDO != 0) { if(digitalRead(inTDO)) { tdo_byte |= mask_bit; } // ==== TCK = HIGH ==== // ISP_OUT |= (1 << TCK); /* TCK High */ // TCK=1; set_bit(TCK ,1); mask_bit <<=1; bitcnt++; if( bitcnt == 8 ) { // store data. *q++ = tdo_byte; bitcnt=0; } } *q = tdo_byte; } } }