]> git.sur5r.net Git - openocd/blobdiff - src/jtag/zy1000/zy1000.c
ZY1000 help/usage fixups
[openocd] / src / jtag / zy1000 / zy1000.c
index 28515c77bee1010bff32d90650087328f6b11f4a..e66a8b5a31ba6904ef864b917f72079ea74f9764 100644 (file)
@@ -1,5 +1,5 @@
 /***************************************************************************
- *   Copyright (C) 2007-2008 by Øyvind Harboe                              *
+ *   Copyright (C) 2007-2009 by Øyvind Harboe                              *
  *                                                                         *
  *   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  *
  *   Free Software Foundation, Inc.,                                       *
  *   59 Temple Place - Suite 330, Boston, MA  02111-1307, USA.             *
  ***************************************************************************/
+
+/* This file supports the zy1000 debugger: http://www.zylin.com/zy1000.html
+ *
+ * The zy1000 is a standalone debugger that has a web interface and
+ * requires no drivers on the developer host as all communication
+ * is via TCP/IP. The zy1000 gets it performance(~400-700kBytes/s
+ * DCC downloads @ 16MHz target) as it has an FPGA to hardware
+ * accelerate the JTAG commands, while offering *very* low latency
+ * between OpenOCD and the FPGA registers.
+ *
+ * The disadvantage of the zy1000 is that it has a feeble CPU compared to
+ * a PC(ca. 50-500 DMIPS depending on how one counts it), whereas a PC
+ * is on the order of 10000 DMIPS(i.e. at a factor of 20-200).
+ *
+ * The zy1000 revc hardware is using an Altera Nios CPU, whereas the
+ * revb is using ARM7 + Xilinx.
+ *
+ * See Zylin web pages or contact Zylin for more information.
+ *
+ * The reason this code is in OpenOCD rather than OpenOCD linked with the
+ * ZY1000 code is that OpenOCD is the long road towards getting
+ * libopenocd into place. libopenocd will support both low performance,
+ * low latency systems(embedded) and high performance high latency
+ * systems(PCs).
+ */
 #ifdef HAVE_CONFIG_H
 #include "config.h"
 #endif
 
-#include "embeddedice.h"
-#include "minidriver.h"
-#include "interface.h"
+#include <target/embeddedice.h>
+#include <jtag/minidriver.h>
+#include <jtag/interface.h>
 #include "zy1000_version.h"
 
 #include <cyg/hal/hal_io.h>             // low level i/o
 
 #include <time.h>
 
+#ifdef CYGPKG_HAL_NIOS2
+#include <cyg/hal/io.h>
+#include <cyg/firmwareutil/firmwareutil.h>
+#endif
+
 #define ZYLIN_VERSION GIT_ZY1000_VERSION
 #define ZYLIN_DATE __DATE__
 #define ZYLIN_TIME __TIME__
 #define ZYLIN_OPENOCD GIT_OPENOCD_VERSION
 #define ZYLIN_OPENOCD_VERSION "ZY1000 " ZYLIN_VERSION " " ZYLIN_DATE
 
-/* low level command set
- */
-void zy1000_reset(int trst, int srst);
-
-
-int zy1000_speed(int speed);
-int zy1000_register_commands(struct command_context *cmd_ctx);
-int zy1000_init(void);
-int zy1000_quit(void);
 
 static int zy1000_khz(int khz, int *jtag_speed)
 {
@@ -77,8 +98,8 @@ static bool readPowerDropout(void)
 {
        cyg_uint32 state;
        // sample and clear power dropout
-       HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x80);
-       HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state);
+       ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x80);
+       ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
        bool powerDropout;
        powerDropout = (state & 0x80) != 0;
        return powerDropout;
@@ -89,8 +110,8 @@ static bool readSRST(void)
 {
        cyg_uint32 state;
        // sample and clear SRST sensing
-       HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x00000040);
-       HAL_READ_UINT32(ZY1000_JTAG_BASE + 0x10, state);
+       ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x00000040);
+       ZY1000_PEEK(ZY1000_JTAG_BASE + 0x10, state);
        bool srstAsserted;
        srstAsserted = (state & 0x40) != 0;
        return srstAsserted;
@@ -108,21 +129,6 @@ static int zy1000_power_dropout(int *dropout)
        return ERROR_OK;
 }
 
-
-struct jtag_interface zy1000_interface =
-{
-       .name = "ZY1000",
-       .execute_queue = NULL,
-       .speed = zy1000_speed,
-       .register_commands = zy1000_register_commands,
-       .init = zy1000_init,
-       .quit = zy1000_quit,
-       .khz = zy1000_khz,
-       .speed_div = zy1000_speed_div,
-       .power_dropout = zy1000_power_dropout,
-       .srst_asserted = zy1000_srst_asserted,
-};
-
 void zy1000_reset(int trst, int srst)
 {
        LOG_DEBUG("zy1000 trst=%d, srst=%d", trst, srst);
@@ -217,10 +223,10 @@ static void setPower(bool power)
        savePower = power;
        if (power)
        {
-               HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x14, 0x8);
+               ZY1000_POKE(ZY1000_JTAG_BASE + 0x14, 0x8);
        } else
        {
-               HAL_WRITE_UINT32(ZY1000_JTAG_BASE + 0x10, 0x8);
+               ZY1000_POKE(ZY1000_JTAG_BASE + 0x10, 0x8);
        }
 }
 
@@ -235,7 +241,7 @@ COMMAND_HANDLER(handle_power_command)
                // fall through
        }
        case 0:
-               command_print(cmd_ctx, "Target power %s", savePower ? "on" : "off");
+               LOG_INFO("Target power %s", savePower ? "on" : "off");
                break;
        default:
                return ERROR_INVALID_ARGUMENTS;
@@ -321,33 +327,57 @@ static int jim_zy1000_version(Jim_Interp *interp, int argc, Jim_Obj *const *argv
 
 
 #ifdef CYGPKG_HAL_NIOS2
+
+
+struct info_forward
+{
+       void *data;
+       struct cyg_upgrade_info *upgraded_file;
+};
+
+static void report_info(void *data, const char * format, va_list args)
+{
+       char *s = alloc_vprintf(format, args);
+       LOG_USER_N("%s", s);
+       free(s);
+}
+
+struct cyg_upgrade_info firmware_info =
+{
+               (cyg_uint8 *)0x84000000,
+               "/ram/firmware.phi",
+               "Firmware",
+               0x0300000,
+               0x1f00000 -
+               0x0300000,
+               "ZylinNiosFirmware\n",
+               report_info,
+};
+
 static int jim_zy1000_writefirmware(Jim_Interp *interp, int argc, Jim_Obj *const *argv)
 {
        if (argc != 2)
                return JIM_ERR;
 
        int length;
-       int stat;
        const char *str = Jim_GetString(argv[1], &length);
 
-       /* BUG!!!! skip header! */
-       void *firmware_address=0x4000000;
-       int firmware_length=0x100000;
-
-       if (length>firmware_length)
+       /* */
+       int tmpFile;
+       if ((tmpFile = open(firmware_info.file, O_RDWR | O_CREAT | O_TRUNC)) <= 0)
+       {
+               return JIM_ERR;
+       }
+       bool success;
+       success = write(tmpFile, str, length) == length;
+       close(tmpFile);
+       if (!success)
                return JIM_ERR;
 
-       void *err_addr;
-
-    if ((stat = flash_erase((void *)firmware_address, firmware_length, (void **)&err_addr)) != 0)
-    {
-       return JIM_ERR;
-    }
-
-    if ((stat = flash_program(firmware_address, str, length, (void **)&err_addr)) != 0)
-       return JIM_ERR;
+       if (!cyg_firmware_upgrade(NULL, firmware_info))
+               return JIM_ERR;
 
-    return JIM_OK;
+       return JIM_OK;
 }
 #endif
 
@@ -370,24 +400,6 @@ zylinjtag_Jim_Command_powerstatus(Jim_Interp *interp,
        return JIM_OK;
 }
 
-int zy1000_register_commands(struct command_context *cmd_ctx)
-{
-       register_command(cmd_ctx, NULL, "power", handle_power_command, COMMAND_ANY,
-                       "power <on/off> - turn power switch to target on/off. No arguments - print status.");
-
-       Jim_CreateCommand(interp, "zy1000_version", jim_zy1000_version, NULL, NULL);
-
-
-       Jim_CreateCommand(interp, "powerstatus", zylinjtag_Jim_Command_powerstatus, NULL, NULL);
-
-#ifdef CYGPKG_HAL_NIOS2
-       Jim_CreateCommand(interp, "updatezy1000firmware", jim_zy1000_writefirmware, NULL, NULL);
-#endif
-
-
-       return ERROR_OK;
-}
-
 
 
 
@@ -817,3 +829,53 @@ void embeddedice_write_dcc(struct jtag_tap *tap, int reg_addr, uint8_t *buffer,
 }
 
 
+static const struct command_registration zy1000_commands[] = {
+       {
+               .name = "power",
+               .handler = handle_power_command,
+               .mode = COMMAND_ANY,
+               .help = "Turn power switch to target on/off. "
+                       "With no arguments, prints status.",
+               .usage = "('on'|'off)",
+       },
+       {
+               .name = "zy1000_version",
+               .mode = COMMAND_ANY,
+               .jim_handler = jim_zy1000_version,
+               .help = "Print version info for zy1000.",
+               .usage = "['openocd'|'zy1000'|'date'|'time'|'pcb'|'fpga']",
+       },
+       {
+               .name = "powerstatus",
+               .mode = COMMAND_ANY,
+               .jim_handler = zylinjtag_Jim_Command_powerstatus,
+               .help = "Returns power status of target",
+       },
+#ifdef CYGPKG_HAL_NIOS2
+       {
+               .name = "updatezy1000firmware",
+               .mode = COMMAND_ANY,
+               .jim_handler = jim_zy1000_writefirmware,
+               .help = "writes firmware to flash",
+               /* .usage = "some_string", */
+       },
+#endif
+       COMMAND_REGISTRATION_DONE
+};
+
+
+
+struct jtag_interface zy1000_interface =
+{
+       .name = "ZY1000",
+       .execute_queue = NULL,
+       .speed = zy1000_speed,
+       .commands = zy1000_commands,
+       .init = zy1000_init,
+       .quit = zy1000_quit,
+       .khz = zy1000_khz,
+       .speed_div = zy1000_speed_div,
+       .power_dropout = zy1000_power_dropout,
+       .srst_asserted = zy1000_srst_asserted,
+};
+