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