diff options
Diffstat (limited to 'src/jtag/drivers/dummy.c')
-rw-r--r-- | src/jtag/drivers/dummy.c | 177 |
1 files changed, 177 insertions, 0 deletions
diff --git a/src/jtag/drivers/dummy.c b/src/jtag/drivers/dummy.c new file mode 100644 index 00000000..c2beb092 --- /dev/null +++ b/src/jtag/drivers/dummy.c @@ -0,0 +1,177 @@ +/*************************************************************************** + * Copyright (C) 2008 by Øyvind Harboe * + * oyvind.harboe@zylin.com * + * * + * This program is free software; you can redistribute it and/or modify * + * it under the terms of the GNU General Public License as published by * + * the Free Software Foundation; either version 2 of the License, or * + * (at your option) any later version. * + * * + * This program is distributed in the hope that it will be useful, * + * but WITHOUT ANY WARRANTY; without even the implied warranty of * + * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * + * GNU General Public License for more details. * + * * + * You should have received a copy of the GNU General Public License * + * along with this program; if not, write to the * + * Free Software Foundation, Inc., * + * 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. * + ***************************************************************************/ +#ifdef HAVE_CONFIG_H +#include "config.h" +#endif + +#include "interface.h" +#include "bitbang.h" +#include "../hello.h" + + +/* my private tap controller state, which tracks state for calling code */ +static tap_state_t dummy_state = TAP_RESET; + +static int dummy_clock; /* edge detector */ + +static int clock_count; /* count clocks in any stable state, only stable states */ + +static uint32_t dummy_data; + + +static int dummy_read(void) +{ + int data = 1 & dummy_data; + dummy_data = (dummy_data >> 1) | (1 << 31); + return data; +} + + +static void dummy_write(int tck, int tms, int tdi) +{ + /* TAP standard: "state transitions occur on rising edge of clock" */ + if (tck != dummy_clock) + { + if (tck) + { + tap_state_t old_state = dummy_state; + dummy_state = tap_state_transition(old_state, tms); + + if (old_state != dummy_state) + { + if (clock_count) + { + LOG_DEBUG("dummy_tap: %d stable clocks", clock_count); + clock_count = 0; + } + + LOG_DEBUG("dummy_tap: %s", tap_state_name(dummy_state)); + +#if defined(DEBUG) + if (dummy_state == TAP_DRCAPTURE) + dummy_data = 0x01255043; +#endif + } + else + { + /* this is a stable state clock edge, no change of state here, + * simply increment clock_count for subsequent logging + */ + ++clock_count; + } + } + dummy_clock = tck; + } +} + +static void dummy_reset(int trst, int srst) +{ + dummy_clock = 0; + + if (trst || (srst && (jtag_get_reset_config() & RESET_SRST_PULLS_TRST))) + dummy_state = TAP_RESET; + + LOG_DEBUG("reset to: %s", tap_state_name(dummy_state)); +} + +static void dummy_led(int on) +{ +} + +static struct bitbang_interface dummy_bitbang = { + .read = &dummy_read, + .write = &dummy_write, + .reset = &dummy_reset, + .blink = &dummy_led, + }; + + +static int dummy_khz(int khz, int *jtag_speed) +{ + if (khz == 0) + { + *jtag_speed = 0; + } + else + { + *jtag_speed = 64000/khz; + } + return ERROR_OK; +} + +static int dummy_speed_div(int speed, int *khz) +{ + if (speed == 0) + { + *khz = 0; + } + else + { + *khz = 64000/speed; + } + + return ERROR_OK; +} + +static int dummy_speed(int speed) +{ + return ERROR_OK; +} + +static int dummy_init(void) +{ + bitbang_interface = &dummy_bitbang; + + return ERROR_OK; +} + +static int dummy_quit(void) +{ + return ERROR_OK; +} + +static const struct command_registration dummy_command_handlers[] = { + { + .name = "dummy", + .mode = COMMAND_ANY, + .help = "dummy interface driver commands", + + .chain = hello_command_handlers, + }, + COMMAND_REGISTRATION_DONE, +}; + +/* The dummy driver is used to easily check the code path + * where the target is unresponsive. + */ +struct jtag_interface dummy_interface = { + .name = "dummy", + + .commands = dummy_command_handlers, + + .execute_queue = &bitbang_execute_queue, + + .speed = &dummy_speed, + .khz = &dummy_khz, + .speed_div = &dummy_speed_div, + + .init = &dummy_init, + .quit = &dummy_quit, + }; |