From 6f15628e4735a47b9817673680d8efd2688a2923 Mon Sep 17 00:00:00 2001 From: hackbard Date: Sat, 26 Mar 2011 17:01:15 +0100 Subject: [PATCH] added initial jtag code (chain inint by now) --- jtag.c | 236 +++++++++++++++++++++++++++++++++++++++++++++++++++++++++ 1 file changed, 236 insertions(+) create mode 100644 jtag.c diff --git a/jtag.c b/jtag.c new file mode 100644 index 0000000..ca2e683 --- /dev/null +++ b/jtag.c @@ -0,0 +1,236 @@ +/* + * jtag.c - basic jtag stuff (good excercise!) + * + * author: hackbard@hackdaworld.org + * + */ + +#include +#include +#include +#include +#include + +// 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;itot_ir_len=i; + jtag_leave_shift_ir(); + + jtag_enter_shift_dr(); + for(i=0;inod=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; + +} + -- 2.39.2