implemented set ir stuff
[my-code/pnx.git] / jtag.c
1 /*
2  * jtag.c - basic jtag stuff (good excercise!)
3  *
4  * build: gcc -Wall jtag.c -o jtag
5  * author: hackbard@hackdaworld.org
6  *
7  */
8
9 #include <stdio.h>
10 #include <stdlib.h>
11 #include <unistd.h>
12 #include <sys/io.h>
13 #include <string.h>
14
15 // variables
16
17 #define u16 unsigned short
18 #define u8 unsigned char
19 #define u32 unsigned int 
20
21 // max devices and ir chain len
22 #define MAXDEV 64
23 #define MAXIRLEN 32
24
25 typedef struct s_jtdrv {
26         unsigned long ppaddr;
27         //int *init(t_jtag *jtag);
28 } t_jtdrv;
29
30 typedef struct s_part {
31         int irlen;
32         u32 idcode;
33 } t_part;
34
35 typedef struct s_jtag {
36         int nod;
37         int tot_ir_len;
38         t_part part[MAXDEV];
39 } t_jtag;
40
41 // only parallel III cable by now
42
43 #define TDI 0x01
44 #define TMS 0x04
45 #define TCK 0x02
46 #define TDO 0x10
47
48 // parport functions
49
50 int parport_init(unsigned long ppaddr) {
51
52         if(ioperm(ppaddr,1,1)||ioperm(ppaddr+1,1,1)) {
53                 perror("parport init");
54                 return -1;
55         }
56
57         return 0;
58
59 }
60
61 int parport_out(u8 data) {
62
63         outb(data,0x378);
64
65         return 0;
66
67 }
68
69 int parport_in(u8 *data) {
70
71         *data=inb(0x379);
72
73         return 0;
74
75 }
76
77 // jtag low level functions
78
79 u8 jtag_clock(u8 tms,u8 tdi) {
80
81         u8 in;
82         u8 out;
83         u8 tdo;
84
85         out=0;
86         if(tms) out|=TMS;
87         if(tdi) out|=TDI;
88         parport_out(out);
89
90         parport_in(&in);
91
92         tdo=in&TDO?1:0;
93
94         // clock cycle
95         parport_out(out|TCK);
96         parport_out(out);
97
98         return tdo;
99
100 }
101
102 // jtag mid level functions
103
104 int jtag_reset() {
105
106         // 5 times TMS
107         jtag_clock(1,0);
108         jtag_clock(1,0);
109         jtag_clock(1,0);
110         jtag_clock(1,0);
111         jtag_clock(1,0);
112
113         // go to idle mode
114         jtag_clock(0,0);
115
116         return 0;
117 }
118
119 int jtag_enter_shift_ir() {
120
121         jtag_clock(1,0);
122         jtag_clock(1,0);
123         jtag_clock(0,0);
124         jtag_clock(0,0);
125
126         return 0;
127
128 }
129
130 int jtag_leave_shift_ir() {
131
132         jtag_clock(1,0);
133         jtag_clock(1,0);
134         jtag_clock(0,0);
135
136         return 0;
137
138 }
139
140 int jtag_enter_shift_dr() {
141
142         jtag_clock(1,0);
143         jtag_clock(0,0);
144         jtag_clock(0,0);
145
146         return 0;
147
148 }
149
150 int jtag_leave_shift_dr() {
151
152         jtag_clock(1,0);
153         jtag_clock(1,0);
154         jtag_clock(0,0);
155
156         return 0;
157
158 }
159
160 int jtag_read_data(u8 *p,int bitlen) {
161
162         u8 in;
163         int count;
164
165         memset(p,0,bitlen+7/8);
166         count=0;
167
168         printf("  <- ");
169         while(bitlen) {
170                 in=jtag_clock(0,0);
171                 p[count/8]|=((in&1)<<(count%8));
172                 printf("%d",p[count/8]&(1<<(count%8))?1:0);
173                 count+=1;
174                 bitlen-=1;
175         }
176         printf("\n");
177
178         return 0;
179
180 }
181
182 int jtag_write_data(u8 *p,int bitlen) {
183
184         int count;
185
186         count=0;
187
188         printf("  -> ");
189         while(bitlen) {
190                 jtag_clock(0,p[count/8]&(1<<(count%8))?1:0);
191                 printf("%d",p[count/8]&(1<<(count%8))?1:0);
192                 bitlen-=1;
193                 count+=1;
194         }
195         printf("\n");
196
197         return 0;
198
199 }
200
201 int jtag_chain_init(t_jtag *jtag) {
202
203         int i;
204         u8 tdo;
205
206         jtag_enter_shift_ir();
207         for(i=0;i<MAXIRLEN*MAXDEV;i++) jtag_clock(0,0);
208         for(i=0;i<MAXIRLEN*MAXDEV;i++) {
209                 tdo=jtag_clock(0,1);
210                 if(tdo)
211                         break;
212         }
213         printf("ir len: %d\n",i);
214         jtag->tot_ir_len=i;
215         jtag_leave_shift_ir();
216
217         jtag_enter_shift_dr();
218         for(i=0;i<MAXIRLEN*MAXDEV;i++) jtag_clock(0,0);
219         for(i=0;i<MAXIRLEN*MAXDEV;i++)
220                 if(jtag_clock(0,1))
221                          break;
222         printf("number of devices: %d\n",i);
223         jtag->nod=i;
224         jtag_leave_shift_dr();
225
226         jtag_reset();
227         jtag_enter_shift_dr();
228         for(i=1;i<=jtag->nod;i++) {
229                 jtag_read_data((u8 *)&(jtag->part[jtag->nod-i].idcode),32);
230                 printf("idcode of part %d: %x\n",i,jtag->part[jtag->nod-i].idcode);
231         }
232         jtag_leave_shift_dr();
233
234         return i;
235
236 }
237
238 int jtag_set_ir(char *s,int bitlen) {
239
240         u8 ir[MAXDEV*MAXIRLEN/8];
241         int count;
242
243         if(bitlen>=MAXDEV*MAXIRLEN) {
244                 printf("instruction register too big!\n");
245                 return -1;
246         }
247
248         memset(ir,0,MAXDEV*MAXIRLEN/8*sizeof(u8));
249         count=0;
250
251         printf("set ir: ");
252         while(bitlen) {
253                 if(s[count]=='1')
254                         ir[count/8]|=(1<<(count%8));
255                 printf("%d",ir[count/8]&(1<<(count%8))?1:0);
256                 count+=1;
257                 bitlen-=1;
258         }
259         printf("\n");
260
261         jtag_enter_shift_ir();
262         jtag_write_data(ir,count);
263         jtag_leave_shift_ir();
264
265         return 0;
266
267 }
268
269 int main(int argc,char **argv) {
270
271         t_jtag jtag;
272         u8 io[256];
273
274         memset(&jtag,0,sizeof(t_jtag));
275
276         printf("parport init ...\n");
277         parport_init(0x378);
278         printf("done\n\n");
279
280         printf("reset test logic ...\n");
281         jtag_reset();
282         printf("done\n\n");
283
284         printf("jtag chain init ...\n");
285         jtag_chain_init(&jtag);
286         printf("done\n\n");
287
288         printf("testing some instructions ...\n\n");
289         jtag_set_ir("000001000001",12);
290         jtag_enter_shift_dr();
291         jtag_read_data(io,64);
292         jtag_leave_shift_dr();
293
294         return 0;
295
296 }
297