]> git.sur5r.net Git - openocd/blob - src/jtag/bitbang.c
97ea94e04bad7767adaea3db08cb91ce900da4d4
[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 static enum tap_state end_state;
47 static enum tap_state cur_state;
48
49 void bitbang_end_state(enum tap_state state)
50 {
51         if (tap_move_map[state] != -1)
52                 end_state = state;
53         else
54         {
55                 LOG_ERROR("BUG: %i is not a valid end state", state);
56                 exit(-1);
57         }
58 }
59
60 void bitbang_state_move(void) {
61         
62         int i=0, tms=0;
63         u8 tms_scan = TAP_MOVE(cur_state, end_state);
64         
65         for (i = 0; i < 7; i++)
66         {
67                 tms = (tms_scan >> i) & 1;
68                 bitbang_interface->write(0, tms, 0);
69                 bitbang_interface->write(1, tms, 0);
70         }
71         bitbang_interface->write(0, tms, 0);
72         
73         cur_state = end_state;
74 }
75
76 void bitbang_path_move(pathmove_command_t *cmd)
77 {
78         int num_states = cmd->num_states;
79         int state_count;
80         int tms = 0;
81
82         state_count = 0;
83         while (num_states)
84         {
85                 if (tap_transitions[cur_state].low == cmd->path[state_count])
86                 {
87                         tms = 0;
88                 }
89                 else if (tap_transitions[cur_state].high == cmd->path[state_count])
90                 {
91                         tms = 1;
92                 }
93                 else
94                 {
95                         LOG_ERROR("BUG: %s -> %s isn't a valid TAP transition", tap_state_strings[cur_state], tap_state_strings[cmd->path[state_count]]);
96                         exit(-1);
97                 }
98                 
99                 bitbang_interface->write(0, tms, 0);
100                 bitbang_interface->write(1, tms, 0);
101
102                 cur_state = cmd->path[state_count];
103                 state_count++;
104                 num_states--;
105         }
106         
107         bitbang_interface->write(0, tms, 0);
108
109         end_state = cur_state;
110 }
111
112 void bitbang_runtest(int num_cycles)
113 {
114         int i;
115         
116         enum tap_state saved_end_state = end_state;
117         
118         /* only do a state_move when we're not already in RTI */
119         if (cur_state != TAP_RTI)
120         {
121                 bitbang_end_state(TAP_RTI);
122                 bitbang_state_move();
123         }
124         
125         /* execute num_cycles */
126         bitbang_interface->write(0, 0, 0);
127         for (i = 0; i < num_cycles; i++)
128         {
129                 bitbang_interface->write(1, 0, 0);
130                 bitbang_interface->write(0, 0, 0);
131         }
132         
133         /* finish in end_state */
134         bitbang_end_state(saved_end_state);
135         if (cur_state != end_state)
136                 bitbang_state_move();
137 }
138
139 void bitbang_scan(int ir_scan, enum scan_type type, u8 *buffer, int scan_size)
140 {
141         enum tap_state saved_end_state = end_state;
142         int bit_cnt;
143         
144         if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
145         {
146                 if (ir_scan)
147                         bitbang_end_state(TAP_SI);
148                 else
149                         bitbang_end_state(TAP_SD);
150
151                 bitbang_state_move();
152                 bitbang_end_state(saved_end_state);
153         }
154
155         for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
156         {
157                 /* if we're just reading the scan, but don't care about the output
158                  * default to outputting 'low', this also makes valgrind traces more readable,
159                  * as it removes the dependency on an uninitialised value
160                  */ 
161                 if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
162                 {
163                         bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
164                         bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
165                 } else {
166                         bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0);
167                         bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0);
168                 }
169                 
170                 if (type != SCAN_OUT)
171                 {
172                         /*
173                         TDO should be sampled on the rising edge, and will change 
174                         on the falling edge. 
175                         
176                         Because there is no way to read the signal exactly at the rising edge,
177                         read after the rising edge.
178
179                         This is plain IEEE 1149 JTAG - nothing specific to the OpenOCD or its JTAG
180                         API. 
181                         */
182                         if (bitbang_interface->read())
183                                 buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
184                         else
185                                 buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
186                 }
187         }
188         
189         /* TAP_SD & TAP_SI are illegal end states, so we always transition to the pause
190          * state which is a legal stable state from which statemove will work.
191          *  
192          * Exit1 -> Pause 
193          */
194         bitbang_interface->write(0, 0, 0);
195         bitbang_interface->write(1, 0, 0);
196         bitbang_interface->write(0, 0, 0);
197         
198         if (ir_scan)
199                 cur_state = TAP_PI;
200         else
201                 cur_state = TAP_PD;
202         
203         if (cur_state != end_state)
204                 bitbang_state_move();
205 }
206
207 int bitbang_execute_queue(void)
208 {
209         jtag_command_t *cmd = jtag_command_queue; /* currently processed command */
210         int scan_size;
211         enum scan_type type;
212         u8 *buffer;
213         int retval;
214         
215         if (!bitbang_interface)
216         {
217                 LOG_ERROR("BUG: Bitbang interface called, but not yet initialized");
218                 exit(-1);
219         }
220         
221         /* return ERROR_OK, unless a jtag_read_buffer returns a failed check
222          * that wasn't handled by a caller-provided error handler
223          */ 
224         retval = ERROR_OK;
225                 
226         if(bitbang_interface->blink)
227                 bitbang_interface->blink(1);
228
229         while (cmd)
230         {
231                 switch (cmd->type)
232                 {
233                         case JTAG_END_STATE:
234 #ifdef _DEBUG_JTAG_IO_
235                                 LOG_DEBUG("end_state: %i", cmd->cmd.end_state->end_state);
236 #endif
237                                 if (cmd->cmd.end_state->end_state != -1)
238                                         bitbang_end_state(cmd->cmd.end_state->end_state);
239                                 break;
240                         case JTAG_RESET:
241 #ifdef _DEBUG_JTAG_IO_
242                                 LOG_DEBUG("reset trst: %i srst %i", cmd->cmd.reset->trst, cmd->cmd.reset->srst);
243 #endif
244                                 if ((cmd->cmd.reset->trst == 1) || (cmd->cmd.reset->srst && (jtag_reset_config & RESET_SRST_PULLS_TRST)))
245                                 {
246                                         cur_state = TAP_TLR;
247                                 }
248                                 bitbang_interface->reset(cmd->cmd.reset->trst, cmd->cmd.reset->srst);
249                                 break;
250                         case JTAG_RUNTEST:
251 #ifdef _DEBUG_JTAG_IO_
252                                 LOG_DEBUG("runtest %i cycles, end in %i", cmd->cmd.runtest->num_cycles, cmd->cmd.runtest->end_state);
253 #endif
254                                 if (cmd->cmd.runtest->end_state != -1)
255                                         bitbang_end_state(cmd->cmd.runtest->end_state);
256                                 bitbang_runtest(cmd->cmd.runtest->num_cycles);
257                                 break;
258                         case JTAG_STATEMOVE:
259 #ifdef _DEBUG_JTAG_IO_
260                                 LOG_DEBUG("statemove end in %i", cmd->cmd.statemove->end_state);
261 #endif
262                                 if (cmd->cmd.statemove->end_state != -1)
263                                         bitbang_end_state(cmd->cmd.statemove->end_state);
264                                 bitbang_state_move();
265                                 break;
266                         case JTAG_PATHMOVE:
267 #ifdef _DEBUG_JTAG_IO_
268                                 LOG_DEBUG("pathmove: %i states, end in %i", cmd->cmd.pathmove->num_states, cmd->cmd.pathmove->path[cmd->cmd.pathmove->num_states - 1]);
269 #endif
270                                 bitbang_path_move(cmd->cmd.pathmove);
271                                 break;
272                         case JTAG_SCAN:
273 #ifdef _DEBUG_JTAG_IO_
274                                 LOG_DEBUG("%s scan end in %i",  (cmd->cmd.scan->ir_scan) ? "IR" : "DR", cmd->cmd.scan->end_state);
275 #endif
276                                 if (cmd->cmd.scan->end_state != -1)
277                                         bitbang_end_state(cmd->cmd.scan->end_state);
278                                 scan_size = jtag_build_buffer(cmd->cmd.scan, &buffer);
279                                 type = jtag_scan_type(cmd->cmd.scan);
280                                 bitbang_scan(cmd->cmd.scan->ir_scan, type, buffer, scan_size);
281                                 if (jtag_read_buffer(buffer, cmd->cmd.scan) != ERROR_OK)
282                                         retval = ERROR_JTAG_QUEUE_FAILED;
283                                 if (buffer)
284                                         free(buffer);
285                                 break;
286                         case JTAG_SLEEP:
287 #ifdef _DEBUG_JTAG_IO_
288                                 LOG_DEBUG("sleep %i", cmd->cmd.sleep->us);
289 #endif
290                                 jtag_sleep(cmd->cmd.sleep->us);
291                                 break;
292                         default:
293                                 LOG_ERROR("BUG: unknown JTAG command type encountered");
294                                 exit(-1);
295                 }
296                 cmd = cmd->next;
297         }
298         if(bitbang_interface->blink)
299                 bitbang_interface->blink(0);
300         
301         return retval;
302 }
303