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 --