This is an automated email from Gerrit.

"Benjamin Vernoux <bvern...@gmail.com>" just uploaded a new patch set to 
Gerrit, which you can find at https://review.openocd.org/c/openocd/+/7802

-- gerrit

commit 642996cf4404a25200c7d8d748200571f44139de
Author: Benjamin Vernoux <bvern...@gmail.com>
Date:   Thu Aug 31 10:18:37 2023 +0200

    Add Windows support to buspirate jtag driver
    
    Change-Id: I17ecaab934940af604eb1a8e69b90154da753eb5
    Signed-off-by: Benjamin Vernoux <bvern...@gmail.com>

diff --git a/configure.ac b/configure.ac
index a2442d40b5..0693772944 100644
--- a/configure.ac
+++ b/configure.ac
@@ -425,13 +425,6 @@ AS_CASE([$host],
     ])
     parport_use_giveio=yes
 
-    AS_IF([test "x$enable_buspirate" = "xyes"], [
-      AC_MSG_ERROR([buspirate currently not supported by MinGW32 hosts])
-    ])
-
-    # In case enable_buspirate=auto, make sure it will not be built.
-    enable_buspirate=no
-
     AC_SUBST([HOST_CPPFLAGS], [-D__USE_MINGW_ANSI_STDIO])
   ],
   [*darwin*], [
diff --git a/src/jtag/drivers/buspirate.c b/src/jtag/drivers/buspirate.c
index 03b48e68b2..27d900f5f5 100644
--- a/src/jtag/drivers/buspirate.c
+++ b/src/jtag/drivers/buspirate.c
@@ -4,6 +4,7 @@
  *   Copyright (C) 2010 by Michal Demin                                    *
  *   based on usbprog.c and arm-jtag-ew.c                                  *
  *   Several fixes by R. Diez in 2013.                                     *
+ *   Windows support by B.VERNOUX 31 Aug 2023.                             *
  ***************************************************************************/
 
 #ifdef HAVE_CONFIG_H
@@ -14,9 +15,18 @@
 #include <jtag/swd.h>
 #include <jtag/commands.h>
 
-#include <termios.h>
-#include <fcntl.h>
-#include <sys/ioctl.h>
+#ifdef _WIN32
+       #include <windows.h>
+       // termios.h typdef/include required/used
+       typedef unsigned char cc_t;
+       typedef unsigned int speed_t;
+       typedef HANDLE fd_handle_t;
+#else
+       typedef int fd_handle_t;
+       #include <termios.h>
+       #include <fcntl.h>
+       #include <sys/ioctl.h>
+#endif
 
 #undef DEBUG_SERIAL
 /*#define DEBUG_SERIAL */
@@ -100,8 +110,11 @@ enum {
 static bool swd_mode;
 static int  queued_retval;
 static char swd_features;
-
-static int buspirate_fd = -1;
+#ifdef _WIN32
+static fd_handle_t buspirate_fd = NULL;
+#else
+static fd_handle_t buspirate_fd = -1;
+#endif
 static int buspirate_pinmode = MODE_JTAG_OD;
 static int buspirate_baudrate = SERIAL_NORMAL;
 static int buspirate_vreg;
@@ -125,30 +138,30 @@ static void buspirate_tap_append_scan(int length, uint8_t 
*buffer,
                struct scan_command *command);
 static void buspirate_tap_make_space(int scan, int bits);
 
-static void buspirate_set_feature(int, char, char);
-static void buspirate_set_mode(int, char);
-static void buspirate_set_speed(int, char);
+static void buspirate_set_feature(fd_handle_t, char, char);
+static void buspirate_set_mode(fd_handle_t, char);
+static void buspirate_set_speed(fd_handle_t, char);
 
 /* low level interface */
-static void buspirate_bbio_enable(int);
-static void buspirate_jtag_reset(int);
-static unsigned char buspirate_jtag_command(int, uint8_t *, int);
-static void buspirate_jtag_set_speed(int, char);
-static void buspirate_jtag_set_mode(int, char);
-static void buspirate_jtag_set_feature(int, char, char);
-static void buspirate_jtag_get_adcs(int);
+static void buspirate_bbio_enable(fd_handle_t);
+static void buspirate_jtag_reset(fd_handle_t);
+static unsigned char buspirate_jtag_command(fd_handle_t, uint8_t *, int);
+static void buspirate_jtag_set_speed(fd_handle_t, char);
+static void buspirate_jtag_set_mode(fd_handle_t, char);
+static void buspirate_jtag_set_feature(fd_handle_t, char, char);
+static void buspirate_jtag_get_adcs(fd_handle_t);
 
 /* low level two-wire interface */
-static void buspirate_swd_set_speed(int, char);
-static void buspirate_swd_set_feature(int, char, char);
-static void buspirate_swd_set_mode(int, char);
+static void buspirate_swd_set_speed(fd_handle_t, char);
+static void buspirate_swd_set_feature(fd_handle_t, char, char);
+static void buspirate_swd_set_mode(fd_handle_t, char);
 
 /* low level HW communication interface */
-static int buspirate_serial_open(char *port);
-static int buspirate_serial_setspeed(int fd, char speed, cc_t timeout);
-static int buspirate_serial_write(int fd, uint8_t *buf, int size);
-static int buspirate_serial_read(int fd, uint8_t *buf, int size);
-static void buspirate_serial_close(int fd);
+static fd_handle_t buspirate_serial_open(char *port);
+static int buspirate_serial_setspeed(fd_handle_t fd, char speed, cc_t timeout);
+static int buspirate_serial_write(fd_handle_t fd, uint8_t *buf, int size);
+static int buspirate_serial_read(fd_handle_t fd, uint8_t *buf, int size);
+static void buspirate_serial_close(fd_handle_t fd);
 static void buspirate_print_buffer(uint8_t *buf, int size);
 
 static int buspirate_execute_queue(void)
@@ -227,17 +240,25 @@ static int buspirate_execute_queue(void)
 
 /* Returns true if successful, false if error. */
 
-static bool read_and_discard_all_data(const int fd)
+static bool read_and_discard_all_data(const fd_handle_t fd)
 {
        /* LOG_INFO("Discarding any stale data from a previous connection..."); 
*/
-
+#ifdef _WIN32
+       DWORD read_count;
+#else
+       ssize_t read_count;
+#endif
        bool was_msg_already_printed = false;
 
        for ( ; ; ) {
                uint8_t buffer[1024];  /* Any size will do, it's a trade-off 
between stack size and performance. */
 
-               const ssize_t read_count = read(fd, buffer, sizeof(buffer));
-
+#ifdef _WIN32
+               read_count = 0;
+               ReadFile(fd, buffer, sizeof(buffer), &read_count, NULL);
+#else
+               read_count = read(fd, buffer, sizeof(buffer));
+#endif
                if (read_count == 0) {
                        /* This is the "end of file" or "connection closed at 
the other end" condition. */
                        return true;
@@ -251,9 +272,11 @@ static bool read_and_discard_all_data(const int fd)
 
                        continue;
                }
-
+#ifdef _WIN32
+               /* Do nothing for Windows */
+#else
                assert(read_count == -1);  /* According to the specification. */
-
+#endif
                const int errno_code = errno;
 
                if (errno_code == EINTR)
@@ -280,7 +303,11 @@ static int buspirate_init(void)
        }
 
        buspirate_fd = buspirate_serial_open(buspirate_port);
+#ifdef _WIN32
+       if (buspirate_fd == NULL) {
+#else  
        if (buspirate_fd == -1) {
+#endif
                LOG_ERROR("Could not open serial port");
                return ERROR_JTAG_INIT_FAILED;
        }
@@ -351,8 +378,13 @@ static int buspirate_quit(void)
 /* openocd command interface */
 COMMAND_HANDLER(buspirate_handle_adc_command)
 {
+#ifdef _WIN32
+       if (buspirate_fd == NULL)
+               return ERROR_OK;
+#else  
        if (buspirate_fd == -1)
                return ERROR_OK;
+#endif
 
        /* unavailable in SWD mode */
        if (swd_mode)
@@ -870,7 +902,7 @@ static int buspirate_reset(int trst, int srst)
        return ERROR_OK;
 }
 
-static void buspirate_set_feature(int fd, char feat, char action)
+static void buspirate_set_feature(fd_handle_t fd, char feat, char action)
 {
        if (swd_mode)
                buspirate_swd_set_feature(fd, feat, action);
@@ -878,7 +910,7 @@ static void buspirate_set_feature(int fd, char feat, char 
action)
                buspirate_jtag_set_feature(fd, feat, action);
 }
 
-static void buspirate_set_mode(int fd, char mode)
+static void buspirate_set_mode(fd_handle_t fd, char mode)
 {
        if (swd_mode)
                buspirate_swd_set_mode(fd, mode);
@@ -886,7 +918,7 @@ static void buspirate_set_mode(int fd, char mode)
                buspirate_jtag_set_mode(fd, mode);
 }
 
-static void buspirate_set_speed(int fd, char speed)
+static void buspirate_set_speed(fd_handle_t fd, char speed)
 {
        if (swd_mode)
                buspirate_swd_set_speed(fd, speed);
@@ -897,7 +929,7 @@ static void buspirate_set_speed(int fd, char speed)
 
 /*************** swd lowlevel functions ********************/
 
-static void buspirate_swd_set_speed(int fd, char speed)
+static void buspirate_swd_set_speed(fd_handle_t fd, char speed)
 {
        int  ret;
        uint8_t tmp[1];
@@ -918,7 +950,7 @@ static void buspirate_swd_set_speed(int fd, char speed)
        }
 }
 
-static void buspirate_swd_set_mode(int fd, char mode)
+static void buspirate_swd_set_mode(fd_handle_t fd, char mode)
 {
        int ret;
        uint8_t tmp[1];
@@ -941,7 +973,7 @@ static void buspirate_swd_set_mode(int fd, char mode)
        }
 }
 
-static void buspirate_swd_set_feature(int fd, char feat, char action)
+static void buspirate_swd_set_feature(fd_handle_t fd, char feat, char action)
 {
        int  ret;
        uint8_t tmp[1];
@@ -979,7 +1011,7 @@ static void buspirate_swd_set_feature(int fd, char feat, 
char action)
 }
 
 /*************** jtag lowlevel functions ********************/
-static void buspirate_bbio_enable(int fd)
+static void buspirate_bbio_enable(fd_handle_t fd)
 {
        int ret;
        char command;
@@ -1040,7 +1072,7 @@ static void buspirate_bbio_enable(int fd)
 
 }
 
-static void buspirate_jtag_reset(int fd)
+static void buspirate_jtag_reset(fd_handle_t fd)
 {
        uint8_t tmp[5];
 
@@ -1056,7 +1088,7 @@ static void buspirate_jtag_reset(int fd)
                LOG_ERROR("Unable to restart buspirate!");
 }
 
-static void buspirate_jtag_set_speed(int fd, char speed)
+static void buspirate_jtag_set_speed(fd_handle_t fd, char speed)
 {
        int ret;
        uint8_t tmp[2];
@@ -1090,7 +1122,7 @@ static void buspirate_jtag_set_speed(int fd, char speed)
 }
 
 
-static void buspirate_jtag_set_mode(int fd, char mode)
+static void buspirate_jtag_set_mode(fd_handle_t fd, char mode)
 {
        uint8_t tmp[2];
        tmp[0] = CMD_PORT_MODE;
@@ -1098,7 +1130,7 @@ static void buspirate_jtag_set_mode(int fd, char mode)
        buspirate_jtag_command(fd, tmp, 2);
 }
 
-static void buspirate_jtag_set_feature(int fd, char feat, char action)
+static void buspirate_jtag_set_feature(fd_handle_t fd, char feat, char action)
 {
        uint8_t tmp[3];
        tmp[0] = CMD_FEATURE;
@@ -1107,7 +1139,7 @@ static void buspirate_jtag_set_feature(int fd, char feat, 
char action)
        buspirate_jtag_command(fd, tmp, 3);
 }
 
-static void buspirate_jtag_get_adcs(int fd)
+static void buspirate_jtag_get_adcs(fd_handle_t fd)
 {
        uint8_t tmp[10];
        uint16_t a, b, c, d;
@@ -1124,7 +1156,7 @@ static void buspirate_jtag_get_adcs(int fd)
                ((float)c)/155.1515, ((float)d)/155.1515);
 }
 
-static unsigned char buspirate_jtag_command(int fd,
+static unsigned char buspirate_jtag_command(fd_handle_t fd,
                uint8_t *cmd, int cmdlen)
 {
        int res;
@@ -1160,19 +1192,73 @@ static unsigned char buspirate_jtag_command(int fd,
 }
 
 /* low level serial port */
-/* TODO add support for WIN32 and others ! */
-static int buspirate_serial_open(char *port)
+// Support for WIN32 added
+static fd_handle_t buspirate_serial_open(char *port)
 {
-       int fd;
-       fd = open(buspirate_port, O_RDWR | O_NOCTTY | O_NDELAY);
+       fd_handle_t fd;
+#ifdef _WIN32
+       // Windows specific serial port opening
+       fd = CreateFile(port, GENERIC_READ | GENERIC_WRITE, FILE_SHARE_READ, 
NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL, NULL);
+       return fd;
+#else
+       // Linux specific serial port opening
+       fd = open(port, O_RDWR | O_NOCTTY | O_NDELAY);
        return fd;
+#endif
 }
 
-
 /* Returns -1 on error. */
-
-static int buspirate_serial_setspeed(int fd, char speed, cc_t timeout)
+static int buspirate_serial_setspeed(fd_handle_t fd, char speed, cc_t timeout)
 {
+#ifdef _WIN32
+       // Windows specific serial port configuration
+       DCB dcbSerialParams;
+       memset(&dcbSerialParams, 0, sizeof(dcbSerialParams));
+       dcbSerialParams.DCBlength = sizeof(dcbSerialParams);
+
+       if (!GetCommState(fd, &dcbSerialParams))
+               return -1;
+
+       speed_t baud = CBR_115200; // For USB Serial Port this value do not 
have any impact
+       dcbSerialParams.BaudRate = baud;
+       dcbSerialParams.ByteSize = 8;
+       dcbSerialParams.StopBits = ONESTOPBIT;
+       dcbSerialParams.Parity = NOPARITY;
+       dcbSerialParams.fOutxCtsFlow = FALSE;
+       dcbSerialParams.fOutxDsrFlow = FALSE;
+       dcbSerialParams.fDtrControl = DTR_CONTROL_DISABLE;
+       dcbSerialParams.fRtsControl = RTS_CONTROL_DISABLE;
+       dcbSerialParams.fBinary = TRUE;
+       dcbSerialParams.fDsrSensitivity = 0;    // DSR sensitivity
+       dcbSerialParams.fTXContinueOnXoff = 0;  // XOFF continues Tx
+       dcbSerialParams.fOutX = 0;                              // XON/XOFF 
output flow control
+       dcbSerialParams.fInX = 0;                               // XON/XOFF 
input flow control
+       dcbSerialParams.fErrorChar = 0;                 // enable error 
replacement
+       dcbSerialParams.fNull = 0;                              // enable null 
stripping
+       dcbSerialParams.fAbortOnError = 0;              // abort reads/writes 
on error
+       dcbSerialParams.XoffChar = 19;                  // Tx and Rx XOFF 
character
+       dcbSerialParams.XonChar = 17;                   // Tx and Rx XON 
character
+//     dcbSerialParams.XoffLim = 512;                  // transmit XOFF 
threshold
+//     dcbSerialParams.XonLim = 2048;                  // transmit XON 
threshold
+       dcbSerialParams.ErrorChar = 0;                  // error replacement 
character
+       dcbSerialParams.EofChar = 0;                    // end of input 
character
+       dcbSerialParams.EvtChar = 0;                    // received event 
character
+       
+       if (!SetCommState(fd, &dcbSerialParams))
+               return -1;
+
+       COMMTIMEOUTS timeouts;
+       timeouts.ReadIntervalTimeout = MAXDWORD;
+       timeouts.ReadTotalTimeoutMultiplier = 0;
+       timeouts.ReadTotalTimeoutConstant = timeout * 100;
+       timeouts.WriteTotalTimeoutMultiplier = 0;
+       timeouts.WriteTotalTimeoutConstant = 0;
+
+       if (!SetCommTimeouts(fd, &timeouts))
+               return -1;
+       return 0;
+#else
+       // Linux specific serial port configuration
        struct termios t_opt;
        speed_t baud = (speed == SERIAL_FAST) ? B1000000 : B115200;
 
@@ -1214,13 +1300,19 @@ static int buspirate_serial_setspeed(int fd, char 
speed, cc_t timeout)
        }
 
        return 0;
+#endif
 }
 
-static int buspirate_serial_write(int fd, uint8_t *buf, int size)
+static int buspirate_serial_write(fd_handle_t fd, uint8_t *buf, int size)
 {
        int ret = 0;
-
+#ifdef _WIN32
+       DWORD bytesWritten = 0;
+       if (WriteFile(fd, buf, size, &bytesWritten, NULL))
+               ret = bytesWritten;
+#else
        ret = write(fd, buf, size);
+#endif
 
        LOG_DEBUG("size = %d ret = %d", size, ret);
        buspirate_print_buffer(buf, size);
@@ -1231,9 +1323,32 @@ static int buspirate_serial_write(int fd, uint8_t *buf, 
int size)
        return ret;
 }
 
-static int buspirate_serial_read(int fd, uint8_t *buf, int size)
+static int buspirate_serial_read(fd_handle_t fd, uint8_t *buf, int size)
 {
        int len = 0;
+#ifdef _WIN32
+       int timeout = 0;
+       DWORD read_count;
+
+       while (len < size) {
+               read_count = 0;
+               if (ReadFile(fd, buf + len, size - len, &read_count, NULL) == 
TRUE) {
+                       if (read_count == 0) {
+                               timeout++;
+
+                               if (timeout >= 10)
+                                       break;
+
+                               continue;
+                       }
+
+                       len += read_count;
+               } else {
+                       LOG_ERROR("ReadFile() Error return -1");
+                       return -1;
+               }
+       }
+#else
        int ret = 0;
        int timeout = 0;
 
@@ -1253,6 +1368,7 @@ static int buspirate_serial_read(int fd, uint8_t *buf, 
int size)
 
                len += ret;
        }
+#endif
 
        LOG_DEBUG("should have read = %d actual size = %d", size, len);
        buspirate_print_buffer(buf, len);
@@ -1263,9 +1379,13 @@ static int buspirate_serial_read(int fd, uint8_t *buf, 
int size)
        return len;
 }
 
-static void buspirate_serial_close(int fd)
+static void buspirate_serial_close(fd_handle_t fd)
 {
+#ifdef _WIN32
+       CloseHandle(fd);
+#else
        close(fd);
+#endif
 }
 
 #define LINE_SIZE      81

-- 

Reply via email to