#endif
#include "jtag.h"
+#include "swd.h"
#include "interface.h"
#include <transport/transport.h>
* when an event occurs.
*/
struct jtag_event_callback {
- /* / a event callback */
+ /** a event callback */
jtag_event_handler_t callback;
- /* / the private data to pass to the callback */
+ /** the private data to pass to the callback */
void *priv;
- /* / the next callback */
+ /** the next callback */
struct jtag_event_callback *next;
};
return n;
}
-/* / Append a new TAP to the chain of all taps. */
+/** Append a new TAP to the chain of all taps. */
void jtag_tap_add(struct jtag_tap *t)
{
t->abs_chain_position = jtag_num_taps++;
}
}
+void swd_add_reset(int req_srst)
+{
+ if (req_srst) {
+ if (!(jtag_reset_config & RESET_HAS_SRST)) {
+ LOG_ERROR("BUG: can't assert SRST");
+ jtag_set_error(ERROR_FAIL);
+ return;
+ }
+ req_srst = 1;
+ }
+
+ /* Maybe change SRST signal state */
+ if (jtag_srst != req_srst) {
+ int retval;
+
+ retval = interface_jtag_add_reset(0, req_srst);
+ if (retval != ERROR_OK)
+ jtag_set_error(retval);
+ else
+ retval = jtag_execute_queue();
+
+ if (retval != ERROR_OK) {
+ LOG_ERROR("TRST/SRST error");
+ return;
+ }
+
+ /* SRST resets everything hooked up to that signal */
+ jtag_srst = req_srst;
+ if (jtag_srst) {
+ LOG_DEBUG("SRST line asserted");
+ if (adapter_nsrst_assert_width)
+ jtag_add_sleep(adapter_nsrst_assert_width * 1000);
+ } else {
+ LOG_DEBUG("SRST line released");
+ if (adapter_nsrst_delay)
+ jtag_add_sleep(adapter_nsrst_delay * 1000);
+ }
+ }
+}
+
void jtag_add_reset(int req_tlr_or_trst, int req_srst)
{
int trst_with_tlr = 0;
void jtag_add_sleep(uint32_t us)
{
- /* / @todo Here, keep_alive() appears to be a layering violation!!! */
+ /** @todo Here, keep_alive() appears to be a layering violation!!! */
keep_alive();
jtag_set_error(interface_jtag_add_sleep(us));
}
/* A reserved manufacturer ID is used in END_OF_CHAIN_FLAG, so we
* know that no valid TAP will have it as an IDCODE value.
*/
-#define END_OF_CHAIN_FLAG 0x000000ff
+#define END_OF_CHAIN_FLAG 0xffffffff
/* a larger IR length than we ever expect to autoprobe */
#define JTAG_IRLEN_MAX 60
{
/*
* Some devices, such as AVR8, will output all 1's instead
- * of TDI input value at end of chain. Allow those values
+ * of TDI input value at end of chain. Allow those values
* instead of failing.
*/
- return idcode == END_OF_CHAIN_FLAG || idcode == 0xFFFFFFFF;
+ return idcode == END_OF_CHAIN_FLAG;
}
/**
if (0 == tap->expected_ids_cnt && !idcode)
return true;
- /* optionally ignore the JTAG version field */
- uint32_t mask = tap->ignore_version ? ~(0xff << 24) : ~0;
+ /* optionally ignore the JTAG version field - bits 28-31 of IDCODE */
+ uint32_t mask = tap->ignore_version ? ~(0xf << 28) : ~0;
idcode &= mask;
tap->expected_mask = calloc(1, ir_len_bytes);
tap->cur_instr = malloc(ir_len_bytes);
- /* / @todo cope better with ir_length bigger than 32 bits */
+ /** @todo cope better with ir_length bigger than 32 bits */
if (ir_len_bits > 32)
ir_len_bits = 32;
/* register the reset callback for the TAP */
jtag_register_event_callback(&jtag_reset_callback, tap);
+ jtag_tap_add(tap);
LOG_DEBUG("Created Tap: %s @ abs position %d, "
- "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name,
- tap->abs_chain_position, tap->ir_length,
- (unsigned) tap->ir_capture_value,
- (unsigned) tap->ir_capture_mask);
- jtag_tap_add(tap);
+ "irlen %d, capture: 0x%x mask: 0x%x", tap->dotted_name,
+ tap->abs_chain_position, tap->ir_length,
+ (unsigned) tap->ir_capture_value,
+ (unsigned) tap->ir_capture_mask);
}
void jtag_tap_free(struct jtag_tap *tap)
{
jtag_unregister_event_callback(&jtag_reset_callback, tap);
- /* / @todo is anything missing? no memory leaks please */
+ /** @todo is anything missing? no memory leaks please */
free((void *)tap->expected);
free((void *)tap->expected_ids);
free((void *)tap->chip);
return ERROR_OK;
}
+int swd_init_reset(struct command_context *cmd_ctx)
+{
+ int retval = adapter_init(cmd_ctx);
+ if (retval != ERROR_OK)
+ return retval;
+
+ LOG_DEBUG("Initializing with hard SRST reset");
+
+ if (jtag_reset_config & RESET_HAS_SRST)
+ swd_add_reset(1);
+ swd_add_reset(0);
+ retval = jtag_execute_queue();
+ return retval;
+}
int jtag_init_reset(struct command_context *cmd_ctx)
{
{
return get_current_transport() == &jtag_transport;
}
+
+void adapter_assert_reset(void)
+{
+ if (transport_is_jtag()) {
+ if (jtag_reset_config & RESET_SRST_PULLS_TRST)
+ jtag_add_reset(1, 1);
+ else
+ jtag_add_reset(0, 1);
+ } else if (transport_is_swd())
+ swd_add_reset(1);
+ else if (get_current_transport() != NULL)
+ LOG_ERROR("reset is not supported on %s",
+ get_current_transport()->name);
+ else
+ LOG_ERROR("transport is not selected");
+}
+
+void adapter_deassert_reset(void)
+{
+ if (transport_is_jtag())
+ jtag_add_reset(0, 0);
+ else if (transport_is_swd())
+ swd_add_reset(0);
+ else if (get_current_transport() != NULL)
+ LOG_ERROR("reset is not supported on %s",
+ get_current_transport()->name);
+ else
+ LOG_ERROR("transport is not selected");
+}