Skip to content
Snippets Groups Projects
Commit c7603f54 authored by Carl Philipp Klemm's avatar Carl Philipp Klemm
Browse files

add the ability to select a specific device via serial number

add a interactive mode
add a batch mode
parent e43ef91f
No related branches found
No related tags found
No related merge requests found
......@@ -42,7 +42,7 @@ static void usleep(uint64_t microseconds)
nanosleep(&ts, NULL);
}
int eismultiplexer_connect(struct eismultiplexer* muliplexer, int serial)
int eismultiplexer_connect(struct eismultiplexer* muliplexer, uint16_t serial)
{
int ret;
muliplexer->priv = malloc(sizeof(*muliplexer->priv));
......@@ -53,7 +53,10 @@ int eismultiplexer_connect(struct eismultiplexer* muliplexer, int serial)
if(ret)
return -2;
ret = usbshm_open(muliplexer->priv, 0xfe17, 0x07dc , NULL);
unsigned char serialStr[5];
snprintf((char*)serialStr, sizeof(serialStr), "%04hu", serial);
ret = usbshm_open(muliplexer->priv, 0xfe17, 0x07dc , serial == 0 ? NULL : serialStr);
if(ret)
return -3;
return 0;
......@@ -93,7 +96,7 @@ int eismultiplexer_disconnect_channel(struct eismultiplexer* muliplexer, channel
channel_t eismultiplexer_get_connected(struct eismultiplexer* muliplexer)
{
uint8_t buffer[2] = {};
usbshm_readControlTransferSync(muliplexer->priv, 3, buffer, 1);
usbshm_readControlTransferSync(muliplexer->priv, 3, 0, 0, buffer, 1);
return buffer[0];
}
......@@ -108,7 +111,7 @@ int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on)
int eismultiplexer_write_eeprom(struct eismultiplexer* muliplexer, uint16_t addr, uint16_t value)
{
int ret;
while((ret = usbshm_writeControlTransfer(muliplexer->priv, 4, NULL, 0, value, addr)) == USBSHM_ERROR_AGAIN)
while((ret = usbshm_writeControlTransfer(muliplexer->priv, 5, NULL, 0, value, addr)) == USBSHM_ERROR_AGAIN)
usleep(1000000);
return ret;
}
......@@ -116,7 +119,7 @@ int eismultiplexer_write_eeprom(struct eismultiplexer* muliplexer, uint16_t addr
uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t addr)
{
uint8_t buffer[2] = {};
usbshm_readControlTransferSync(muliplexer->priv, 5, buffer, 2);
usbshm_readControlTransferSync(muliplexer->priv, 4, 0, addr, buffer, 2);
return *((uint16_t*)buffer);
}
......
......@@ -63,7 +63,7 @@ struct eismultiplexer {
* @param serial The serial number of the device to connect to, or 0 for any
* @return 0 on sucess and < 0 on failure
*/
int eismultiplexer_connect(struct eismultiplexer* muliplexer, int serial);
int eismultiplexer_connect(struct eismultiplexer* muliplexer, uint16_t serial);
/**
* @brief Conects the given channel(s) to the common inputs
......
......@@ -29,15 +29,11 @@
#include <stdio.h>
#include <stdlib.h>
#include <string.h>
#include <signal.h>
#include "eismultiplexer.h"
#include "options.h"
void print_help(const char* progname)
{
printf("usage: %s [OPERATION] [CHANNEL] [VALUE]\n", progname);
printf("available operations: connect disconnect clear connect_all get help\n");
}
channel_t char_to_channel(char ch)
static channel_t char_to_channel(char ch)
{
switch(ch)
{
......@@ -74,53 +70,73 @@ channel_t char_to_channel(char ch)
}
}
void disconnect(struct eismultiplexer* multiplexer)
static int process_commands(char** commands, size_t command_count, struct eismultiplexer* multiplexer, char* name)
{
if(strcmp(commands[0], "clear") == 0)
{
eismultiplexer_set_led(multiplexer, false);
eismultiplexer_disconnect(multiplexer);
eismultiplexer_disconnect_channel(multiplexer, CHANNEL_NONE);
}
int main(int argc, char* argv[])
else if(strcmp(commands[0], "write") == 0)
{
if(argc < 2 || strcmp(argv[1], "help") == 0)
if(command_count < 3)
{
print_help(argv[0]);
return 0;
printf("Usage %s %s [ADDRESS] [VALUE]\n", name, commands[0]);
return 2;
}
struct eismultiplexer multiplexer;
if(eismultiplexer_connect(&multiplexer, 0))
long address = strtol(commands[1], NULL, 10);
long value = strtol(commands[2], NULL, 10);
if(address > UINT16_MAX || address < 0 || value < 0 || value > UINT16_MAX)
{
printf("Can not connect to EISmultiplexer device\n");
return 1;
puts("Value or address is out of range");
return 2;
}
eismultiplexer_set_led(&multiplexer, true);
if(strcmp(argv[1], "clear") == 0)
if(address % 2 == 1)
{
puts("Address must be a even number, 16 bits are written at a time");
return 2;
}
eismultiplexer_write_eeprom(multiplexer, address, value);
}
else if(strcmp(commands[0], "read") == 0)
{
if(command_count < 2)
{
printf("Usage %s %s [ADDRESS] [LENGTH]\n", name, commands[0]);
return 2;
}
long address = strtol(commands[1], NULL, 10);
long length = 2;
if(command_count > 2)
length = strtol(commands[2], NULL, 10);
if(address > UINT16_MAX || address < 0 || length < 0 || length > UINT16_MAX)
{
eismultiplexer_disconnect_channel(&multiplexer, CHANNEL_NONE);
return 2;
puts("Value or address is out of range");
}
if(address % 2 == 1)
{
puts("Address must be a even number, 16 bits are read at a time");
return 2;
}
else if(strcmp(argv[1], "write") == 0)
if(length % 2 == 1)
{
eismultiplexer_write_eeprom(&multiplexer, 0, 42);
puts("Length must be a even number, 16 bits are read at a time");
return 2;
}
else if(strcmp(argv[1], "read") == 0)
for(uint16_t i = address; i - address < length; i+=2)
{
uint16_t value = eismultiplexer_read_eeprom(&multiplexer, 0);
printf("0: %u\n", value);
uint16_t value = eismultiplexer_read_eeprom(multiplexer, i);
printf("%u: %u\n", i, value);
}
}
else if(strcmp(argv[1], "connect_all") == 0)
else if(strcmp(commands[0], "connect_all") == 0)
{
eismultiplexer_connect_channel(&multiplexer, 0xff);
eismultiplexer_connect_channel(multiplexer, 0xff);
}
else if(strcmp(argv[1], "get") == 0)
else if(strcmp(commands[0], "get") == 0)
{
channel_t channels = eismultiplexer_get_connected(&multiplexer);
printf("%d\n", channels);
channel_t channels = eismultiplexer_get_connected(multiplexer);
for(size_t i = 0; i < 7; ++i)
{
bool connected = channels & (1 << i);
......@@ -129,41 +145,134 @@ int main(int argc, char* argv[])
}
else
{
if(argc != 3)
if(command_count != 2)
{
printf("Usage %s %s [CHANNEL]\n", argv[0], argv[1]);
disconnect(&multiplexer);
printf("Usage %s %s [CHANNEL]\n", name, commands[0]);
return 2;
}
channel_t channel = char_to_channel(argv[2][0]);
channel_t channel = char_to_channel(commands[1][0]);
if(channel == CHANNEL_NONE)
{
printf("%c is not a valid channel\n", argv[2][0]);
disconnect(&multiplexer);
printf("%c is not a valid channel\n", commands[1][0]);
return 2;
}
if(strcmp(argv[1], "connect") == 0)
if(strcmp(commands[0], "connect") == 0)
{
if(eismultiplexer_connect_channel(&multiplexer, channel))
if(eismultiplexer_connect_channel(multiplexer, channel))
{
printf("could not connect channel %c\n", argv[2][0]);
disconnect(&multiplexer);
printf("could not connect channel %c\n", commands[1][0]);
return 3;
}
}
else if(strcmp(argv[1], "disconnect") == 0)
else if(strcmp(commands[0], "disconnect") == 0)
{
if(eismultiplexer_disconnect_channel(&multiplexer, channel))
if(eismultiplexer_disconnect_channel(multiplexer, channel))
{
printf("could not disconnect channel %c\n", argv[2][0]);
disconnect(&multiplexer);
printf("could not disconnect channel %c\n", commands[1][0]);
return 3;
}
}
}
disconnect(&multiplexer);
return 0;
}
enum
{
INPUT_SUCESS = 0,
INPUT_NO_INPUT,
INPUT_TOO_LONG
};
static int get_input(char *prompt, char *buffer, size_t length)
{
int ch, extra;
if(prompt != NULL)
{
fputs(prompt, stdout);
fflush(stdout);
}
if(fgets (buffer, length, stdin) == NULL)
return INPUT_NO_INPUT;
if(buffer[strlen(buffer)-1] != '\n')
{
extra = 0;
while((ch = getchar()) != '\n' && ch != EOF)
extra = 1;
return (extra == 1) ? INPUT_TOO_LONG : INPUT_SUCESS;
}
buffer[strlen(buffer)-1] = '\0';
return INPUT_SUCESS;
}
int main(int argc, char* argv[])
{
struct config config = {};
argp_parse(&argp, argc, argv, 0, 0, &config);
if(config.command_count < 1 && !(config.interactive || config.pipe))
{
printf("A command is required\n");
return 2;
}
struct eismultiplexer multiplexer;
if(eismultiplexer_connect(&multiplexer, config.serialSet ? config.serial : 0))
{
char serialStr[5];
snprintf(serialStr, sizeof(serialStr), "%04hu", config.serial);
printf("Can not connect to EISmultiplexer device%s%s\n",
config.serialSet ? " with serial " : "", config.serialSet ? serialStr : "");
return 1;
}
int ret = 0;
if(config.interactive || config.pipe)
{
char buffer[256];
while(true)
{
int ret = get_input(config.pipe ? NULL : "> ", buffer, sizeof(buffer));
if(ret == INPUT_NO_INPUT)
{
break;
}
else if(ret != INPUT_SUCESS)
{
puts("Invalid command");
continue;
}
char* commands[MAX_COMMANDS];
char* command = strtok(buffer, " \t");
size_t i = 0;
while(command && i < MAX_COMMANDS)
{
commands[i] = command;
command = strtok(NULL, " \t");
++i;
}
int cmdRet = process_commands(commands, i, &multiplexer, "");
if(cmdRet == 0)
puts("OK");
else
printf("ERR %i\n", cmdRet);
}
}
else
{
eismultiplexer_set_led(&multiplexer, true);
ret = process_commands(config.commands, config.command_count, &multiplexer, argv[0]);
eismultiplexer_set_led(&multiplexer, false);
}
eismultiplexer_disconnect(&multiplexer);
return ret;
}
......@@ -59,7 +59,6 @@ void usbshm_distroy(struct usbshm* instance)
free(instance->priv->transfer);
libusb_close(instance->priv->handle);
free(instance->priv->buffer);
free(instance->productName);
free(instance->priv);
if(--objectCounter == 0)
{
......@@ -94,7 +93,6 @@ int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, u
instance->priv->buffer = NULL;
instance->vendorID = 0;
instance->productID = 0;
instance->productName = NULL;
instance->dataCallback = dataCallback;
instance->user_data = user_data;
if(objectCounter == 0)
......@@ -114,7 +112,7 @@ bool usbshm_ready(struct usbshm* instance)
return instance->priv->transfer == NULL;
}
int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char* productName)
int usbshm_open(struct usbshm* instance, int vendorID, int productID, const unsigned char* serial)
{
instance->priv->handle = NULL;
pthread_mutex_lock(libusbDataMutex);
......@@ -130,6 +128,21 @@ int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char
if(desc.idVendor == vendorID && desc.idProduct == productID)
{
errorCode = libusb_open(list[i], &instance->priv->handle) < 0 ? USBSHM_ERROR_ERR : 0;
if(serial)
{
size_t len = strlen((const char*)serial)+1;
unsigned char* buffer = malloc(len);
buffer[0] = '\0';
libusb_get_string_descriptor_ascii(instance->priv->handle, desc.iSerialNumber, buffer, len);
int cmp = strcmp((const char*)serial, (const char*)buffer);
free(buffer);
if(cmp != 0)
{
libusb_close(instance->priv->handle);
instance->priv->handle = NULL;
continue;
}
}
break;
}
}
......@@ -145,15 +158,6 @@ int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char
{
instance->vendorID = vendorID;
instance->productID = productID;
if(productName)
{
instance->productName = malloc(strlen(productName)+1);
strcpy(instance->productName, productName);
}
else
{
instance->productName = NULL;
}
libusb_set_auto_detach_kernel_driver(instance->priv->handle, true);
}
else
......@@ -181,7 +185,7 @@ void usbshm_reset(struct usbshm* instance)
void usbshm_reopen(struct usbshm* instance)
{
libusb_close(instance->priv->handle);
usbshm_open(instance, instance->vendorID, instance->productID, instance->productName);
usbshm_open(instance, instance->vendorID, instance->productID, NULL);
}
int usbshm_writeControlTransfer(struct usbshm* instance, const uint8_t request,
......@@ -219,7 +223,7 @@ int usbshm_writeControlTransfer(struct usbshm* instance, const uint8_t request,
else return USBSHM_ERROR_AGAIN;
}
int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t length)
int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t wValue, const uint16_t wIndex, const uint16_t length)
{
if(!usbshm_isOpen(instance))
return USBSHM_ERROR_NOT_CONNECTED;
......@@ -230,7 +234,7 @@ int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, c
pthread_mutex_lock(libusbDataMutex);
instance->priv->buffer = malloc(length+8);
libusb_fill_control_setup(instance->priv->buffer, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
request, request, request, length);
request, wValue, wIndex, length);
instance->priv->transfer = libusb_alloc_transfer(0);
libusb_fill_control_transfer(instance->priv->transfer, instance->priv->handle, instance->priv->buffer, &usbshm_transferCallBack, instance, 100);
int ret = libusb_submit_transfer(instance->priv->transfer);
......@@ -265,8 +269,8 @@ static void usbshm_transferCallBack(struct libusb_transfer *transfer)
context->priv->transfer = NULL;
}
int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, uint8_t* buffer, const uint16_t length)
int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, const uint16_t wValue, const uint16_t wIndex, uint8_t* buffer, const uint16_t length)
{
return libusb_control_transfer(instance->priv->handle, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN,
request, request, request, buffer, length, 2000);
request, wValue, wIndex, buffer, length, 2000);
}
......@@ -45,7 +45,6 @@ struct usbshm {
struct usbshm_priv* priv;
int vendorID;
int productID;
char* productName;
void* user_data;
void (*dataCallback)(uint8_t request, unsigned char* data, size_t length, void* user_data);
};
......@@ -56,7 +55,7 @@ int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, u
bool usbshm_ready(struct usbshm* instance);
int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char* productName);
int usbshm_open(struct usbshm* instance, int vendorID, int productID, const unsigned char* serial);
bool usbshm_isOpen(struct usbshm* instance);
......@@ -68,7 +67,7 @@ int usbshm_writeControlTransfer(struct usbshm* instance, const uint8_t request,
char* buffer, const uint8_t length,
const uint16_t wValue, const uint16_t wIndex);
int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t length);
int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t wValue, const uint16_t wIndex, const uint16_t length);
int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, uint8_t* buffer, const uint16_t length);
int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, const uint16_t wValue, const uint16_t wIndex, uint8_t* buffer, const uint16_t length);
0% Loading or .
You are about to add 0 people to the discussion. Proceed with caution.
Please register or to comment