This is an automated email from Gerrit.

"Daniel Anselmi <danse...@gmx.ch>" just uploaded a new patch set to Gerrit, 
which you can find at https://review.openocd.org/c/openocd/+/7565

-- gerrit

commit 310d77c191e0625a51ad713057cd62eed9875be5
Author: Daniel Anselmi <danse...@gmx.ch>
Date:   Fri Feb 24 15:57:30 2023 +0100

    pld: add support for cologne chip gatemate fpgas
    
    Change-Id: I0bf5a52ee6a7f0287524619114eba0cfccf6ac81
    Signed-off-by: Daniel Anselmi <danse...@gmx.ch>

diff --git a/doc/openocd.texi b/doc/openocd.texi
index 3407786dcb..1fce51bc01 100644
--- a/doc/openocd.texi
+++ b/doc/openocd.texi
@@ -8566,6 +8566,12 @@ The files @verb{|.fs|} and @verb{|.bin|} generated by 
Gowin FPGA Designer are su
 @end deffn
 
 
+@deffn {FPGA Driver} {gatemate}
+This driver can be used to load the bitstream into GateMate FPGAs form 
CologneChip.
+The files @verb{|.bit|} and @verb{|.cfg|} both generated by p_r tool from 
CologneChip are supported.
+@end deffn
+
+
 @node General Commands
 @chapter General Commands
 @cindex commands
diff --git a/src/pld/Makefile.am b/src/pld/Makefile.am
index 22ae9fd208..69e457c96a 100644
--- a/src/pld/Makefile.am
+++ b/src/pld/Makefile.am
@@ -6,6 +6,7 @@ noinst_LTLIBRARIES += %D%/libpld.la
        %D%/ecp2_3.c \
        %D%/ecp5.c \
        %D%/efinix.c \
+       %D%/gatemate.c \
        %D%/gowin.c \
        %D%/intel.c \
        %D%/lattice.c \
diff --git a/src/pld/gatemate.c b/src/pld/gatemate.c
new file mode 100644
index 0000000000..d585b9e6b6
--- /dev/null
+++ b/src/pld/gatemate.c
@@ -0,0 +1,256 @@
+// SPDX-License-Identifier: GPL-2.0-or-later
+
+/***************************************************************************
+ *   Copyright (C) 2022 by Daniel Anselmi                                  *
+ *   danse...@gmx.ch                                                       *
+ ***************************************************************************/
+
+#ifdef HAVE_CONFIG_H
+#include "config.h"
+#endif
+
+#include <jtag/jtag.h>
+#include <jtag/adapter.h>
+#include "pld.h"
+#include "raw_bit.h"
+
+#define JTAG_CONFIGURE  0x06
+
+//#define USER1 0x55
+//#define USER2
+
+
+struct gatemate_pld_device {
+       struct jtag_tap *tap;
+};
+
+struct gatemate_bit_file {
+       struct raw_bit_file raw_file;
+       size_t capacity;
+};
+
+static int gatemate_add_byte_to_bitfile(struct gatemate_bit_file *bit_file, 
uint8_t byte)
+{
+       const size_t chunk_size = 8192;
+       if (bit_file->raw_file.length + 1 > bit_file->capacity) {
+               uint8_t *buffer;
+               if (bit_file->raw_file.data)
+                       buffer = realloc(bit_file->raw_file.data, 
bit_file->capacity + chunk_size);
+               else
+                       buffer = malloc(chunk_size);
+               if (!buffer)
+                       return ERROR_FAIL;
+               bit_file->raw_file.data = buffer;
+               bit_file->capacity += chunk_size;
+       }
+
+       bit_file->raw_file.data[bit_file->raw_file.length++] = byte;
+
+       return ERROR_OK;
+}
+
+static int gatemate_read_cfg_line(struct gatemate_bit_file *bit_file,
+                                                       const char 
*line_buffer, size_t nread)
+{
+       for (size_t idx = 0; idx < nread; ++idx) {
+               if (line_buffer[idx] == ' ') {
+                       continue;
+               } else if (line_buffer[idx] == 0) {
+                       break;
+               } else if (idx + 1 < nread) {
+                       if (isxdigit(line_buffer[idx]) && 
isxdigit(line_buffer[idx + 1])) {
+                               uint8_t byte;
+                               unhexify(&byte, line_buffer + idx, 2);
+                               int retval = 
gatemate_add_byte_to_bitfile(bit_file, byte);
+                               if (retval != ERROR_OK)
+                                       return retval;
+                       } else if (line_buffer[idx] == '/' && line_buffer[idx + 
1] == '/') {
+                               break;
+                       }
+                       ++idx;
+               } else {
+                       LOG_ERROR("parsing failed");
+                       return ERROR_FAIL;
+               }
+       }
+       return ERROR_OK;
+}
+
+static int gatemate_getline(char **buffer, size_t *buf_size, FILE *input_file)
+{
+       const size_t chunk_size = 32;
+       if (!*buffer)
+               *buf_size = 0;
+
+       size_t read = 0;
+       do {
+               if (read + 1 > *buf_size) {
+                       char *new_buffer;
+                       if (*buffer)
+                               new_buffer = realloc(*buffer, *buf_size + 
chunk_size);
+                       else
+                               new_buffer = malloc(chunk_size);
+                       if (!new_buffer)
+                               return -1;
+                       *buffer = new_buffer;
+                       *buf_size += chunk_size;
+               }
+
+               int c = fgetc(input_file);
+               if ((c == EOF && read) || (char)c == '\n') {
+                       (*buffer)[read++] = 0;
+                       return read;
+               } else if (c == EOF) {
+                       return -1;
+               }
+
+               (*buffer)[read++] = (char)c;
+       } while (1);
+
+       return -1;
+}
+
+static int gatemate_read_cfg_file(struct gatemate_bit_file *bit_file,
+                                                       const char *filename)
+{
+       FILE *input_file = fopen(filename, "r");
+
+       if (!input_file) {
+               LOG_ERROR("Couldn't open %s: %s", filename, strerror(errno));
+               return ERROR_PLD_FILE_LOAD_FAILED;
+       }
+
+       int retval = ERROR_OK;
+       char *line_buffer = NULL;
+       size_t buffer_length = 0;
+       int nread;
+       while (((nread = gatemate_getline(&line_buffer, &buffer_length, 
input_file)) != -1) && (retval == ERROR_OK))
+               retval = gatemate_read_cfg_line(bit_file, line_buffer, 
(size_t)nread);
+
+       if (line_buffer)
+               free(line_buffer);
+
+       fclose(input_file);
+       if (retval != ERROR_OK)
+               free(bit_file->raw_file.data);
+       return retval;
+}
+
+static int gatemate_read_file(struct gatemate_bit_file *bit_file,
+                                               const char *filename)
+{
+       memset(bit_file, 0, sizeof(struct gatemate_bit_file));
+
+       if (!filename || !bit_file)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       /* check if binary .bit or ascii .cfg */
+       const char *file_suffix_pos = strrchr(filename, '.');
+       if (!file_suffix_pos) {
+               LOG_ERROR("Unable to detect filename suffix");
+               return ERROR_PLD_FILE_LOAD_FAILED;
+       }
+
+       if (strcasecmp(file_suffix_pos, ".bit") == 0)
+               return cpld_read_raw_bit_file(&bit_file->raw_file, filename);
+       else if (strcasecmp(file_suffix_pos, ".cfg") == 0)
+               return gatemate_read_cfg_file(bit_file, filename);
+
+       LOG_ERROR("Filetype not supported, expecting .bit or .cfg file");
+       return ERROR_PLD_FILE_LOAD_FAILED;
+}
+
+static void gatemate_set_instr(struct jtag_tap *tap,
+                                               uint32_t new_instr)
+{
+       struct scan_field field;
+
+       field.num_bits = tap->ir_length;
+
+       void *t = calloc(DIV_ROUND_UP(field.num_bits, 8), 1);
+       field.out_value = t;
+       buf_set_u32(t, 0, field.num_bits, new_instr);
+       field.in_value = NULL;
+
+       jtag_add_ir_scan(tap, &field, TAP_IDLE);
+       jtag_add_runtest(3, TAP_IDLE);
+
+       free(t);
+}
+
+static int gatemate_load(struct pld_device *pld_device, const char *filename)
+{
+       if (!pld_device)
+               return ERROR_FAIL;
+
+       struct gatemate_pld_device *gatemate_info = pld_device->driver_priv;
+
+       if (!gatemate_info || !gatemate_info->tap)
+               return ERROR_FAIL;
+       struct jtag_tap *tap = gatemate_info->tap;
+
+       struct gatemate_bit_file bit_file;
+       int retval = gatemate_read_file(&bit_file, filename);
+       if (retval != ERROR_OK) {
+               printf("gatemate_read_file failed !!!!!!\n");
+               return retval;
+       }
+
+       gatemate_set_instr(tap, JTAG_CONFIGURE);
+
+       struct scan_field field;
+       field.num_bits = bit_file.raw_file.length * 8;
+       field.out_value = bit_file.raw_file.data;
+       field.in_value = NULL;
+       jtag_add_dr_scan(tap, 1, &field, TAP_IDLE);
+
+       retval = jtag_execute_queue();
+       free(bit_file.raw_file.data);
+
+       return retval;
+}
+
+PLD_DEVICE_COMMAND_HANDLER(gatemate_pld_device_command)
+{
+       struct jtag_tap *tap;
+
+       struct gatemate_pld_device *gatemate_info;
+
+       if (CMD_ARGC != 2)
+               return ERROR_COMMAND_SYNTAX_ERROR;
+
+       tap = jtag_tap_by_string(CMD_ARGV[1]);
+       if (!tap) {
+               command_print(CMD, "Tap: %s does not exist", CMD_ARGV[1]);
+               return ERROR_FAIL;
+       }
+
+       gatemate_info = malloc(sizeof(struct gatemate_pld_device));
+       if (!gatemate_info) {
+               LOG_ERROR("Out of memory");
+               return ERROR_FAIL;
+       }
+       gatemate_info->tap = tap;
+
+       pld->driver_priv = gatemate_info;
+
+       return ERROR_OK;
+}
+
+static const struct command_registration gatemate_command_handler[] = {
+       {
+               .name = "gatemate",
+               .mode = COMMAND_ANY,
+               .handler = NULL,
+               .help = "gatemate specific commands",
+               .usage = "",
+       },
+       COMMAND_REGISTRATION_DONE
+};
+
+struct pld_driver gatemate_pld = {
+       .name = "gatemate",
+       .commands = gatemate_command_handler,
+       .pld_device_command = &gatemate_pld_device_command,
+       .load = &gatemate_load,
+};
diff --git a/src/pld/pld.c b/src/pld/pld.c
index d9e01f16cd..dd8f8263fe 100644
--- a/src/pld/pld.c
+++ b/src/pld/pld.c
@@ -19,6 +19,7 @@
 /* pld drivers
  */
 extern struct pld_driver efinix_pld;
+extern struct pld_driver gatemate_pld;
 extern struct pld_driver gowin_pld;
 extern struct pld_driver intel_pld;
 extern struct pld_driver lattice_pld;
@@ -26,6 +27,7 @@ extern struct pld_driver virtex2_pld;
 
 static struct pld_driver *pld_drivers[] = {
        &efinix_pld,
+       &gatemate_pld,
        &gowin_pld,
        &intel_pld,
        &lattice_pld,
diff --git a/tcl/board/gatemate_eval.cfg b/tcl/board/gatemate_eval.cfg
new file mode 100644
index 0000000000..cc078a0e30
--- /dev/null
+++ b/tcl/board/gatemate_eval.cfg
@@ -0,0 +1,16 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# GateMateTM FPGA Evaluation Board
+# https://www.colognechip.com/programmable-logic/gatemate-evaluation-board/
+#
+
+adapter driver ftdi
+ftdi vid_pid 0x0403 0x6010
+
+ftdi channel 0
+ftdi layout_init 0x0014 0x011b
+reset_config none
+transport select jtag
+adapter speed 6000
+
+source [find fpga/gatemate.cfg]
diff --git a/tcl/fpga/gatemate.cfg b/tcl/fpga/gatemate.cfg
new file mode 100644
index 0000000000..35a615936a
--- /dev/null
+++ b/tcl/fpga/gatemate.cfg
@@ -0,0 +1,15 @@
+# SPDX-License-Identifier: GPL-2.0-or-later
+
+# gatemate
+# https://www.
+
+if { [info exists CHIPNAME] } {
+       set _CHIPNAME $CHIPNAME
+} else {
+       set _CHIPNAME gatemate
+}
+
+jtag newtap $_CHIPNAME tap -irlen 6 -ignore-version \
+       -expected-id 0x20000001
+
+pld device gatemate $_CHIPNAME.tap

-- 

Reply via email to