command_context_t -> struct command_context
[fw/openocd] / src / jtag / dummy.c
index bfdf0dcccfe37c757b8248f85d5c0ad19f96fb68..324ea7e94409de98d1fc30b1eb3e00d967e24180 100644 (file)
-/***************************************************************************\r
- *   Copyright (C) 2008 by Øyvind Harboe                                   *\r
- *   oyvind.harboe@zylin.com                                               *\r
- *                                                                         *\r
- *   This program is free software; you can redistribute it and/or modify  *\r
- *   it under the terms of the GNU General Public License as published by  *\r
- *   the Free Software Foundation; either version 2 of the License, or     *\r
- *   (at your option) any later version.                                   *\r
- *                                                                         *\r
- *   This program is distributed in the hope that it will be useful,       *\r
- *   but WITHOUT ANY WARRANTY; without even the implied warranty of        *\r
- *   MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the         *\r
- *   GNU General Public License for more details.                          *\r
- *                                                                         *\r
- *   You should have received a copy of the GNU General Public License     *\r
- *   along with this program; if not, write to the                         *\r
- *   Free Software Foundation, Inc.,                                       *\r
- *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *\r
- ***************************************************************************/\r
-#ifdef HAVE_CONFIG_H\r
-#include "config.h"\r
-#endif\r
-\r
-#include "replacements.h"\r
-\r
-#include "jtag.h"\r
-#include "bitbang.h"\r
-\r
-\r
-/* my private tap controller state, which tracks state for calling code */\r
-static tap_state_t dummy_state = TAP_RESET;\r
-\r
-static int dummy_clock;         /* edge detector */\r
-\r
-static tap_state_t tap_state_transition(tap_state_t cur_state, int tms);\r
-\r
-\r
-int dummy_speed(int speed);\r
-int dummy_register_commands(struct command_context_s *cmd_ctx);\r
-int dummy_init(void);\r
-int dummy_quit(void);\r
-static int dummy_khz(int khz, int *jtag_speed);\r
-static int dummy_speed_div(int speed, int *khz);\r
-\r
-\r
-/* The dummy driver is used to easily check the code path\r
- * where the target is unresponsive.\r
- */\r
-jtag_interface_t dummy_interface =\r
-{\r
-       .name = "dummy",\r
-\r
-       .execute_queue = bitbang_execute_queue,\r
-\r
-       .speed = dummy_speed,\r
-       .register_commands = dummy_register_commands,\r
-       .khz = dummy_khz,\r
-       .speed_div = dummy_speed_div,\r
-\r
-       .init = dummy_init,\r
-       .quit = dummy_quit,\r
-};\r
-\r
-int dummy_read(void);\r
-void dummy_write(int tck, int tms, int tdi);\r
-void dummy_reset(int trst, int srst);\r
-void dummy_led(int on);\r
-\r
-bitbang_interface_t dummy_bitbang =\r
-{\r
-       .read = dummy_read,\r
-       .write = dummy_write,\r
-       .reset = dummy_reset,\r
-       .blink = dummy_led\r
-};\r
-\r
-int dummy_read(void)\r
-{\r
-       return 1;\r
-}\r
-\r
-\r
-void dummy_write(int tck, int tms, int tdi)\r
-{\r
-       /* TAP standard: "state transitions occur on rising edge of clock" */\r
-       if( tck != dummy_clock )\r
-       {\r
-               if( tck )\r
-               {\r
-                       int old_state = dummy_state;\r
-                       dummy_state = tap_state_transition( dummy_state, tms );\r
-                       if( old_state != dummy_state )\r
-                               LOG_DEBUG( "dummy_tap=%s", jtag_state_name(dummy_state) );\r
-               }\r
-               dummy_clock = tck;\r
-       }\r
-}\r
-\r
-void dummy_reset(int trst, int srst)\r
-{\r
-       dummy_clock = 0;\r
-       dummy_state = TAP_RESET;\r
-       LOG_DEBUG( "reset to %s", jtag_state_name(dummy_state) );\r
-}\r
-\r
-static int dummy_khz(int khz, int *jtag_speed)\r
-{\r
-       if (khz==0)\r
-       {\r
-               *jtag_speed=0;\r
-       }\r
-       else\r
-       {\r
-               *jtag_speed=64000/khz;\r
-       }\r
-       return ERROR_OK;\r
-}\r
-\r
-static int dummy_speed_div(int speed, int *khz)\r
-{\r
-       if (speed==0)\r
-       {\r
-               *khz = 0;\r
-       }\r
-       else\r
-       {\r
-               *khz=64000/speed;\r
-       }\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int dummy_speed(int speed)\r
-{\r
-       return ERROR_OK;\r
-}\r
-\r
-int dummy_register_commands(struct command_context_s *cmd_ctx)\r
-{\r
-       return ERROR_OK;\r
-}\r
-\r
-int dummy_init(void)\r
-{\r
-       bitbang_interface = &dummy_bitbang;\r
-\r
-       return ERROR_OK;\r
-}\r
-\r
-int dummy_quit(void)\r
-{\r
-       return ERROR_OK;\r
-}\r
-\r
-void dummy_led(int on)\r
-{\r
-}\r
-\r
-\r
-/**\r
- * Function tap_state_transition\r
- * takes a current TAP state and returns the next state according to the tms value.\r
- *\r
- * Even though there is code to duplicate this elsewhere, we do it here a little\r
- * differently just to get a second opinion, i.e. a verification, on state tracking\r
- * in that other logic. Plus array lookups without index checking are no favorite thing.\r
- * This is educational for developers new to TAP controllers.\r
- */\r
-static tap_state_t tap_state_transition(tap_state_t cur_state, int tms)\r
-{\r
-       tap_state_t new_state;\r
-\r
-       if (tms)\r
-       {\r
-               switch (cur_state)\r
-               {\r
-               case TAP_RESET:\r
-                       new_state = cur_state;\r
-                       break;\r
-               case TAP_IDLE:\r
-               case TAP_DRUPDATE:\r
-               case TAP_IRUPDATE:\r
-                       new_state = TAP_DRSELECT;\r
-                       break;\r
-               case TAP_DRSELECT:\r
-                       new_state = TAP_IRSELECT;\r
-                       break;\r
-               case TAP_DRCAPTURE:\r
-               case TAP_DRSHIFT:\r
-                       new_state = TAP_DREXIT1;\r
-                       break;\r
-               case TAP_DREXIT1:\r
-               case TAP_DREXIT2:\r
-                       new_state = TAP_DRUPDATE;\r
-                       break;\r
-               case TAP_DRPAUSE:\r
-                       new_state = TAP_DREXIT2;\r
-                       break;\r
-               case TAP_IRSELECT:\r
-                       new_state = TAP_RESET;\r
-                       break;\r
-               case TAP_IRCAPTURE:\r
-               case TAP_IRSHIFT:\r
-                       new_state = TAP_IREXIT1;\r
-                       break;\r
-               case TAP_IREXIT1:\r
-               case TAP_IREXIT2:\r
-                       new_state = TAP_IRUPDATE;\r
-                       break;\r
-               case TAP_IRPAUSE:\r
-                       new_state = TAP_IREXIT2;\r
-                       break;\r
-               default:\r
-                       LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );\r
-                       exit(1);\r
-                       break;\r
-               }\r
-       }\r
-       else\r
-       {\r
-               switch (cur_state)\r
-               {\r
-               case TAP_RESET:\r
-               case TAP_IDLE:\r
-               case TAP_DRUPDATE:\r
-               case TAP_IRUPDATE:\r
-                       new_state = TAP_IDLE;\r
-                       break;\r
-               case TAP_DRSELECT:\r
-                       new_state = TAP_DRCAPTURE;\r
-                       break;\r
-               case TAP_DRCAPTURE:\r
-               case TAP_DRSHIFT:\r
-               case TAP_DREXIT2:\r
-                       new_state = TAP_DRSHIFT;\r
-                       break;\r
-               case TAP_DREXIT1:\r
-               case TAP_DRPAUSE:\r
-                       new_state = TAP_DRPAUSE;\r
-                       break;\r
-               case TAP_IRSELECT:\r
-                       new_state = TAP_IRCAPTURE;\r
-                       break;\r
-               case TAP_IRCAPTURE:\r
-               case TAP_IRSHIFT:\r
-               case TAP_IREXIT2:\r
-                       new_state = TAP_IRSHIFT;\r
-                       break;\r
-               case TAP_IREXIT1:\r
-               case TAP_IRPAUSE:\r
-                       new_state = TAP_IRPAUSE;\r
-                       break;\r
-               default:\r
-                       LOG_ERROR( "fatal: invalid argument cur_state=%d", cur_state );\r
-                       exit(1);\r
-                       break;\r
-               }\r
-       }\r
-\r
-       return new_state;\r
-}\r
+/***************************************************************************
+ *   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"
+
+
+/* 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_speed(int speed);
+static int dummy_register_commands(struct command_context *cmd_ctx);
+static int dummy_init(void);
+static int dummy_quit(void);
+static int dummy_khz(int khz, int *jtag_speed);
+static int dummy_speed_div(int speed, int *khz);
+
+
+/* The dummy driver is used to easily check the code path
+ * where the target is unresponsive.
+ */
+struct jtag_interface dummy_interface =
+{
+       .name = "dummy",
+
+       .execute_queue = bitbang_execute_queue,
+
+       .speed = dummy_speed,
+       .register_commands = dummy_register_commands,
+       .khz = dummy_khz,
+       .speed_div = dummy_speed_div,
+
+       .init = dummy_init,
+       .quit = dummy_quit,
+};
+
+static int dummy_read(void);
+static void dummy_write(int tck, int tms, int tdi);
+static void dummy_reset(int trst, int srst);
+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_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 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_register_commands(struct command_context *cmd_ctx)
+{
+       return ERROR_OK;
+}
+
+static int dummy_init(void)
+{
+       bitbang_interface = &dummy_bitbang;
+
+       return ERROR_OK;
+}
+
+static int dummy_quit(void)
+{
+       return ERROR_OK;
+}
+
+static void dummy_led(int on)
+{
+}
+