1 /* SPDX-License-Identifier: GPL-2.0-or-later */
4 * Copyright (C) 2020 by Antonio Borneo <borneo.antonio@gmail.com
6 * SWIM (Single Wire Interface Module) is a low-pin-count debug protocol
7 * used by STMicroelectronics MCU family STM8 and documented in UM470
8 * https://www.st.com/resource/en/user_manual/cd00173911.pdf
15 #include "interface.h"
17 #include <helper/command.h>
18 #include <transport/transport.h>
20 extern struct adapter_driver
*adapter_driver
;
22 int swim_system_reset(void)
24 assert(adapter_driver
->swim_ops
);
26 return adapter_driver
->swim_ops
->srst();
29 int swim_read_mem(uint32_t addr
, uint32_t size
, uint32_t count
,
32 assert(adapter_driver
->swim_ops
);
34 return adapter_driver
->swim_ops
->read_mem(addr
, size
, count
, buffer
);
37 int swim_write_mem(uint32_t addr
, uint32_t size
, uint32_t count
,
38 const uint8_t *buffer
)
40 assert(adapter_driver
->swim_ops
);
42 return adapter_driver
->swim_ops
->write_mem(addr
, size
, count
, buffer
);
45 int swim_reconnect(void)
47 assert(adapter_driver
->swim_ops
);
49 return adapter_driver
->swim_ops
->reconnect();
52 COMMAND_HANDLER(handle_swim_newtap_command
)
57 * only need "basename" and "tap_type", but for backward compatibility
58 * ignore extra parameters
61 return ERROR_COMMAND_SYNTAX_ERROR
;
63 tap
= calloc(1, sizeof(*tap
));
65 LOG_ERROR("Out of memory");
69 tap
->chip
= strdup(CMD_ARGV
[0]);
70 tap
->tapname
= strdup(CMD_ARGV
[1]);
71 tap
->dotted_name
= alloc_printf("%s.%s", CMD_ARGV
[0], CMD_ARGV
[1]);
72 if (!tap
->chip
|| !tap
->tapname
|| !tap
->dotted_name
) {
73 LOG_ERROR("Out of memory");
74 free(tap
->dotted_name
);
81 LOG_DEBUG("Creating new SWIM \"tap\", Chip: %s, Tap: %s, Dotted: %s",
82 tap
->chip
, tap
->tapname
, tap
->dotted_name
);
84 /* default is enabled-after-reset */
91 static const struct command_registration swim_transport_subcommand_handlers
[] = {
94 .handler
= handle_swim_newtap_command
,
95 .mode
= COMMAND_CONFIG
,
96 .help
= "Create a new TAP instance named basename.tap_type, "
97 "and appends it to the scan chain.",
98 .usage
= "basename tap_type",
100 COMMAND_REGISTRATION_DONE
103 static const struct command_registration swim_transport_command_handlers
[] = {
107 .help
= "perform swim adapter actions",
109 .chain
= swim_transport_subcommand_handlers
,
111 COMMAND_REGISTRATION_DONE
114 static int swim_transport_select(struct command_context
*cmd_ctx
)
118 return register_commands(cmd_ctx
, NULL
, swim_transport_command_handlers
);
121 static int swim_transport_init(struct command_context
*cmd_ctx
)
123 enum reset_types jtag_reset_config
= jtag_get_reset_config();
127 if (jtag_reset_config
& RESET_CNCT_UNDER_SRST
) {
128 if (jtag_reset_config
& RESET_SRST_NO_GATING
)
129 adapter_assert_reset();
131 LOG_WARNING("\'srst_nogate\' reset_config option is required");
133 adapter_deassert_reset();
138 static struct transport swim_transport
= {
140 .select
= swim_transport_select
,
141 .init
= swim_transport_init
,
144 static void swim_constructor(void) __attribute__ ((constructor
));
145 static void swim_constructor(void)
147 transport_register(&swim_transport
);
150 bool transport_is_swim(void)
152 return get_current_transport() == &swim_transport
;