This is an automated email from Gerrit.

Ricardo Ribalda Delgado ([email protected]) just uploaded a new patch 
set to Gerrit, which you can find at http://openocd.zylin.com/3609

-- gerrit

commit 77ed258940446d1e3b061deb57c2a211f86426f4
Author: Vianney le Clément de Saint-Marcq <[email protected]>
Date:   Tue Jun 2 16:55:42 2015 +0200

    jtag/drivers/openjtag: Add support for Cypress CY7C65215
    
    The Cypress CY7C65215 Dual Channel USB-Serial Bridge Controller [1]
    understands the OpenJTAG protocol over a proprietary USB interface.
    
    This patch adds support for the CY7C65215 to the openjtag interface
    driver.  A new configuration option, `openjtag_variant`, allows to
    select the transport to use.
    
    Libusb (1.x or 0.1) is now a hard dependency of the openjtag driver.
    This should not be a big issue as libftdi also depends on it.
    
    [1] http://www.cypress.com/?rID=82870
    
    Change-Id: If39d5a15b43984f03d4395665c08f9bd610e8fcb
    Signed-off-by: Vianney le Clément de Saint-Marcq 
<[email protected]>
    Signed-off-by: Ricardo Ribalda Delgado <[email protected]>

diff --git a/configure.ac b/configure.ac
index fb5514e..31b1bfd 100644
--- a/configure.ac
+++ b/configure.ac
@@ -1183,6 +1183,14 @@ PROCESS_ADAPTERS([USB_ADAPTERS], [$use_libusb1 = yes -o 
$use_libusb0 = yes], [li
 PROCESS_ADAPTERS([USB0_ADAPTERS], [$use_libusb0 = yes], [libusb-0.1])
 PROCESS_ADAPTERS([HIDAPI_ADAPTERS], [$use_hidapi = yes], [hidapi])
 
+if test $build_openjtag_ftd2xx = yes -o $build_openjtag_ftdi = yes; then
+       if test $use_libusb1 != yes -a $use_libusb0 != yes; then
+               AC_MSG_ERROR([libusb-1.x or libusb-0.1 is required for the 
OpenJTAG Programmer])
+               build_openjtag_ftd2xx=no
+               build_openjtag_ftdi=no
+       fi
+fi
+
 if test $enable_stlink != no -o $enable_ti_icdi != no; then
        AC_DEFINE([BUILD_HLADAPTER], [1], [1 if you want the High Level JTAG 
driver.])
 else
diff --git a/doc/openocd.texi b/doc/openocd.texi
index 983ce3c..8a66fcd 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -3002,6 +3002,27 @@ pinout.
 
 @end deffn
 
+@deffn {Interface Driver} {openjtag}
+OpenJTAG compatible USB adapter.
+This defines some driver-specific commands:
+
+@deffn {Config Command} {openjtag_variant} variant
+Specifies the variant of the OpenJTAG adapter (see 
@uref{http://www.openjtag.org/}).
+Currently valid @var{variant} values include:
+
+@itemize @minus
+@item @b{standard} Standard variant (default).
+@item @b{cy7c65215} Cypress CY7C65215 Dual Channel USB-Serial Bridge Controller
+(see @uref{http://www.cypress.com/?rID=82870}).
+@end itemize
+@end deffn
+
+@deffn {Config Command} {openjtag_device_desc} string
+The USB device description string of the adapter.
+This value is only used with the standard variant.
+@end deffn
+@end deffn
+
 @section Transport Configuration
 @cindex Transport
 As noted earlier, depending on the version of OpenOCD you use,
diff --git a/src/jtag/drivers/openjtag.c b/src/jtag/drivers/openjtag.c
index 157020e..b007acd 100644
--- a/src/jtag/drivers/openjtag.c
+++ b/src/jtag/drivers/openjtag.c
@@ -2,6 +2,10 @@
  *   Driver for OpenJTAG Project (www.openjtag.org)                            
*
  *   Compatible with libftdi and ftd2xx drivers.                               
*
  *                                                                             
*
+ *   Cypress CY7C65215 support                                                 
*
+ *   Copyright (C) 2015 Vianney le Clément de Saint-Marcq, Essensium NV       
 *
+ *                      <[email protected]>                      
*
+ *                                                                             
*
  *   Copyright (C) 2010 by Ivan Meleca <[email protected]>                      
*
  *                                                                             
*
  *   Copyright (C) 2013 by Ryan Corbin, GlueLogix Inc. <[email protected]> 
*
@@ -41,7 +45,18 @@
 
 #include <jtag/interface.h>
 #include <jtag/commands.h>
-#include "usb_common.h"
+#include "libusb_common.h"
+
+static enum {
+       OPENJTAG_VARIANT_STANDARD,
+       OPENJTAG_VARIANT_CY7C65215,
+} openjtag_variant = OPENJTAG_VARIANT_STANDARD;
+
+static const char * const openjtag_variant_names[] = {
+       "standard",
+       "cy7c65215",
+       NULL
+};
 
 /*
  * OpenJTAG-OpenOCD state conversion
@@ -112,10 +127,24 @@ static uint8_t usb_rx_buf[OPENJTAG_BUFFER_SIZE];
 static struct openjtag_scan_result 
openjtag_scan_result_buffer[OPENJTAG_MAX_PENDING_RESULTS];
 static int openjtag_scan_result_count;
 
-/* Openocd usb handler */
-struct openocd {
-       struct usb_dev_handle *usb_handle;
-};
+static jtag_libusb_device_handle *usbh;
+
+/* CY7C65215 model only */
+#define CY7C65215_JTAG_REQUEST  0x40  /* bmRequestType: vendor host-to-device 
*/
+#define CY7C65215_JTAG_ENABLE   0xD0  /* bRequest: enable JTAG */
+#define CY7C65215_JTAG_DISABLE  0xD1  /* bRequest: disable JTAG */
+#define CY7C65215_JTAG_READ     0xD2  /* bRequest: read buffer */
+#define CY7C65215_JTAG_WRITE    0xD3  /* bRequest: write buffer */
+
+#define CY7C65215_USB_TIMEOUT   100
+
+static const uint16_t cy7c65215_vids[] = {0x04b4, 0};
+static const uint16_t cy7c65215_pids[] = {0x0007, 0};
+
+#define CY7C65215_JTAG_CLASS     0xff
+#define CY7C65215_JTAG_SUBCLASS  0x04
+
+static unsigned int ep_in, ep_out;
 
 #ifdef _DEBUG_USB_COMMS_
 
@@ -201,7 +230,7 @@ static int8_t openjtag_get_tap_state(int8_t state)
        }
 }
 
-static int openjtag_buf_write(
+static int openjtag_buf_write_standard(
        uint8_t *buf, int size, uint32_t *bytes_written)
 {
 #if BUILD_OPENJTAG_FTD2XX == 1
@@ -239,7 +268,52 @@ static int openjtag_buf_write(
 #endif
 }
 
-static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+static int openjtag_buf_write_cy7c65215(
+       uint8_t *buf, int size, uint32_t *bytes_written)
+{
+       int ret;
+
+#ifdef _DEBUG_USB_COMMS_
+       openjtag_debug_buffer(buf, size, DEBUG_TYPE_WRITE);
+#endif
+
+       if (size == 0) {
+               *bytes_written = 0;
+               return ERROR_OK;
+       }
+
+       ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
+                                                                          
CY7C65215_JTAG_WRITE, size, 0,
+                                                                          
NULL, 0, CY7C65215_USB_TIMEOUT);
+       if (ret < 0) {
+               LOG_ERROR("vendor command failed, error %d", ret);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       ret = jtag_libusb_bulk_write(usbh, ep_out, (char *)buf, size,
+                                                                
CY7C65215_USB_TIMEOUT);
+       if (ret < 0) {
+               LOG_ERROR("bulk write failed, error %d", ret);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+       *bytes_written = ret;
+
+       return ERROR_OK;
+}
+
+static int openjtag_buf_write(
+       uint8_t *buf, int size, uint32_t *bytes_written)
+{
+       switch (openjtag_variant) {
+       case OPENJTAG_VARIANT_CY7C65215:
+               return openjtag_buf_write_cy7c65215(buf, size, bytes_written);
+       default:
+               return openjtag_buf_write_standard(buf, size, bytes_written);
+       }
+}
+
+static int openjtag_buf_read_standard(
+       uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
 {
 
 #if BUILD_OPENJTAG_FTD2XX == 1
@@ -291,6 +365,50 @@ static int openjtag_buf_read(uint8_t *buf, uint32_t qty, 
uint32_t *bytes_read)
        return ERROR_OK;
 }
 
+static int openjtag_buf_read_cy7c65215(
+       uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+{
+       int ret;
+
+       if (qty == 0) {
+               *bytes_read = 0;
+               goto out;
+       }
+
+       ret = jtag_libusb_control_transfer(usbh, CY7C65215_JTAG_REQUEST,
+                                                                          
CY7C65215_JTAG_READ, qty, 0,
+                                                                          
NULL, 0, CY7C65215_USB_TIMEOUT);
+       if (ret < 0) {
+               LOG_ERROR("vendor command failed, error %d", ret);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+
+       ret = jtag_libusb_bulk_read(usbh, ep_in, (char *)buf, qty,
+                                                               
CY7C65215_USB_TIMEOUT);
+       if (ret < 0) {
+               LOG_ERROR("bulk read failed, error %d", ret);
+               return ERROR_JTAG_DEVICE_ERROR;
+       }
+       *bytes_read = ret;
+
+out:
+#ifdef _DEBUG_USB_COMMS_
+       openjtag_debug_buffer(buf, *bytes_read, DEBUG_TYPE_READ);
+#endif
+
+       return ERROR_OK;
+}
+
+static int openjtag_buf_read(uint8_t *buf, uint32_t qty, uint32_t *bytes_read)
+{
+       switch (openjtag_variant) {
+       case OPENJTAG_VARIANT_CY7C65215:
+               return openjtag_buf_read_cy7c65215(buf, qty, bytes_read);
+       default:
+               return openjtag_buf_read_standard(buf, qty, bytes_read);
+       }
+}
+
 static int openjtag_sendcommand(uint8_t cmd)
 {
        uint32_t written;
@@ -335,7 +453,7 @@ static int openjtag_speed(int speed)
        return ERROR_OK;
 }
 
-static int openjtag_init(void)
+static int openjtag_init_standard(void)
 {
        uint8_t latency_timer;
 
@@ -343,10 +461,6 @@ static int openjtag_init(void)
        FT_STATUS status;
 #endif
 
-usb_tx_buf_offs = 0;
-usb_rx_buf_len = 0;
-openjtag_scan_result_count = 0;
-
 #if BUILD_OPENJTAG_FTD2XX == 1
        LOG_DEBUG("'openjtag' interface using FTD2XX");
 #elif BUILD_OPENJTAG_LIBFTDI == 1
@@ -483,16 +597,70 @@ if (openjtag_device_desc == NULL) {
        }
 #endif
 
-       /* OpenJTAG speed */
-       openjtag_sendcommand(0xE0); /*Start at slowest adapter speed*/
+       return ERROR_OK;
+}
 
-       /* MSB */
-       openjtag_sendcommand(0x75);
+static int openjtag_init_cy7c65215(void)
+{
+       int ret;
+
+       usbh = NULL;
+       ret = jtag_libusb_open(cy7c65215_vids, cy7c65215_pids, NULL, &usbh);
+       if (ret != ERROR_OK) {
+               LOG_ERROR("unable to open cy7c65215 device");
+               goto err;
+       }
+
+       ret = jtag_libusb_choose_interface(usbh, &ep_in, &ep_out,
+                                                                          
CY7C65215_JTAG_CLASS,
+                                                                          
CY7C65215_JTAG_SUBCLASS, -1);
+       if (ret != ERROR_OK) {
+               LOG_ERROR("unable to claim JTAG interface");
+               goto err;
+       }
+
+       ret = jtag_libusb_control_transfer(usbh,
+                                                                          
CY7C65215_JTAG_REQUEST,
+                                                                          
CY7C65215_JTAG_ENABLE,
+                                                                          0, 
0, NULL, 0, CY7C65215_USB_TIMEOUT);
+       if (ret < 0) {
+               LOG_ERROR("could not enable JTAG module");
+               goto err;
+       }
 
        return ERROR_OK;
+
+err:
+       if (usbh != NULL)
+               jtag_libusb_close(usbh);
+       return ERROR_JTAG_INIT_FAILED;
 }
 
-static int openjtag_quit(void)
+static int openjtag_init(void)
+{
+       int ret;
+
+       usb_tx_buf_offs = 0;
+       usb_rx_buf_len = 0;
+       openjtag_scan_result_count = 0;
+
+       switch (openjtag_variant) {
+       case OPENJTAG_VARIANT_CY7C65215:
+               ret = openjtag_init_cy7c65215();
+               break;
+       default:
+               ret = openjtag_init_standard();
+       }
+       if (ret != ERROR_OK)
+               return ret;
+
+       openjtag_speed(375); /* Start at slowest adapter speed */
+       openjtag_sendcommand(0x75); /* MSB */
+
+       return ERROR_OK;
+}
+
+static int openjtag_quit_standard(void)
 {
 #if BUILD_OPENJTAG_FTD2XX == 1
        FT_Close(ftdih);
@@ -504,6 +672,32 @@ static int openjtag_quit(void)
        return ERROR_OK;
 }
 
+static int openjtag_quit_cy7c65215(void)
+{
+       int ret;
+
+       ret = jtag_libusb_control_transfer(usbh,
+                                                                          
CY7C65215_JTAG_REQUEST,
+                                                                          
CY7C65215_JTAG_DISABLE,
+                                                                          0, 
0, NULL, 0, CY7C65215_USB_TIMEOUT);
+       if (ret < 0)
+               LOG_WARNING("could not disable JTAG module");
+
+       jtag_libusb_close(usbh);
+
+       return ERROR_OK;
+}
+
+static int openjtag_quit(void)
+{
+       switch (openjtag_variant) {
+       case OPENJTAG_VARIANT_CY7C65215:
+               return openjtag_quit_cy7c65215();
+       default:
+               return openjtag_quit_standard();
+       }
+}
+
 static void openjtag_write_tap_buffer(void)
 {
        uint32_t written;
@@ -536,8 +730,8 @@ static int openjtag_execute_tap_queue(void)
 
                        uint8_t *buffer = 
openjtag_scan_result_buffer[res_count].buffer;
 
-                       while (len) {
-                               if (len <= 8) {
+                       while (len > 0) {
+                               if (len <= 8 && openjtag_variant != 
OPENJTAG_VARIANT_CY7C65215) {
                                        DEBUG_JTAG_IO("bits < 8 buf = 0x%X, 
will be 0x%X",
                                                usb_rx_buf[rx_offs], 
usb_rx_buf[rx_offs] >> (8 - len));
                                        buffer[count] = usb_rx_buf[rx_offs] >> 
(8 - len);
@@ -724,11 +918,14 @@ static void openjtag_execute_runtest(struct jtag_command 
*cmd)
        if (cmd->cmd.runtest->num_cycles > 16)
                LOG_WARNING("num_cycles > 16 on run test");
 
-       uint8_t command;
-       command = 7;
-       command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
+       if (openjtag_variant != OPENJTAG_VARIANT_CY7C65215 ||
+               cmd->cmd.runtest->num_cycles) {
+               uint8_t command;
+               command = 7;
+               command |= ((cmd->cmd.runtest->num_cycles - 1) & 0x0F) << 4;
 
-       openjtag_add_byte(command);
+               openjtag_add_byte(command);
+       }
 
        tap_set_end_state(end_state);
        if (tap_get_end_state() != tap_get_state()) {
@@ -816,6 +1013,24 @@ COMMAND_HANDLER(openjtag_handle_device_desc_command)
        return ERROR_OK;
 }
 
+COMMAND_HANDLER(openjtag_handle_variant_command)
+{
+       if (CMD_ARGC == 1) {
+               const char * const *name = openjtag_variant_names;
+               int variant = 0;
+               for (; *name; name++, variant++) {
+                       if (strcasecmp(CMD_ARGV[0], *name) == 0) {
+                               openjtag_variant = variant;
+                               return ERROR_OK;
+                       }
+               }
+               LOG_ERROR("unknown openjtag variant '%s'", CMD_ARGV[0]);
+       } else {
+               LOG_ERROR("require exactly one argument to "
+                                 "openjtag_variant <variant>");
+       }
+       return ERROR_OK;
+}
 
 static const struct command_registration openjtag_command_handlers[] = {
        {
@@ -825,6 +1040,13 @@ static const struct command_registration 
openjtag_command_handlers[] = {
                .help = "set the USB device description of the OpenJTAG",
                .usage = "description-string",
        },
+       {
+               .name = "openjtag_variant",
+               .handler = openjtag_handle_variant_command,
+               .mode = COMMAND_CONFIG,
+               .help = "set the OpenJTAG variant",
+               .usage = "variant-string",
+       },
        COMMAND_REGISTRATION_DONE
 };
 

-- 

------------------------------------------------------------------------------
_______________________________________________
OpenOCD-devel mailing list
[email protected]
https://lists.sourceforge.net/lists/listinfo/openocd-devel

Reply via email to