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