]> git.sur5r.net Git - openocd/blob - src/jtag/bitbang.c
a4e415c2ec8cff69c5de240ddffe67575bb629d9
[openocd] / src / jtag / bitbang.c
1 /***************************************************************************
2  *   Copyright (C) 2005 by Dominic Rath                                    *
3  *   Dominic.Rath@gmx.de                                                   *
4  *                                                                         *
5  *   This program is free software; you can redistribute it and/or modify  *
6  *   it under the terms of the GNU General Public License as published by  *
7  *   the Free Software Foundation; either version 2 of the License, or     *
8  *   (at your option) any later version.                                   *
9  *                                                                         *
10  *   This program is distributed in the hope that it will be useful,       *
11  *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *
12  *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *
13  *   GNU General Public License for more details.                          *
14  *                                                                         *
15  *   You should have received a copy of the GNU General Public License     *
16  *   along with this program; if not, write to the                         *
17  *   Free Software Foundation, Inc.,                                       *
18  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
19  ***************************************************************************/
20 #ifdef HAVE_CONFIG_H
21 #include "config.h"
22 #endif
23
24 #include "bitbang.h"
25
26 /* project specific includes */
27 #include "log.h"
28 #include "types.h"
29 #include "jtag.h"
30 #include "configuration.h"
31
32 /* system includes */
33 #include <string.h>
34 #include <stdlib.h>
35 #include <unistd.h>
36
37 #include <sys/time.h>
38 #include <time.h>
39
40 bitbang_interface_t *bitbang_interface;
41
42 int bitbang_execute_queue(void);
43
44 /* The bitbang driver leaves the TCK 0 when in idle */
45
46
47 void bitbang_end_state(enum tap_state state)
48 {
49         if (tap_move_map[state] != -1)
50                 end_state = state;
51         else
52         {
53                 LOG_ERROR("BUG: %i is not a valid end state", state);
54                 exit(-1);
55         }
56 }
57
58 void bitbang_state_move(void) {
59         
60         int i=0, tms=0;
61         u8 tms_scan = TAP_MOVE(cur_state, end_state);
62         
63         for (i = 0; i < 7; i++)
64         {
65                 tms = (tms_scan >> i) & 1;
66                 bitbang_interface->write(0, tms, 0);
67                 bitbang_interface->write(1, tms, 0);
68         }
69         bitbang_interface->write(0, tms, 0);
70         
71         cur_state = end_state;
72 }
73
74 void bitbang_path_move(pathmove_command_t *cmd)
75 {
76         int num_states = cmd->num_states;
77         int state_count;
78         int tms = 0;
79
80         state_count = 0;
81         while (num_states)
82         {
83                 if (tap_transitions[cur_state].low == cmd->path[state_count])
84                 {
85                         tms = 0;
86                 }
87                 else if (tap_transitions[cur_state].high == cmd->path[state_count])
88                 {
89                         tms = 1;
90                 }
91                 else
92                 {
93                         LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
94                         exit(-1);
95                 }
96                 
97                 bitbang_interface->write(0, tms, 0);
98                 bitbang_interface->write(1, tms, 0);
99
100                 cur_state = cmd->path[state_count];
101                 state_count++;
102                 num_states--;
103         }
104         
105         bitbang_interface->write(0, tms, 0);
106
107         end_state = cur_state;
108 }
109
110 void bitbang_runtest(int num_cycles)
111 {
112         int i;
113         
114         enum tap_state saved_end_state = end_state;
115         
116         /* only do a state_move when we're not already in RTI */
117         if (cur_state != TAP_RTI)
118         {
119                 bitbang_end_state(TAP_RTI);
120                 bitbang_state_move();
121         }
122         
123         /* execute num_cycles */
124         bitbang_interface->write(0, 0, 0);
125         for (i = 0; i < num_cycles; i++)
126         {
127                 bitbang_interface->write(1, 0, 0);
128                 bitbang_interface->write(0, 0, 0);
129         }
130         
131         /* finish in end_state */
132         bitbang_end_state(saved_end_state);
133         if (cur_state != end_state)
134                 bitbang_state_move();
135 }
136
137 void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
138 {
139         enum tap_state saved_end_state = end_state;
140         int bit_cnt;
141         
142         if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
143         {
144                 if (ir_scan)
145                         bitbang_end_state(TAP_SI);
146                 else
147                         bitbang_end_state(TAP_SD);
148
149                 bitbang_state_move();
150                 bitbang_end_state(saved_end_state);
151         }
152
153         for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
154         {
155                 /* if we're just reading the scan, but don't care about the output
156                  * default to outputting 'low', this also makes valgrind traces more readable,
157                  * as it removes the dependency on an uninitialised value
158                  */ 
159                 if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
160                 {
161                         bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
162                         bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
163                 } else {
164                         bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0);
165                         bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0);
166                 }
167                 
168                 if (type != SCAN_OUT)
169                 {
170                         /*
171                         TDO should be sampled on the rising edge, and will change 
172                         on the falling edge. 
173                         
174                         Because there is no way to read the signal exactly at the rising edge,
175                         read after the rising edge.
176
177                         This is plain IEEE 1149 JTAG - nothing specific to the OpenOCD or its JTAG
178                         API. 
179                         */
180                         if (bitbang_interface->read())
181                                 buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
182                         else
183                                 buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
184                 }
185         }
186         
187         /* TAP_SD & TAP_SI are illegal end states, so we always transition to the pause
188          * state which is a legal stable state from which statemove will work.
189          *  
190          * Exit1 -> Pause 
191          */
192         bitbang_interface->write(0, 0, 0);
193         bitbang_interface->write(1, 0, 0);
194         bitbang_interface->write(0, 0, 0);
195         
196         if (ir_scan)
197                 cur_state = TAP_PI;
198         else
199                 cur_state = TAP_PD;
200         
201         if (cur_state != end_state)
202                 bitbang_state_move();
203 }
204
205 int bitbang_execute_queue(void)
206 {
207         jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
208         int scan_size;
209         enum scan_type type;
210         u8 *buffer;
211         int retval;
212         
213         if (!bitbang_interface)
214         {
215                 LOG_ERROR("BUG: Bitbang interface called, but not yet initialized");
216                 exit(-1);
217         }
218         
219         /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
220          * that wasn't handled by a caller-provided error handler
221          */ 
222         retval = ERROR_OK;
223                 
224         if(bitbang_interface->blink)
225                 bitbang_interface->blink(1);
226
227         while (cmd)
228         {
229                 switch (cmd->type)
230                 {
231                         case JTAG_END_STATE:
232 #ifdef _DEBUG_JTAG_IO_
233                                 LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
234 #endif
235                                 if (cmd->cmd.end_state->end_state != -1)
236                                         bitbang_end_state(cmd->cmd.end_state->end_state);
237                                 break;
238                         case JTAG_RESET:
239 #ifdef _DEBUG_JTAG_IO_
240                                 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
241 #endif
242                                 if (cmd->cmd.reset->trst == 1)
243                                 {
244                                         cur_state = TAP_TLR;
245                                 }
246                                 bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
247                                 break;
248                         case JTAG_RUNTEST:
249 #ifdef _DEBUG_JTAG_IO_
250                                 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
251 #endif
252                                 if (cmd->cmd.runtest->end_state != -1)
253                                         bitbang_end_state(cmd->cmd.runtest->end_state);
254                                 bitbang_runtest(cmd->cmd.runtest->num_cycles);
255                                 break;
256                         case JTAG_STATEMOVE:
257 #ifdef _DEBUG_JTAG_IO_
258                                 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
259 #endif
260                                 if (cmd->cmd.statemove->end_state != -1)
261                                         bitbang_end_state(cmd->cmd.statemove->end_state);
262                                 bitbang_state_move();
263                                 break;
264                         case JTAG_PATHMOVE:
265 #ifdef _DEBUG_JTAG_IO_
266                                 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
267 #endif
268                                 bitbang_path_move(cmd->cmd.pathmove);
269                                 break;
270                         case JTAG_SCAN:
271 #ifdef _DEBUG_JTAG_IO_
272                                 LOG_DEBUG("%s scan end in %i",  (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
273 #endif
274                                 if (cmd->cmd.scan->end_state != -1)
275                                         bitbang_end_state(cmd->cmd.scan->end_state);
276                                 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
277                                 type = jtag_scan_type(cmd->cmd.scan);
278                                 bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
279                                 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
280                                         retval = ERROR_JTAG_QUEUE_FAILED;
281                                 if (buffer)
282                                         free(buffer);
283                                 break;
284                         case JTAG_SLEEP:
285 #ifdef _DEBUG_JTAG_IO_
286                                 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
287 #endif
288                                 jtag_sleep(cmd->cmd.sleep->us);
289                                 break;
290                         default:
291                                 LOG_ERROR("BUG: unknown JTAG command type encountered");
292                                 exit(-1);
293                 }
294                 cmd = cmd->next;
295         }
296         if(bitbang_interface->blink)
297                 bitbang_interface->blink(0);
298         
299         return retval;
300 }
301