{
int num_states = cmd->num_states;
int state_count;
- int tms;
+ int tms = 0;
state_count = 0;
while (num_states)
{
enum tap_state saved_end_state = end_state;
int bit_cnt;
- int last_bit, last_bit_in;
if (!((!ir_scan && (cur_state == TAP_SD)) || (ir_scan && (cur_state == TAP_SI))))
{
bitbang_end_state(saved_end_state);
}
- for (bit_cnt = 0; bit_cnt < scan_size - 1; bit_cnt++)
+ for (bit_cnt = 0; bit_cnt < scan_size; bit_cnt++)
{
/* if we're just reading the scan, but don't care about the output
* default to outputting 'low', this also makes valgrind traces more readable,
*/
if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
{
- bitbang_interface->write(0, 0, 1);
- bitbang_interface->write(1, 0, 1);
+ bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 1);
+ bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 1);
} else {
- bitbang_interface->write(0, 0, 0);
- bitbang_interface->write(1, 0, 0);
+ bitbang_interface->write(0, (bit_cnt==scan_size-1) ? 1 : 0, 0);
+ bitbang_interface->write(1, (bit_cnt==scan_size-1) ? 1 : 0, 0);
}
if (type != SCAN_OUT)
{
+ /*
+ TDO should be sampled on the rising edge, and will change
+ on the falling edge.
+
+ Because there is no way to read the signal exactly at the rising edge,
+ read after the rising edge.
+
+ This is plain IEEE 1149 JTAG - nothing specific to the OpenOCD or its JTAG
+ API.
+ */
if (bitbang_interface->read())
buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
else
buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
}
}
-
- if ((type != SCAN_IN) && ((buffer[bit_cnt/8] >> (bit_cnt % 8)) & 0x1))
- last_bit = 1;
- else
- last_bit = 0;
-
- if ((ir_scan && (end_state == TAP_SI)) ||
- (!ir_scan && (end_state == TAP_SD)))
- {
- bitbang_interface->write(0, 0, last_bit);
- bitbang_interface->write(1, 0, last_bit);
-
- if (type != SCAN_OUT)
- last_bit_in = bitbang_interface->read();
-
- bitbang_interface->write(0, 0, last_bit);
- }
+
+ /* TAP_SD & TAP_SI are illegal end states, so we always transition to the pause
+ * state which is a legal stable state from which statemove will work.
+ *
+ * Exit1 -> Pause
+ */
+ bitbang_interface->write(0, 0, 0);
+ bitbang_interface->write(1, 0, 0);
+ bitbang_interface->write(0, 0, 0);
+
+ if (ir_scan)
+ cur_state = TAP_PI;
else
- {
- /* Shift-[ID]R -> Exit1-[ID]R */
- bitbang_interface->write(0, 1, last_bit);
- bitbang_interface->write(1, 1, last_bit);
-
- if (type != SCAN_OUT)
- last_bit_in = bitbang_interface->read();
-
- /* Exit1-[ID]R -> Pause-[ID]R */
- bitbang_interface->write(0, 0, 0);
- bitbang_interface->write(1, 0, 0);
-
- if (cur_state == TAP_SI)
- cur_state = TAP_PI;
- else
- cur_state = TAP_PD;
-
- if (cur_state != end_state)
- bitbang_state_move();
- else
- bitbang_interface->write(0, 0, 0);
- }
-
- if (type != SCAN_OUT)
- {
- if (last_bit_in)
- buffer[(bit_cnt)/8] |= 1 << ((bit_cnt) % 8);
- else
- buffer[(bit_cnt)/8] &= ~(1 << ((bit_cnt) % 8));
- }
+ cur_state = TAP_PD;
+
+ if (cur_state != end_state)
+ bitbang_state_move();
}
int bitbang_execute_queue(void)
void jtag_add_statemove(enum tap_state endstate);
void jtag_add_pathmove(int num_states, enum tap_state *path);
void jtag_add_runtest(int num_cycles, enum tap_state endstate);
-int jtag_add_reset(int trst, int srst);
+void jtag_add_reset(int trst, int srst);
void jtag_add_end_state(enum tap_state endstate);
void jtag_add_sleep(u32 us);
int jtag_execute_queue(void);
jtag_prelude1();
if (state != -1)
- cmd_queue_end_state = state;
+ jtag_add_end_state(state);
cmd_queue_cur_state = cmd_queue_end_state;
}
jtag_error=retval;
}
-int jtag_add_reset(int req_trst, int req_srst)
+void jtag_add_reset(int req_trst, int req_srst)
{
int trst_with_tms = 0;
int retval;
- if (req_trst == -1)
- req_trst = jtag_trst;
-
- if (req_srst == -1)
- req_srst = jtag_srst;
-
/* Make sure that jtag_reset_config allows the requested reset */
/* if SRST pulls TRST, we can't fulfill srst == 1 with trst == 0 */
if (((jtag_reset_config & RESET_SRST_PULLS_TRST) && (req_srst == 1)) && (req_trst == 0))
{
- LOG_WARNING("requested reset would assert trst");
- return ERROR_JTAG_RESET_WOULD_ASSERT_TRST;
+ LOG_ERROR("BUG: requested reset would assert trst");
+ jtag_error=ERROR_FAIL;
+ return;
}
/* if TRST pulls SRST, we reset with TAP T-L-R */
if (req_srst && !(jtag_reset_config & RESET_HAS_SRST))
{
- LOG_WARNING("requested nSRST assertion, but the current configuration doesn't support this");
- return ERROR_JTAG_RESET_CANT_SRST;
+ LOG_ERROR("BUG: requested nSRST assertion, but the current configuration doesn't support this");
+ jtag_error=ERROR_FAIL;
+ return;
}
if (req_trst && !(jtag_reset_config & RESET_HAS_TRST))
if (retval!=ERROR_OK)
{
jtag_error=retval;
- return retval;
+ return;
}
if (jtag_srst)
jtag_add_end_state(TAP_TLR);
jtag_add_statemove(TAP_TLR);
jtag_call_event_callbacks(JTAG_TRST_ASSERTED);
- return ERROR_OK;
+ return;
}
if (jtag_trst)
if (jtag_ntrst_delay)
jtag_add_sleep(jtag_ntrst_delay * 1000);
}
- return ERROR_OK;
}
int MINIDRIVER(interface_jtag_add_reset)(int req_trst, int req_srst)
void jtag_add_end_state(enum tap_state state)
{
cmd_queue_end_state = state;
+ if ((cmd_queue_end_state == TAP_SD)||(cmd_queue_end_state == TAP_SD))
+ {
+ LOG_ERROR("BUG: TAP_SD/SI can't be end state. Calling code should use a larger scan field");
+ }
}
int MINIDRIVER(interface_jtag_add_sleep)(u32 us)
extern int jtag_init(struct command_context_s *cmd_ctx);
extern int jtag_register_commands(struct command_context_s *cmd_ctx);
-/* JTAG interface, can be implemented with a software or hardware fifo */
+/* JTAG interface, can be implemented with a software or hardware fifo
+ *
+ * TAP_SD and TAP_SI are illegal end states. TAP_SD/SI as end states
+ * can be emulated by using a larger scan.
+ */
extern void jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
extern int interface_jtag_add_ir_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
extern void jtag_add_dr_scan(int num_fields, scan_field_t *fields, enum tap_state endstate);
*/
extern void jtag_add_runtest(int num_cycles, enum tap_state endstate);
extern int interface_jtag_add_runtest(int num_cycles, enum tap_state endstate);
-/* If it fails and one of the error messages below are returned, nothing is
- * added to the queue and jtag_execute() won't return an error code.
- *
- * ERROR_JTAG_RESET_WOULD_ASSERT_TRST
- * ERROR_JTAG_RESET_CANT_SRST
+/* Invoking jtag_add_reset() with unsupported combinations is
+ * not allowed and constitutes a bug in the calling code.
*
- * All other error codes will result in jtag_execute_queue() returning
- * an error.
+ * trst & srst must be 0 or 1. There is no way to
+ * read the current reset state.
*/
-extern int jtag_add_reset(int trst, int srst);
+extern void jtag_add_reset(int trst, int srst);
extern int interface_jtag_add_reset(int trst, int srst);
extern void jtag_add_end_state(enum tap_state endstate);
extern int interface_jtag_add_end_state(enum tap_state endstate);
#define ERROR_JTAG_NOT_IMPLEMENTED (-102)
#define ERROR_JTAG_TRST_ASSERTED (-103)
#define ERROR_JTAG_QUEUE_FAILED (-104)
-#define ERROR_JTAG_RESET_WOULD_ASSERT_TRST (-105)
-#define ERROR_JTAG_RESET_CANT_SRST (-106)
#define ERROR_JTAG_DEVICE_ERROR (-107)
int arm7_9_assert_reset(target_t *target)
{
- int retval;
-
LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
+ if (!(jtag_reset_config & RESET_HAS_SRST))
+ {
+ LOG_ERROR("Can't assert SRST");
+ return ERROR_FAIL;
+ }
+
if (target->state == TARGET_HALTED || target->state == TARGET_UNKNOWN)
{
/* if the target wasn't running, there might be working areas allocated */
/* assert SRST and TRST */
/* system would get ouf sync if we didn't reset test-logic, too */
- if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_CANT_SRST)
- {
- return retval;
- }
- else
- {
- LOG_ERROR("unknown error");
- exit(-1);
- }
- }
+ jtag_add_reset(1, 1);
+
jtag_add_sleep(5000);
- if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
- {
- retval = jtag_add_reset(1, 1);
- }
- }
+
}
- else
+
+ if (jtag_reset_config & RESET_SRST_PULLS_TRST)
{
- if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
- {
- retval = jtag_add_reset(1, 1);
- }
-
- if (retval == ERROR_JTAG_RESET_CANT_SRST)
- {
- return retval;
- }
- else if (retval != ERROR_OK)
- {
- LOG_ERROR("unknown error");
- exit(-1);
- }
- }
+ jtag_add_reset(1, 1);
+ } else
+ {
+ jtag_add_reset(0, 1);
}
target->state = TARGET_RESET;
int cortex_m3_assert_reset(target_t *target)
{
- int retval;
armv7m_common_t *armv7m = target->arch_info;
cortex_m3_common_t *cortex_m3 = armv7m->arch_info;
swjdp_common_t *swjdp = &cortex_m3->swjdp_info;
LOG_DEBUG("target->state: %s", target_state_strings[target->state]);
+ if (!(jtag_reset_config & RESET_HAS_SRST))
+ {
+ LOG_ERROR("Can't assert SRST");
+ return ERROR_FAIL;
+ }
+
ahbap_write_system_u32(swjdp, DCB_DCRDR, 0 );
if (target->reset_mode == RESET_RUN)
{
/* assert SRST and TRST */
/* system would get ouf sync if we didn't reset test-logic, too */
- if ((retval = jtag_add_reset(1, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_CANT_SRST)
- {
- return retval;
- }
- else
- {
- LOG_ERROR("unknown error");
- exit(-1);
- }
- }
+ jtag_add_reset(1, 1);
jtag_add_sleep(5000);
- if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
- {
- retval = jtag_add_reset(1, 1);
- }
- }
}
- else
+
+ if (jtag_reset_config & RESET_SRST_PULLS_TRST)
{
- if ((retval = jtag_add_reset(0, 1)) != ERROR_OK)
- {
- if (retval == ERROR_JTAG_RESET_WOULD_ASSERT_TRST)
- {
- retval = jtag_add_reset(1, 1);
- }
-
- if (retval == ERROR_JTAG_RESET_CANT_SRST)
- {
- return retval;
- }
- else if (retval != ERROR_OK)
- {
- LOG_ERROR("unknown error");
- exit(-1);
- }
- }
+ jtag_add_reset(1, 1);
+ } else
+ {
+ jtag_add_reset(0, 1);
}
target->state = TARGET_RESET;