2 * Copyright (C) 2019-2020 by Marc Schink <dev@zapb.de>
4 * This program is free software; you can redistribute it and/or modify
5 * it under the terms of the GNU General Public License as published by
6 * the Free Software Foundation; either version 2 of the License, or
7 * (at your option) any later version.
9 * This program is distributed in the hope that it will be useful,
10 * but WITHOUT ANY WARRANTY; without even the implied warranty of
11 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
12 * GNU General Public License for more details.
14 * You should have received a copy of the GNU General Public License
15 * along with this program. If not, see <http://www.gnu.org/licenses/>.
22 #include <helper/log.h>
23 #include <target/rtt.h>
27 #define CHANNEL_NAME_SIZE 128
29 COMMAND_HANDLER(handle_rtt_setup_command)
31 struct rtt_source source;
34 return ERROR_COMMAND_SYNTAX_ERROR;
36 source.find_cb = &target_rtt_find_control_block;
37 source.read_cb = &target_rtt_read_control_block;
38 source.start = &target_rtt_start;
39 source.stop = &target_rtt_stop;
40 source.read = &target_rtt_read_callback;
41 source.write = &target_rtt_write_callback;
42 source.read_channel_info = &target_rtt_read_channel_info;
44 target_addr_t address;
47 COMMAND_PARSE_NUMBER(target_addr, CMD_ARGV[0], address);
48 COMMAND_PARSE_NUMBER(u32, CMD_ARGV[1], size);
50 rtt_register_source(source, get_current_target(CMD_CTX));
52 if (rtt_setup(address, size, CMD_ARGV[2]) != ERROR_OK)
58 COMMAND_HANDLER(handle_rtt_start_command)
61 return ERROR_COMMAND_SYNTAX_ERROR;
63 if (!rtt_configured()) {
64 command_print(CMD, "RTT is not configured");
71 COMMAND_HANDLER(handle_rtt_stop_command)
74 return ERROR_COMMAND_SYNTAX_ERROR;
79 COMMAND_HANDLER(handle_rtt_polling_interval_command)
83 unsigned int interval;
85 ret = rtt_get_polling_interval(&interval);
87 if (ret != ERROR_OK) {
88 command_print(CMD, "Failed to get polling interval");
92 command_print(CMD, "%u ms", interval);
93 } else if (CMD_ARGC == 1) {
95 unsigned int interval;
97 COMMAND_PARSE_NUMBER(uint, CMD_ARGV[0], interval);
98 ret = rtt_set_polling_interval(interval);
100 if (ret != ERROR_OK) {
101 command_print(CMD, "Failed to set polling interval");
105 return ERROR_COMMAND_SYNTAX_ERROR;
111 COMMAND_HANDLER(handle_rtt_channels_command)
114 char channel_name[CHANNEL_NAME_SIZE];
115 const struct rtt_control *ctrl;
116 struct rtt_channel_info info;
118 if (!rtt_found_cb()) {
119 command_print(CMD, "rtt: Control block not available");
123 ctrl = rtt_get_control();
125 command_print(CMD, "Channels: up=%u, down=%u", ctrl->num_up_channels,
126 ctrl->num_down_channels);
128 command_print(CMD, "Up-channels:");
130 info.name = channel_name;
131 info.name_length = sizeof(channel_name);
133 for (unsigned int i = 0; i < ctrl->num_up_channels; i++) {
134 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
142 command_print(CMD, "%u: %s %u %u", i, info.name, info.size,
146 command_print(CMD, "Down-channels:");
148 for (unsigned int i = 0; i < ctrl->num_down_channels; i++) {
149 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
157 command_print(CMD, "%u: %s %u %u", i, info.name, info.size,
164 static int jim_channel_list(Jim_Interp *interp, int argc,
165 Jim_Obj * const *argv)
168 Jim_Obj *channel_list;
169 char channel_name[CHANNEL_NAME_SIZE];
170 const struct rtt_control *ctrl;
171 struct rtt_channel_info info;
173 if (!rtt_found_cb()) {
174 Jim_SetResultFormatted(interp, "rtt: Control block not available");
178 ctrl = rtt_get_control();
180 info.name = channel_name;
181 info.name_length = sizeof(channel_name);
183 list = Jim_NewListObj(interp, NULL, 0);
184 channel_list = Jim_NewListObj(interp, NULL, 0);
186 for (unsigned int i = 0; i < ctrl->num_up_channels; i++) {
190 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_UP, &info);
198 tmp = Jim_NewListObj(interp, NULL, 0);
200 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
202 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
205 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
207 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
210 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
212 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
215 Jim_ListAppendElement(interp, channel_list, tmp);
218 Jim_ListAppendElement(interp, list, channel_list);
220 channel_list = Jim_NewListObj(interp, NULL, 0);
222 for (unsigned int i = 0; i < ctrl->num_down_channels; i++) {
226 ret = rtt_read_channel_info(i, RTT_CHANNEL_TYPE_DOWN, &info);
234 tmp = Jim_NewListObj(interp, NULL, 0);
236 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
238 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
241 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
243 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
246 Jim_ListAppendElement(interp, tmp, Jim_NewStringObj(interp,
248 Jim_ListAppendElement(interp, tmp, Jim_NewIntObj(interp,
251 Jim_ListAppendElement(interp, channel_list, tmp);
254 Jim_ListAppendElement(interp, list, channel_list);
255 Jim_SetResult(interp, list);
260 static const struct command_registration rtt_subcommand_handlers[] = {
263 .handler = handle_rtt_setup_command,
266 .usage = "<address> <size> <ID>"
270 .handler = handle_rtt_start_command,
271 .mode = COMMAND_EXEC,
277 .handler = handle_rtt_stop_command,
278 .mode = COMMAND_EXEC,
283 .name = "polling_interval",
284 .handler = handle_rtt_polling_interval_command,
285 .mode = COMMAND_EXEC,
286 .help = "show or set polling interval in ms",
287 .usage = "[interval]"
291 .handler = handle_rtt_channels_command,
292 .mode = COMMAND_EXEC,
293 .help = "list available channels",
297 .name = "channellist",
298 .jim_handler = jim_channel_list,
299 .mode = COMMAND_EXEC,
300 .help = "list available channels",
303 COMMAND_REGISTRATION_DONE
306 const struct command_registration rtt_target_command_handlers[] = {
309 .mode = COMMAND_EXEC,
310 .help = "RTT target commands",
312 .chain = rtt_subcommand_handlers
314 COMMAND_REGISTRATION_DONE