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