changeset 4:6b1594fb668f

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.
author Thinker K.F. Li <thinker@branda.to>
date Sun, 22 Feb 2009 12:54:45 +0800
parents e410832c3280
children eb14cac68cbb
files py_avrjtag/cmd_proto.py py_avrjtag/cp_ping.py py_avrjtag/cp_tditdo.py src/jtag.c tests/cp_ping.py
diffstat 5 files changed, 349 insertions(+), 77 deletions(-) [+]
line wrap: on
line diff
--- /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
+
--- /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 <port device>'
+        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)
+
--- /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 <port device>'
+        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
+
--- 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;
     }
 }
--- 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 <port device>'
-        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