added initial jtag code (chain inint by now)
[my-code/pnx.git] / jtag.c
diff --git a/jtag.c b/jtag.c
new file mode 100644 (file)
index 0000000..ca2e683
--- /dev/null
+++ b/jtag.c
@@ -0,0 +1,236 @@
+/*
+ * jtag.c - basic jtag stuff (good excercise!)
+ *
+ * author: hackbard@hackdaworld.org
+ *
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <unistd.h>
+#include <sys/io.h>
+#include <string.h>
+
+// variables
+
+#define u16 unsigned short
+#define u8 unsigned char
+#define u32 unsigned int 
+
+// max devices and ir chain len
+#define MAXDEV 64
+#define MAXIRLEN 32
+
+typedef struct s_jtdrv {
+       unsigned long ppaddr;
+       //int *init(t_jtag *jtag);
+} t_jtdrv;
+
+typedef struct s_part {
+       int irlen;
+       u32 idcode;
+} t_part;
+
+typedef struct s_jtag {
+       int nod;
+       int tot_ir_len;
+       t_part part[MAXDEV];
+} t_jtag;
+
+// only parallel III cable by now
+
+#define TDI 0x01
+#define TMS 0x04
+#define TCK 0x02
+#define TDO 0x10
+
+// parport functions
+
+int parport_init(unsigned long ppaddr) {
+
+       if(ioperm(ppaddr,1,1)||ioperm(ppaddr+1,1,1)) {
+               perror("parport init");
+               return -1;
+       }
+
+       return 0;
+
+}
+
+int parport_out(u8 data) {
+
+       outb(data,0x378);
+
+       return 0;
+
+}
+
+int parport_in(u8 *data) {
+
+       *data=inb(0x379);
+
+       return 0;
+
+}
+
+// jtag low level functions
+
+u8 jtag_clock(u8 tms,u8 tdi) {
+
+       u8 in;
+       u8 out;
+       u8 tdo;
+
+       out=0;
+       if(tms) out|=TMS;
+       if(tdi) out|=TDI;
+       parport_out(out);
+
+       parport_in(&in);
+
+       tdo=in&TDO?1:0;
+
+       // clock cycle
+       parport_out(out|TCK);
+       parport_out(out);
+
+       return tdo;
+
+}
+
+// jtag mid level functions
+
+int jtag_reset() {
+
+       // 5 times TMS
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+
+       // go to idle mode
+       jtag_clock(0,0);
+
+       return 0;
+}
+
+int jtag_enter_shift_ir() {
+
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(0,0);
+       jtag_clock(0,0);
+
+       return 0;
+
+}
+
+int jtag_leave_shift_ir() {
+
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(0,0);
+
+       return 0;
+
+}
+
+int jtag_enter_shift_dr() {
+
+       jtag_clock(1,0);
+       jtag_clock(0,0);
+       jtag_clock(0,0);
+
+       return 0;
+
+}
+
+int jtag_leave_shift_dr() {
+
+       jtag_clock(1,0);
+       jtag_clock(1,0);
+       jtag_clock(0,0);
+
+       return 0;
+
+}
+
+int jtag_read_data(u8 *p,int bitlen) {
+
+       u8 in;
+       int count;
+
+       memset(p,0,bitlen+7/8);
+       count=0;
+
+       while(bitlen) {
+               in=jtag_clock(0,0);
+               p[count/8]|=((in&1)<<(count%8));
+               count+=1;
+               bitlen-=1;
+       }
+
+       return 0;
+
+}
+
+int jtag_chain_init(t_jtag *jtag) {
+
+       int i;
+       u8 tdo;
+
+       jtag_enter_shift_ir();
+       for(i=0;i<MAXIRLEN*MAXDEV;i++) jtag_clock(0,0);
+       for(i=0;i<MAXIRLEN*MAXDEV;i++) {
+               tdo=jtag_clock(0,1);
+               if(tdo)
+                       break;
+       }
+       printf("ir len: %d\n",i);
+       jtag->tot_ir_len=i;
+       jtag_leave_shift_ir();
+
+       jtag_enter_shift_dr();
+       for(i=0;i<MAXIRLEN*MAXDEV;i++) jtag_clock(0,0);
+       for(i=0;i<MAXIRLEN*MAXDEV;i++)
+               if(jtag_clock(0,1))
+                        break;
+       printf("number of devices: %d\n",i);
+       jtag->nod=i;
+       jtag_leave_shift_dr();
+
+       jtag_reset();
+       jtag_enter_shift_dr();
+       for(i=1;i<=jtag->nod;i++) {
+               jtag_read_data((u8 *)&(jtag->part[jtag->nod-i].idcode),32);
+               printf("idcode of part %d: %x\n",i,jtag->part[jtag->nod-i].idcode);
+       }
+       jtag_leave_shift_dr();
+
+       return i;
+
+}
+
+int main(int argc,char **argv) {
+
+       t_jtag jtag;
+
+       memset(&jtag,0,sizeof(t_jtag));
+
+       printf("parport init ...\n");
+       parport_init(0x378);
+       printf("done\n\n");
+
+       printf("reset test logic ...\n");
+       jtag_reset();
+       printf("done\n\n");
+
+       printf("jtag chain init ...\n");
+       jtag_chain_init(&jtag);
+       printf("done\n\n");
+
+       return 0;
+
+}
+