diff src/jtag.c @ 10:cc106f278d7d

Get identify of components
author Thinker K.F. Li <thinker@branda.to>
date Tue, 24 Feb 2009 13:32:04 +0800
parents 61f27549de57
children 1ea479d26fce
line wrap: on
line diff
--- a/src/jtag.c	Sun Feb 22 22:43:26 2009 +0800
+++ b/src/jtag.c	Tue Feb 24 13:32:04 2009 +0800
@@ -4,16 +4,18 @@
 #include "avriotools.h"
 
 /* It is supposed to work at 1Mbps */
-#define CLK_DELAY()
+#define CLK_DELAY() _delay_us(1)
 
 void jtag_init(void) {
     pin_mode(&JTAG_PORT, JTAG_TCK, PM_OUTPUT);
     pin_mode(&JTAG_PORT, JTAG_TMS, PM_OUTPUT);
     pin_mode(&JTAG_PORT, JTAG_TDI, PM_OUTPUT);
     pin_mode(&JTAG_PORT, JTAG_TDO, PM_INPUT);
+    pin_mode(&JTAG_PORT, JTAG_TRST, PM_OUTPUT);
     pin_lo(JTAG_PORT, JTAG_TCK);
     pin_lo(JTAG_PORT, JTAG_TMS);
     pin_lo(JTAG_PORT, JTAG_TDI);
+    pin_hi(JTAG_PORT, JTAG_TRST);
 }
 
 #define TCK_LO() pin_lo(JTAG_PORT, JTAG_TCK)
@@ -27,13 +29,30 @@
 	CLK_DELAY();				\
 	TCK_HI();				\
 	CLK_DELAY();				\
+	TCK_LO();				\
     } while(0)
 #define GET_TDO() (JTAG_PIN & _BV(JTAG_TDO))
+#define SEND_GET_BIT(pin, bit, out)		\
+    do {					\
+	if(bit)					\
+	    pin_hi(JTAG_PORT, pin);		\
+	else					\
+	    pin_lo(JTAG_PORT, pin);		\
+	CLK_DELAY();				\
+	TCK_HI();				\
+	CLK_DELAY();				\
+	out = GET_TDO();			\
+	TCK_LO();				\
+    } while(0)
 
 void jtag_trst(void) {
-    SEND_BIT(JTAG_TRST, 1);
-    TCK_LO();
     pin_lo(JTAG_PORT, JTAG_TRST);
+    SEND_BIT(JTAG_TMS, 1);
+    SEND_BIT(JTAG_TMS, 1);
+    SEND_BIT(JTAG_TMS, 1);
+    SEND_BIT(JTAG_TMS, 1);
+    SEND_BIT(JTAG_TMS, 1);
+    pin_hi(JTAG_PORT, JTAG_TRST);
 }
 
 /*!
@@ -41,47 +60,41 @@
  * shift state.  The state machine transite to shift state when shifting
  * starts.
  */
-void jtag_tms(char *buf, int nbits) {
+void jtag_tms(unsigned char *buf, int nbits) {
     int i;
     int nbytes, byte;
     int byteoff, bitoff;
     int bit;
     
+    pin_hi(JTAG_PORT, JTAG_TDI);
+
     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];
@@ -89,175 +102,170 @@
     for(i = 0; i < nbits; i++) {
 	bit = byte & (1 << i);
 	SEND_BIT(JTAG_TMS, bit);
-	TCK_LO();
     }
 }
 
-void jtag_shift(char *buf, int nbits) {
+void jtag_shift(unsigned char *buf, int nbits) {
     int i;
+    int nbits_1;
     int nbytes, byte;
     int byteoff, bitoff;
-    int bit;
+    int bit, remain;
+
+    if(nbits == 0)
+	return;
     
     /* Transite to shift state.
      * \sa jtag_tms()
      */
     pin_lo(JTAG_PORT, JTAG_TMS);
 
-    nbytes = nbits / 8;
+    nbits_1 = nbits - 1;
+    nbytes = nbits_1 / 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();
-	}
+    remain = nbits_1 % 8;
+    byte = buf[i];
+    for(i = 0; i < remain; i++) {
+	bit = byte & (1 << i);
+	SEND_BIT(JTAG_TDI, bit);
     }
+
+    byte = buf[nbits / 8];
+    bit = byte & (1 << (nbits_1 % 8));
+    
+    pin_hi(JTAG_PORT, JTAG_TMS);
+    SEND_BIT(JTAG_TDI, bit);
 }
 
-void jtag_shift_inout(char *ibuf, char *obuf, int nbits) {
+void jtag_shift_inout(unsigned char *ibuf, unsigned char *obuf, int nbits) {
     int i, j;
+    int nbits_1;
     int nbytes, byte, obyte;
     int tdo;
     int byteoff, bitoff;
-    int bit;
+    int bit, remain;
+    
+    if(nbits == 0)
+	return;
     
     /* Transite to shift state.
      * \sa jtag_tms()
      */
     pin_lo(JTAG_PORT, JTAG_TMS);
 
-    nbytes = nbits / 8;
+    nbits_1 = nbits - 1;
+    nbytes = nbits_1 / 8;
     for(i = 0; i < nbytes; i++) {
 	byte = ibuf[i];
 	obyte = 0;
 	
 	bit = byte & 0x01;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x01;
 	else
 	    obyte &= ~0x01;
-	TCK_LO();
 	
 	bit = byte & 0x02;
-	SEND_BIT(JTAG_TDI, bit);
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	tdo = GET_TDO();
 	if(tdo)
 	    obyte |= 0x02;
 	else
 	    obyte &= ~0x02;
-	TCK_LO();
 	
 	bit = byte & 0x04;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x04;
 	else
 	    obyte &= ~0x04;
-	TCK_LO();
 	
 	bit = byte & 0x08;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x08;
 	else
 	    obyte &= ~0x08;
-	TCK_LO();
 	
 	bit = byte & 0x10;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x10;
 	else
 	    obyte &= ~0x10;
-	TCK_LO();
 	
 	bit = byte & 0x20;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x20;
 	else
 	    obyte &= ~0x20;
-	TCK_LO();
 	
 	bit = byte & 0x40;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x40;
 	else
 	    obyte &= ~0x40;
-	TCK_LO();
 	
 	bit = byte & 0x80;
-	SEND_BIT(JTAG_TDI, bit);
-	tdo = GET_TDO();
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
 	if(tdo)
 	    obyte |= 0x80;
 	else
 	    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;
+    remain = nbits_1 % 8;
+    byte = ibuf[i];
+    obyte = 0;
+    for(j = 0; j < remain; j++) {
+	bit = byte & (1 << j);
+	SEND_GET_BIT(JTAG_TDI, bit, tdo);
+	if(tdo)
+	    obyte |= 1 << j;
+	else
+	    obyte &= ~(1 << j);
     }
+    obuf[i] = obyte;
+
+    byte = ibuf[nbits / 8];
+    bit = byte & (1 << (nbits_1 % 8));
+
+    pin_hi(JTAG_PORT, JTAG_TMS);
+    SEND_GET_BIT(JTAG_TDI, bit, tdo);
+    if(tdo)
+	obuf[nbits / 8] |= 1 << j;
+    else
+	obuf[nbits / 8] &= ~(1 << j);
 }