# HG changeset patch # User Thinker K.F. Li # Date 1235278485 -28800 # Node ID 6b1594fb668f35e81addcb5a4b36faba465758ec # Parent e410832c32809cb3cb978d1b1e534d06e9aad9ae Improve performance of jtag.c and test it with Python scripts. - cp_tditdo.py send bits to TDI and hope it will feed back from TDO. - Expand loops in jtag.c to improve performance. diff -r e410832c3280 -r 6b1594fb668f py_avrjtag/cmd_proto.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/py_avrjtag/cmd_proto.py Sun Feb 22 12:54:45 2009 +0800 @@ -0,0 +1,67 @@ +import struct + +CPCMD_PING = 1 +CPCMD_SHIFT_TDI = 2 +CPCMD_SHIFT_TMS = 3 +CPCMD_SHIFT_TDI_TDO = 4 +CPCMD_PONG = 5 +CPCMD_DATA = 6 +CPCMD_ACK = 7 +CPCMD_NAK = 8 + +def csum_add(csum, c): + return (((csum << 3) | (csum >> 5)) ^ c) & 0xff + +class cmd(object): + OFF_SEQ = 2 + OFF_DSZ = 3 + OFF_CODE = 4 + FRAME_OVERHEAD = 5 + + def __init__(self, seq=0, code=0, data=''): + self.seq = seq + self.code = code + self.data = data + pass + + def to_frame(self): + csum = 0 + csum = csum_add(0, self.code) + for c in self.data: + csum = csum_add(csum, ord(c)) + pass + csum = csum_add(csum, 0) + + frame = struct.pack('BBBBB', ord('J'), ord('C'), self.seq, + len(self.data) + 1, self.code) + frame = frame + self.data + chr(csum) + return frame + + def from_frame(self, frame): + if frame[:2] != 'JC': + return -1 + + csum = 0 + for c in frame[self.OFF_CODE:]: + csum = csum_add(csum, ord(c)) + pass + if csum: + return -1 + + data_sz = ord(frame[self.OFF_DSZ]) + if data_sz != (len(frame) - self.FRAME_OVERHEAD): + return -1 + + if not data_sz: + return -1 + + self.seq = ord(frame[self.OFF_SEQ]) + self.code = ord(frame[self.OFF_CODE]) + self.data = frame[self.OFF_CODE + 1:-1] + pass + + def __repr__(self): + return '<%s {seq: %d, code: %d, data: %s}>' % \ + (self.__class__.__name__, self.seq, self.code, repr(self.data)) + pass + diff -r e410832c3280 -r 6b1594fb668f py_avrjtag/cp_ping.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/py_avrjtag/cp_ping.py Sun Feb 22 12:54:45 2009 +0800 @@ -0,0 +1,47 @@ +import cmd_proto + +def cp_ping(seq, data): + cmd = cmd_proto.cmd(seq, cmd_proto.CPCMD_PING, data) + frame = cmd.to_frame() + return frame + +def get_reply(fo): + import fcntl, os + import time + + reply = '' + fcntl.fcntl(fo.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + while True: + try: + s = os.read(fo.fileno(), 256) + except OSError: + time.sleep(0.5) + try: + s = os.read(fo.fileno(), 256) + except OSError: + break + pass + reply = reply + s + pass + return reply + +if __name__ == '__main__': + import sys + + if len(sys.argv) != 2: + print >> sys.stderr, 'Usage: prog ' + sys.exit(1) + pass + + port = sys.argv[1] + + fo = open(port, 'r+b') + cmd_str = cp_ping(0, 'hello') + fo.write(cmd_str) + fo.flush() + + frame = get_reply(fo) + cmd = cmd_proto.cmd() + cmd.from_frame(frame) + print repr(cmd) + diff -r e410832c3280 -r 6b1594fb668f py_avrjtag/cp_tditdo.py --- /dev/null Thu Jan 01 00:00:00 1970 +0000 +++ b/py_avrjtag/cp_tditdo.py Sun Feb 22 12:54:45 2009 +0800 @@ -0,0 +1,54 @@ +import cmd_proto + +def cp_tms(seq, nbits, data): + nbits_bytes = chr(nbits & 0xff) + chr(nbits >> 8) + cmd = cmd_proto.cmd(seq, cmd_proto.CPCMD_SHIFT_TDI_TDO, + nbits_bytes + data) + frame = cmd.to_frame() + return frame + +def get_reply(fo): + import fcntl, os + import time + + reply = '' + fcntl.fcntl(fo.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) + while True: + try: + s = os.read(fo.fileno(), 256) + except OSError: + time.sleep(0.13) + try: + s = os.read(fo.fileno(), 256) + except OSError: + break + pass + reply = reply + s + pass + return reply + +if __name__ == '__main__': + import sys + + if len(sys.argv) != 2: + print >> sys.stderr, 'Usage: prog ' + sys.exit(1) + pass + + port = sys.argv[1] + + fo = open(port, 'r+b') + cmd_str = cp_tms(12, 37, 'hello') + fo.write(cmd_str) + fo.flush() + + frame = get_reply(fo) + cmd = cmd_proto.cmd() + r = cmd.from_frame(frame) + if r: + print 'frame error %s' % (repr(frame)) + else: + print repr(cmd) + pass + pass + diff -r e410832c3280 -r 6b1594fb668f src/jtag.c --- a/src/jtag.c Sun Feb 22 01:40:36 2009 +0800 +++ b/src/jtag.c Sun Feb 22 12:54:45 2009 +0800 @@ -4,7 +4,7 @@ #include "avriotools.h" /* It is supposed to work at 1Mbps */ -#define CLK_DELAY() do { _delay_ms(0.0004); } while(0) +#define CLK_DELAY() void jtag_init(void) { pin_mode(&JTAG_PORT, JTAG_TCK, PM_OUTPUT); @@ -21,9 +21,9 @@ #define SEND_BIT(pin, bit) \ do { \ if(bit) \ - pin_hi(JTAG_PORT, JTAG_TDI); \ + pin_hi(JTAG_PORT, pin); \ else \ - pin_lo(JTAG_PORT, JTAG_TDI); \ + pin_lo(JTAG_PORT, pin); \ CLK_DELAY(); \ TCK_HI(); \ CLK_DELAY(); \ @@ -32,13 +32,51 @@ void jtag_tms(char *buf, int nbits) { int i; + int nbytes, byte; int byteoff, bitoff; int bit; + nbytes = nbits / 8; + for(i = 0; i < nbytes; i++) { + byte = buf[i]; + + bit = byte & 0x01; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x02; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x04; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x08; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x10; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x20; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x40; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + + bit = byte & 0x80; + SEND_BIT(JTAG_TMS, bit); + TCK_LO(); + } + + byte = buf[i]; + nbits %= 8; for(i = 0; i < nbits; i++) { - byteoff = i / 8; - bitoff = i % 8; - bit = buf[byteoff] & (1 << bitoff); + bit = byte & (1 << i); SEND_BIT(JTAG_TMS, bit); TCK_LO(); } @@ -46,35 +84,159 @@ void jtag_shift(char *buf, int nbits) { int i; + int nbytes, byte; int byteoff, bitoff; int bit; - for(i = 0; i < nbits; i++) { - byteoff = i / 8; - bitoff = i % 8; - bit = buf[byteoff] & (1 << bitoff); + nbytes = nbits / 8; + for(i = 0; i < nbytes; i++) { + byte = buf[i]; + + bit = byte & 0x01; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x02; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x04; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x08; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x10; SEND_BIT(JTAG_TDI, bit); TCK_LO(); + + bit = byte & 0x20; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x40; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + + bit = byte & 0x80; + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + } + + nbits %= 8; + if(nbits) { + byte = buf[i]; + for(i = 0; i < nbits; i++) { + bit = byte & (1 << i); + SEND_BIT(JTAG_TDI, bit); + TCK_LO(); + } } } void jtag_shift_inout(char *ibuf, char *obuf, int nbits) { - int i; + int i, j; + int nbytes, byte, obyte; + int tdo; int byteoff, bitoff; - int bit, tdo, bitmask; + int bit; - for(i = 0; i < nbits; i++) { - byteoff = i / 8; - bitoff = i % 8; - bitmask = 1 << bitoff; + nbytes = nbits / 8; + for(i = 0; i < nbytes; i++) { + byte = ibuf[i]; + obyte = 0; + + bit = byte & 0x01; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x01; + else + obyte &= ~0x01; + TCK_LO(); - bit = ibuf[byteoff] & bitmask; + bit = byte & 0x02; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x02; + else + obyte &= ~0x02; + TCK_LO(); + + bit = byte & 0x04; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x04; + else + obyte &= ~0x04; + TCK_LO(); + + bit = byte & 0x08; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x08; + else + obyte &= ~0x08; + TCK_LO(); + + bit = byte & 0x10; SEND_BIT(JTAG_TDI, bit); tdo = GET_TDO(); + if(tdo) + obyte |= 0x10; + else + obyte &= ~0x10; TCK_LO(); + + bit = byte & 0x20; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x20; + else + obyte &= ~0x20; + TCK_LO(); + + bit = byte & 0x40; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); if(tdo) - obuf[byteoff] |= bitmask; + obyte |= 0x40; + else + obyte &= ~0x40; + TCK_LO(); + + bit = byte & 0x80; + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 0x80; else - obuf[byteoff] &= ~(bitmask); + obyte &= ~0x80; + TCK_LO(); + + obuf[i] = obyte; + } + + nbits %= 8; + if(nbits) { + byte = ibuf[i]; + obyte = 0; + for(j = 0; j < nbits; j++) { + bit = byte & (1 << j); + SEND_BIT(JTAG_TDI, bit); + tdo = GET_TDO(); + if(tdo) + obyte |= 1 << j; + else + obyte &= ~(1 << j); + TCK_LO(); + } + obuf[i] = obyte; } } diff -r e410832c3280 -r 6b1594fb668f tests/cp_ping.py --- a/tests/cp_ping.py Sun Feb 22 01:40:36 2009 +0800 +++ /dev/null Thu Jan 01 00:00:00 1970 +0000 @@ -1,58 +0,0 @@ -import struct - -CP_CMD_PING = 1 - -def csum_add(csum, c): - return (((csum << 3) | (csum >> 5)) ^ c) & 0xff - -def cp_ping(seq, data): - csum = 0 - csum = csum_add(0, CP_CMD_PING) - for c in data: - csum = csum_add(csum, ord(c)) - pass - csum = csum_add(csum, 0) - - cmd_str = struct.pack('BBBBB', ord('J'), ord('C'), seq, - len(data) + 1, CP_CMD_PING) - cmd_str = cmd_str + data + chr(csum) - return cmd_str - -def get_reply(fo): - import fcntl, os - import time - - reply = '' - fcntl.fcntl(fo.fileno(), fcntl.F_SETFL, os.O_NONBLOCK) - while True: - try: - s = os.read(fo.fileno(), 256) - except OSError: - time.sleep(0.5) - try: - s = os.read(fo.fileno(), 256) - except OSError: - break - pass - reply = reply + s - pass - return reply - -if __name__ == '__main__': - import sys - - if len(sys.argv) != 2: - print >> sys.stderr, 'Usage: prog ' - sys.exit(1) - pass - - port = sys.argv[1] - - fo = open(port, 'r+b') - cmd_str = cp_ping(0, 'hello') - fo.write(cmd_str) - fo.flush() - - reply = get_reply(fo) - print repr(reply) - pass