* { TAP_RESET, TAP_IDLE, TAP_DRSHIFT, TAP_DRPAUSE, TAP_IRSHIFT, TAP_IRPAUSE } *
* This sequence corresponds to look up tables which are used in some of the * cable drivers. * @param astate is the stable state to find in the sequence. If a non stable * state is passed, this may cause the program to output an error message * and terminate. * @return int - the array (or sequence) index as described above */ int tap_move_ndx(tap_state_t astate); /** * Function tap_is_state_stable * returns true if the \a astate is stable. */ bool tap_is_state_stable(tap_state_t astate); /** * Function tap_state_transition * takes a current TAP state and returns the next state according to the tms value. * @param current_state is the state of a TAP currently. * @param tms is either zero or non-zero, just like a real TMS line in a jtag interface. * @return tap_state_t - the next state a TAP would enter. */ tap_state_t tap_state_transition(tap_state_t current_state, bool tms); /** Allow switching between old and new TMS tables. @see tap_get_tms_path */ void tap_use_new_tms_table(bool use_new); /** @returns True if new TMS table is active; false otherwise. */ bool tap_uses_new_tms_table(void); /** * @brief Prints verbose TAP state transitions for the given TMS/TDI buffers. * @param tms_buf must points to a buffer containing the TMS bitstream. * @param tdi_buf must points to a buffer containing the TDI bitstream. * @param tap_len must specify the length of the TMS/TDI bitstreams. * @param start_tap_state must specify the current TAP state. * @returns the final TAP state; pass as @a start_tap_state in following call. */ static inline tap_state_t jtag_debug_state_machine(const void *tms_buf, const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state) { /* Private declaration */ tap_state_t jtag_debug_state_machine_(const void *tms_buf, const void *tdi_buf, unsigned tap_len, tap_state_t start_tap_state); if (LOG_LEVEL_IS(LOG_LVL_DEBUG_IO)) return jtag_debug_state_machine_(tms_buf, tdi_buf, tap_len, start_tap_state); else return start_tap_state; } /** * Represents a driver for a debugging interface. * * @todo Rename; perhaps "debug_driver". This isn't an interface, * it's a driver! Also, not all drivers support JTAG. * * @todo We need a per-instance structure too, and changes to pass * that structure to the driver. Instances can for example be in * either SWD or JTAG modes. This will help remove globals, and * eventually to cope with systems which have more than one such * debugging interface. */ struct jtag_interface { /** * Bit vector listing capabilities exposed by this driver. */ unsigned supported; #define DEBUG_CAP_TMS_SEQ (1 << 0) /** * Execute queued commands. * @returns ERROR_OK on success, or an error code on failure. */ int (*execute_queue)(void); }; /** * Represents a driver for a debugging interface * * @todo We need a per-instance structure too, and changes to pass * that structure to the driver. Instances can for example be in * either SWD or JTAG modes. This will help remove globals, and * eventually to cope with systems which have more than one such * debugging interface. */ struct adapter_driver { /** The name of the interface driver. */ const char * const name; /** transports supported in C code (NULL terminated vector) */ const char * const *transports; /** * The interface driver may register additional commands to expose * additional features not covered by the standard command set. */ const struct command_registration *commands; /** * Interface driver must initialize any resources and connect to a * JTAG device. * * quit() is invoked if and only if init() succeeds. quit() is always * invoked if init() succeeds. Same as malloc() + free(). Always * invoke free() if malloc() succeeds and do not invoke free() * otherwise. * * @returns ERROR_OK on success, or an error code on failure. */ int (*init)(void); /** * Interface driver must tear down all resources and disconnect from * the JTAG device. * * @returns ERROR_OK on success, or an error code on failure. */ int (*quit)(void); /** * Control (assert/deassert) the signals SRST and TRST on the interface. * This function is synchronous and should be called after the adapter * queue has been properly flushed. * This function is optional. * Adapters that don't support resets can either not define this function * or return an error code. * Adapters that don't support one of the two reset should ignore the * request to assert the missing signal and eventually log an error. * * @param srst 1 to assert SRST, 0 to deassert SRST. * @param trst 1 to assert TRST, 0 to deassert TRST. * @returns ERROR_OK on success, or an error code on failure. */ int (*reset)(int srst, int trst); /** * Set the interface speed. * @param speed The new interface speed setting. * @returns ERROR_OK on success, or an error code on failure. */ int (*speed)(int speed); /** * Returns JTAG maxium speed for KHz. 0 = RTCK. The function returns * a failure if it can't support the KHz/RTCK. * * WARNING!!!! if RTCK is *slow* then think carefully about * whether you actually want to support this in the driver. * Many target scripts are written to handle the absence of RTCK * and use a fallback kHz TCK. * @returns ERROR_OK on success, or an error code on failure. */ int (*khz)(int khz, int *jtag_speed); /** * Calculate the clock frequency (in KHz) for the given @a speed. * @param speed The desired interface speed setting. * @param khz On return, contains the speed in KHz (0 for RTCK). * @returns ERROR_OK on success, or an error code if the * interface cannot support the specified speed (KHz or RTCK). */ int (*speed_div)(int speed, int *khz); /** * Read and clear the power dropout flag. Note that a power dropout * can be transitionary, easily much less than a ms. * * To find out if the power is *currently* on, one must invoke this * method twice. Once to clear the power dropout flag and a second * time to read the current state. The default implementation * never reports power dropouts. * * @returns ERROR_OK on success, or an error code on failure. */ int (*power_dropout)(int *power_dropout); /** * Read and clear the srst asserted detection flag. * * Like power_dropout this does *not* read the current * state. SRST assertion is transitionary and may be much * less than 1ms, so the interface driver must watch for these * events until this routine is called. * * @param srst_asserted On return, indicates whether SRST has * been asserted. * @returns ERROR_OK on success, or an error code on failure. */ int (*srst_asserted)(int *srst_asserted); /** * Configure trace parameters for the adapter * * @param enabled Whether to enable trace * @param pin_protocol Configured pin protocol * @param port_size Trace port width for sync mode * @param trace_freq A pointer to the configured trace * frequency; if it points to 0, the adapter driver must write * its maximum supported rate there * @param traceclkin_freq TRACECLKIN frequency provided to the TPIU in Hz * @param prescaler Pointer to the SWO prescaler calculated by the * adapter * @returns ERROR_OK on success, an error code on failure. */ int (*config_trace)(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler); /** * Poll for new trace data * * @param buf A pointer to buffer to store received data * @param size A pointer to buffer size; must be filled with * the actual amount of bytes written * * @returns ERROR_OK on success, an error code on failure. */ int (*poll_trace)(uint8_t *buf, size_t *size); /** Low-level JTAG APIs */ struct jtag_interface *jtag_ops; /** Low-level SWD APIs */ const struct swd_driver *swd_ops; /* DAP APIs over JTAG transport */ const struct dap_ops *dap_jtag_ops; /* DAP APIs over SWD transport */ const struct dap_ops *dap_swd_ops; }; extern const char * const jtag_only[]; int adapter_resets(int assert_trst, int assert_srst); int adapter_assert_reset(void); int adapter_deassert_reset(void); int adapter_config_trace(bool enabled, enum tpiu_pin_protocol pin_protocol, uint32_t port_size, unsigned int *trace_freq, unsigned int traceclkin_freq, uint16_t *prescaler); int adapter_poll_trace(uint8_t *buf, size_t *size); #endif /* OPENOCD_JTAG_INTERFACE_H */