1 /*
2 * $Id$
3 *
4 * Copyright (C) 2003 ETC s.r.o.
5 *
6 * This program is free software; you can redistribute it and/or
7 * modify it under the terms of the GNU General Public License
8 * as published by the Free Software Foundation; either version 2
9 * of the License, or (at your option) any later version.
10 *
11 * This program is distributed in the hope that it will be useful,
12 * but WITHOUT ANY WARRANTY; without even the implied warranty of
13 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
14 * GNU General Public License for more details.
15 *
16 * You should have received a copy of the GNU General Public License
17 * along with this program; if not, write to the Free Software
18 * Foundation, Inc., 59 Temple Place - Suite 330, Boston, MA
19 * 02111-1307, USA.
20 *
21 * Written by Marcel Telka <marcel@telka.sk>, 2003.
22 *
23 */
24
25 #include <sysdep.h>
26
27 #include <inttypes.h>
28 #include <stdio.h>
29 #include <string.h>
30
31 #include <urjtag/error.h>
32 #include <urjtag/chain.h>
33 #include <urjtag/part.h>
34 #include <urjtag/part_instruction.h>
35 #include <urjtag/data_register.h>
36 #include <urjtag/tap_register.h>
37
38 #include <urjtag/cmd.h>
39
40 #include "cmd.h"
41
42 static int
cmd_dr_run(urj_chain_t * chain,char * params[])43 cmd_dr_run (urj_chain_t *chain, char *params[])
44 {
45 int dir = 1;
46 urj_part_t *part;
47 urj_tap_register_t *r;
48 urj_data_register_t *dr;
49 urj_part_instruction_t *active_ir;
50
51 if (urj_cmd_params (params) < 1 || urj_cmd_params (params) > 2)
52 {
53 urj_error_set (URJ_ERROR_SYNTAX,
54 "%s: #parameters should be >= 1 and <= 2, not %d",
55 params[0], urj_cmd_params (params));
56 return URJ_STATUS_FAIL;
57 }
58
59 if (urj_cmd_test_cable (chain) != URJ_STATUS_OK)
60 return URJ_STATUS_FAIL;
61
62 part = urj_tap_chain_active_part (chain);
63 if (part == NULL)
64 return URJ_STATUS_FAIL;
65
66 active_ir = part->active_instruction;
67 if (active_ir == NULL)
68 {
69 urj_error_set (URJ_ERROR_ILLEGAL_STATE,
70 _("%s: part without active instruction"), "dr");
71 return URJ_STATUS_FAIL;
72 }
73 dr = active_ir->data_register;
74 if (dr == NULL)
75 {
76 urj_error_set (URJ_ERROR_ILLEGAL_STATE,
77 _("%s: instruction without active data register"), "dr");
78 return URJ_STATUS_FAIL;
79 }
80
81 if (params[1])
82 {
83 if (strcasecmp (params[1], "in") == 0)
84 dir = 0;
85 else if (strcasecmp (params[1], "out") == 0)
86 dir = 1;
87 else
88 {
89 int ret = urj_tap_register_set_string (dr->in, params[1]);
90 if (ret != URJ_STATUS_OK)
91 return ret;
92 dir = 0;
93 }
94 }
95
96 if (dir)
97 r = dr->out;
98 else
99 r = dr->in;
100 urj_log (URJ_LOG_LEVEL_NORMAL, "%s (0x%0*" PRIX64 ")\n",
101 urj_tap_register_get_string (r), r->len / 4,
102 urj_tap_register_get_value (r));
103
104 return URJ_STATUS_OK;
105 }
106
107 static void
cmd_dr_complete(urj_chain_t * chain,char *** matches,size_t * match_cnt,char * const * tokens,const char * text,size_t text_len,size_t token_point)108 cmd_dr_complete (urj_chain_t *chain, char ***matches, size_t *match_cnt,
109 char * const *tokens, const char *text, size_t text_len,
110 size_t token_point)
111 {
112 static const char * const dir[] = {
113 "in",
114 "out",
115 };
116
117 if (token_point != 1)
118 return;
119
120 urj_completion_mayben_add_matches (matches, match_cnt, text, text_len, dir);
121 }
122
123 static void
cmd_dr_help(void)124 cmd_dr_help (void)
125 {
126 urj_log (URJ_LOG_LEVEL_NORMAL,
127 _("Usage: %1$s [DIR]\n"
128 "Usage: %1$s BITSTRING\n"
129 "Usage: %1$s HEXSTRING\n"
130 "Display input or output data register content or set current register.\n"
131 "\n"
132 "DIR requested data register; possible values: 'in' for\n"
133 " input and 'out' for output; default is 'out'\n"
134 "BITSTRING set current data register with BITSTRING (e.g. 01010)\n"
135 "HEXSTRING set current data register with HEXSTRING (e.g. 0x123)\n"),
136 "dr");
137 }
138
139 const urj_cmd_t urj_cmd_dr = {
140 "dr",
141 N_("display active data register for a part"),
142 cmd_dr_help,
143 cmd_dr_run,
144 cmd_dr_complete,
145 };
146