X-Git-Url: https://review.openocd.org/gitweb?a=blobdiff_plain;f=src%2Fjtag%2Fjtag.h;h=40639dce63fee70788028d4a4e213bb555e1f795;hb=175867ea323137285a5389fc6a65105c06853651;hp=bc9470e1bb84769934595f7ccd38a6e2534b3584;hpb=4bc3af0374c43492040b8a17ab78be05f7b3094f;p=openocd.git diff --git a/src/jtag/jtag.h b/src/jtag/jtag.h index bc9470e1bb..40639dce63 100644 --- a/src/jtag/jtag.h +++ b/src/jtag/jtag.h @@ -104,8 +104,6 @@ const char* tap_state_name(tap_state_t state); /// The current TAP state of the pending JTAG command queue. extern tap_state_t cmd_queue_cur_state; -/// The TAP state in which DR scans should end. -extern tap_state_t cmd_queue_end_state; /** * This structure defines a single scan field in the scan. It provides @@ -177,20 +175,20 @@ struct jtag_tap_s jtag_tap_t* next_tap; }; -extern jtag_tap_t* jtag_AllTaps(void); -extern jtag_tap_t* jtag_TapByPosition(int n); -extern jtag_tap_t* jtag_TapByString(const char* dotted_name); -extern jtag_tap_t* jtag_TapByJimObj(Jim_Interp* interp, Jim_Obj* obj); -extern jtag_tap_t* jtag_TapByAbsPosition(int abs_position); -extern int jtag_NumEnabledTaps(void); -extern int jtag_NumTotalTaps(void); - -static __inline__ jtag_tap_t* jtag_NextEnabledTap(jtag_tap_t* p) +extern jtag_tap_t* jtag_all_taps(void); +extern const char *jtag_tap_name(const jtag_tap_t *tap); +extern jtag_tap_t* jtag_tap_by_string(const char* dotted_name); +extern jtag_tap_t* jtag_tap_by_jim_obj(Jim_Interp* interp, Jim_Obj* obj); +extern jtag_tap_t* jtag_tap_by_position(unsigned abs_position); +extern unsigned jtag_tap_count_enabled(void); +extern unsigned jtag_tap_count(void); + +static __inline__ jtag_tap_t* jtag_tap_next_enabled(jtag_tap_t* p) { if (p == NULL) { /* start at the head of list */ - p = jtag_AllTaps(); + p = jtag_all_taps(); } else { @@ -218,19 +216,26 @@ enum reset_line_mode { LINE_PUSH_PULL = 0x1, }; +/* + * There are three cases when JTAG_TRST_ASSERTED callback is invoked. The + * event is invoked *after* TRST is asserted(or queued rather). It is illegal + * to communicate with the JTAG interface during the callback(as there is + * currently a queue being built). + * + * - TMS reset + * - SRST pulls TRST + * - TRST asserted + * + **/ enum jtag_event { JTAG_TRST_ASSERTED }; -extern char* jtag_event_strings[]; - enum jtag_tap_event { JTAG_TAP_EVENT_ENABLE, JTAG_TAP_EVENT_DISABLE }; -extern const Jim_Nvp nvp_jtag_tap_event[]; - struct jtag_tap_event_action_s { enum jtag_tap_event event; @@ -238,8 +243,10 @@ struct jtag_tap_event_action_s jtag_tap_event_action_t* next; }; -extern int jtag_trst; -extern int jtag_srst; +/// @returns The current state of TRST. +int jtag_get_trst(void); +/// @returns The current state of SRST. +int jtag_get_srst(void); typedef struct jtag_event_callback_s { @@ -299,12 +306,29 @@ extern int jtag_register_commands(struct command_context_s* cmd_ctx); * end state and a subsequent jtag_add_pathmove() must be issued. */ +/** + * Generate an IR SCAN with a list of scan fields with one entry for + * each enabled TAP. + * + * If the input field list contains an instruction value for a TAP then + * that is used otherwise the TAP is set to bypass. + * + * TAPs for which no fields are passed are marked as bypassed for + * subsequent DR SCANs. + * + */ extern void jtag_add_ir_scan(int num_fields, scan_field_t* fields, tap_state_t endstate); /** * The same as jtag_add_ir_scan except no verification is performed out * the output values. */ extern void jtag_add_ir_scan_noverify(int num_fields, const scan_field_t *fields, tap_state_t state); +/** + * Duplicate the scan fields passed into the function into an IR SCAN + * command. This function assumes that the caller handles extra fields + * for bypassed TAPs. + */ +extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); /** @@ -318,10 +342,20 @@ extern void jtag_add_ir_scan_noverify(int num_fields, const scan_field_t *fields */ extern void jtag_alloc_in_value32(scan_field_t *field); +/** + * Generate a DR SCAN using the fields passed to the function. + * For connected TAPs, the function checks in_fields and uses fields + * specified there. For bypassed TAPs, the function generates a dummy + * 1-bit field. The bypass status of TAPs is set by jtag_add_ir_scan(). + */ extern void jtag_add_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); /// A version of jtag_add_dr_scan() that uses the check_value/mask fields extern void jtag_add_dr_scan_check(int num_fields, scan_field_t* fields, tap_state_t endstate); -extern void jtag_add_plain_ir_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); +/** + * Duplicate the scan fields passed into the function into a DR SCAN + * command. Unlike jtag_add_dr_scan(), this function assumes that the + * caller handles extra fields for bypassed TAPs. + */ extern void jtag_add_plain_dr_scan(int num_fields, const scan_field_t* fields, tap_state_t endstate); @@ -437,6 +471,12 @@ extern void jtag_add_tlr(void); * can only implement a few transitions and therefore * a partial implementation of pathmove would have little practical * application. + * + * If an error occurs, jtag_error will contain one of these error codes: + * - ERROR_JTAG_NOT_STABLE_STATE -- The final state was not stable. + * - ERROR_JTAG_STATE_INVALID -- The path passed through TAP_RESET. + * - ERROR_JTAG_TRANSITION_INVALID -- The path includes invalid + * state transitions. */ extern void jtag_add_pathmove(int num_states, const tap_state_t* path); @@ -477,7 +517,23 @@ extern void jtag_add_runtest(int num_cycles, tap_state_t endstate); */ extern void jtag_add_reset(int req_tlr_or_trst, int srst); -extern void jtag_add_end_state(tap_state_t endstate); + +/** + * Function jtag_set_end_state + * + * Set a global variable to \a state if \a state != TAP_INVALID. + * + * Return the value of the global variable. + * + **/ +extern tap_state_t jtag_set_end_state(tap_state_t state); +/** + * Function jtag_get_end_state + * + * Return the value of the global variable for end state + * + **/ +extern tap_state_t jtag_get_end_state(void); extern void jtag_add_sleep(u32 us); @@ -535,7 +591,16 @@ static __inline__ void jtag_set_error(int error) jtag_error=error; } - +/** + * Resets jtag_error to ERROR_OK, returning its previous value. + * @returns The previous value of @c jtag_error. + */ +static inline int jtag_error_clear(void) +{ + int temp = jtag_error; + jtag_error = ERROR_OK; + return temp; +} /* can be implemented by hw+sw */ extern int jtag_power_dropout(int* dropout); @@ -552,10 +617,6 @@ extern int jtag_srst_asserted(int* srst_asserted); */ extern void jtag_check_value_mask(scan_field_t *field, u8 *value, u8 *mask); -#ifdef INCLUDE_JTAG_INTERFACE_H -#include "commands.h" -#endif // INCLUDE_JTAG_INTERFACE_H - extern void jtag_sleep(u32 us); extern int jtag_call_event_callbacks(enum jtag_event event); extern int jtag_register_event_callback(int (* callback)(enum jtag_event event, void* priv), void* priv); @@ -575,6 +636,8 @@ void jtag_tap_handle_event(jtag_tap_t* tap, enum jtag_tap_event e); #define ERROR_JTAG_QUEUE_FAILED (-104) #define ERROR_JTAG_NOT_STABLE_STATE (-105) #define ERROR_JTAG_DEVICE_ERROR (-107) +#define ERROR_JTAG_STATE_INVALID (-108) +#define ERROR_JTAG_TRANSITION_INVALID (-109) /** * jtag_add_dr_out() is a version of jtag_add_dr_scan() which @@ -610,12 +673,49 @@ extern void jtag_add_dr_out(jtag_tap_t* tap, /** * jtag_add_statemove() moves from the current state to @a goal_state. * - * This function was originally designed to handle the XSTATE command - * from the XSVF specification. - * * @param goal_state The final TAP state. * @return ERROR_OK on success, or an error code on failure. + * + * Moves from the current state to the goal \a state. + * + * This needs to be handled according to the xsvf spec, see the XSTATE + * command description. From the XSVF spec, pertaining to XSTATE: + * + * For special states known as stable states (Test-Logic-Reset, + * Run-Test/Idle, Pause-DR, Pause- IR), an XSVF interpreter follows + * predefined TAP state paths when the starting state is a stable state + * and when the XSTATE specifies a new stable state. See the STATE + * command in the [Ref 5] for the TAP state paths between stable + * states. + * + * For non-stable states, XSTATE should specify a state that is only one + * TAP state transition distance from the current TAP state to avoid + * undefined TAP state paths. A sequence of multiple XSTATE commands can + * be issued to transition the TAP through a specific state path. + * + * @note Unless @c tms_bits holds a path that agrees with [Ref 5] in the + * above spec, then this code is not fully conformant to the xsvf spec. + * This puts a burden on tap_get_tms_path() function from the xsvf spec. + * If in doubt, you should confirm that that burden is being met. + * + * Otherwise, @a goal_state must be immediately reachable in one clock + * cycle, and does not need to be a stable state. */ extern int jtag_add_statemove(tap_state_t goal_state); +/// @returns the number of times the scan queue has been flushed +int jtag_get_flush_queue_count(void); + +void jtag_set_nsrst_delay(unsigned delay); +unsigned jtag_get_nsrst_delay(void); + +void jtag_set_ntrst_delay(unsigned delay); +unsigned jtag_get_ntrst_delay(void); + +void jtag_set_speed_khz(unsigned speed); +unsigned jtag_get_speed_khz(void); + +void jtag_set_verify(bool enable); +bool jtag_will_verify(void); + #endif /* JTAG_H */