diff --git a/minichlink/ardulink.c b/minichlink/ardulink.c index 44fa1446f831715b03b56fde47cad800cbaa04c7..96c0d93a56d7a2a15924c0d747110e9a59d27242 100644 --- a/minichlink/ardulink.c +++ b/minichlink/ardulink.c @@ -101,7 +101,20 @@ void * TryInit_Ardulink(void) return NULL; } - if (serial_dev_create(&ctx->serial, DEFAULT_SERIAL_NAME, 115200) == -1) { + const char* serial_to_open = NULL; + // This is extremely crude. We receive no parameters, yet we have + // to find the correct serial port for the programmer. + // since the init is executed before the command line parameters are parsed, + // we don't get the value of any "--serial-port=..." switch at all. + // We at least to make it usable by using an environment variable. + // Optimally, we would restructure the init function to include init hints + // or try to enumerate all existing serial ports for our Ardulink programmer. + if ((serial_to_open = getenv("MINICHLINK_SERIAL")) == NULL) { + // fallback + serial_to_open = DEFAULT_SERIAL_NAME; + } + + if (serial_dev_create(&ctx->serial, serial_to_open, 115200) == -1) { perror("create"); return NULL; } diff --git a/minichlink/minichlink.exe b/minichlink/minichlink.exe index f366cfcf2e1fb0fd2451a2c4217a62650e72829a..9e237b4d661f6ae951a3010a84948b76e99a133b 100644 Binary files a/minichlink/minichlink.exe and b/minichlink/minichlink.exe differ diff --git a/minichlink/serial_dev.c b/minichlink/serial_dev.c index 5a35fbe3d45fa1ec9b74886f4c4bddab89d89dcb..f39780fa580f833a47a6ecb8ee756957937637fc 100644 --- a/minichlink/serial_dev.c +++ b/minichlink/serial_dev.c @@ -16,19 +16,31 @@ int serial_dev_create(serial_dev_t *dev, const char* port, unsigned baud) { int serial_dev_open(serial_dev_t *dev) { fprintf(stderr, "Opening serial port %s at %u baud.\n", dev->port, dev->baud); #ifdef IS_WINDOWS - dev->handle = CreateFileA(dev->port, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0,0); + // Windows quirk: port = "COM10" is invalid, has to be encoded as "\\.\COM10". + // This also works for COM below 9. So, let's give the user the ability to use + // any "COMx" string and just prepend the "\\.\". + char winPortName[64]; + if(dev->port[0] != '\\') { + snprintf(winPortName, sizeof(winPortName), "\\\\.\\%s", dev->port); + } else { + // copy verbatim if string already starts with a '\' + snprintf(winPortName, sizeof(winPortName), "%s", dev->port); + } + dev->handle = CreateFileA(winPortName, GENERIC_READ | GENERIC_WRITE, 0, 0, OPEN_EXISTING, 0,0); if (dev->handle == INVALID_HANDLE_VALUE) { if (GetLastError() == ERROR_FILE_NOT_FOUND) { fprintf(stderr, "Serial port %s not found.\n", dev->port); + // weird: without this, errno = 0 (no error). + _set_errno(ERROR_FILE_NOT_FOUND); return -1; // Device not found } // Error while opening the device - return -2; + return -1; } DCB dcbSerialParams; dcbSerialParams.DCBlength = sizeof(dcbSerialParams); if (!GetCommState(dev->handle, &dcbSerialParams)) { - return -3; + return -1; } // set baud and 8N1 serial formatting dcbSerialParams.BaudRate = dev->baud; @@ -37,7 +49,7 @@ int serial_dev_open(serial_dev_t *dev) { dcbSerialParams.Parity = NOPARITY; // write back if (!SetCommState(dev->handle, &dcbSerialParams)){ - return -5; + return -1; } // Set the timeout parameters to "no timeout" (blocking). // see https://learn.microsoft.com/en-us/windows/win32/api/winbase/ns-winbase-commtimeouts @@ -49,7 +61,7 @@ int serial_dev_open(serial_dev_t *dev) { timeouts.WriteTotalTimeoutMultiplier = 0; // Write the parameters if (!SetCommTimeouts(dev->handle, &timeouts)) { - return -6; + return -1; } #else struct termios attr; @@ -60,7 +72,7 @@ int serial_dev_open(serial_dev_t *dev) { if (tcgetattr(dev->fd, &attr) == -1) { perror("tcgetattr"); - return -2; + return -1; } cfmakeraw(&attr); @@ -68,7 +80,7 @@ int serial_dev_open(serial_dev_t *dev) { if (tcsetattr(dev->fd, TCSANOW, &attr) == -1) { perror("tcsetattr"); - return -3; + return -1; } #endif // all okay if we get here @@ -118,12 +130,12 @@ int serial_dev_do_dtr_reset(serial_dev_t *dev) { if (tcdrain(dev->fd) == -1) { perror("tcdrain"); - return -2; + return -1; } if (ioctl(dev->fd, TIOCMBIS, &argp) == -1) { perror("ioctl"); - return -3; + return -1; } #endif return 0;