Skip to content
Snippets Groups Projects
Commit b89184f4 authored by maxgerhardt's avatar maxgerhardt
Browse files

User-specifyable serial port per env var, better error handling

parent a4de56d6
No related branches found
No related tags found
No related merge requests found
......@@ -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;
}
......
No preview for this file type
......@@ -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;
......
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Finish editing this message first!
Please register or to comment