diff --git a/eismultiplexer.c b/eismultiplexer.c index ae0bfd0641abe144ed20a8218e78bfb146bc661b..e83aad97a03e4b6aeae97636062bf5853dba0367 100644 --- a/eismultiplexer.c +++ b/eismultiplexer.c @@ -26,10 +26,13 @@ */ #define _POSIX_C_SOURCE 199309L + +#include <stdint.h> #include "eismultiplexer.h" #include "usbshm.h" #include <stdlib.h> #include <time.h> +#include <stdio.h> static void usleep(uint64_t microseconds) { @@ -39,16 +42,6 @@ static void usleep(uint64_t microseconds) nanosleep(&ts, NULL); } -static void dataCallback(uint8_t request, unsigned char* data, size_t length, void* user_data) -{ - struct eismultiplexer* muliplexer = user_data; - - if(length >= 1) - muliplexer->activeChannels = data[0]; - - sem_post(&muliplexer->readSem); -} - int eismultiplexer_connect(struct eismultiplexer* muliplexer, int serial) { int ret; @@ -56,17 +49,13 @@ int eismultiplexer_connect(struct eismultiplexer* muliplexer, int serial) if(!muliplexer->priv) return -1; - ret = usbshm_init(muliplexer->priv, &dataCallback, muliplexer); + ret = usbshm_init(muliplexer->priv, NULL, muliplexer); if(ret) return -2; ret = usbshm_open(muliplexer->priv, 0xfe17, 0x07dc , NULL); if(ret) return -3; - - ret = sem_init(&muliplexer->readSem, 0, 0); - if(ret) - return -4; return 0; } @@ -92,19 +81,22 @@ int eismultiplexer_connect_channel(struct eismultiplexer* muliplexer, channel_t int eismultiplexer_disconnect_channel(struct eismultiplexer* muliplexer, channel_t channel) { - channel_t channels = eismultiplexer_get_connected(muliplexer); - channels &= ~channel; + channel_t channels = CHANNEL_NONE; + if(channel != CHANNEL_NONE) + { + channels = eismultiplexer_get_connected(muliplexer); + channels &= ~channel; + } return eismultiplexer_connect_channel_exclusive(muliplexer, channels); } channel_t eismultiplexer_get_connected(struct eismultiplexer* muliplexer) { - usbshm_readControlTransfer(muliplexer->priv, 3, 1); - sem_wait(&muliplexer->readSem); - return muliplexer->activeChannels; + uint8_t buffer[2] = {}; + usbshm_readControlTransferSync(muliplexer->priv, 3, buffer, 1); + return buffer[0]; } - int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on) { int ret; @@ -113,10 +105,24 @@ int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on) return ret; } +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) + usleep(1000000); + return ret; +} + +uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t addr) +{ + uint8_t buffer[2] = {}; + usbshm_readControlTransferSync(muliplexer->priv, 5, buffer, 2); + return *((uint16_t*)buffer); +} + void eismultiplexer_disconnect(struct eismultiplexer* muliplexer) { usbshm_distroy(muliplexer->priv); free(muliplexer->priv); muliplexer->priv = NULL; - sem_destroy(&muliplexer->readSem); } diff --git a/eismultiplexer.h b/eismultiplexer.h index 929a9691690111cf58556a052a0163bd356482f3..81e103a243d1071ea601877fab1d07cb54d7d3a4 100644 --- a/eismultiplexer.h +++ b/eismultiplexer.h @@ -43,20 +43,18 @@ extern "C" { #endif typedef enum { - CHANNEL_A = (1 << 1), - CHANNEL_B = (1 << 2), - CHANNEL_C = (1 << 3), - CHANNEL_D = (1 << 4), - CHANNEL_E = (1 << 5), - CHANNEL_F = (1 << 6), - CHANNEL_G = (1 << 7), + CHANNEL_A = (1 << 0), + CHANNEL_B = (1 << 1), + CHANNEL_C = (1 << 2), + CHANNEL_D = (1 << 3), + CHANNEL_E = (1 << 4), + CHANNEL_F = (1 << 5), + CHANNEL_G = (1 << 6), CHANNEL_NONE = 0, } channel_t; struct eismultiplexer { struct usbshm* priv; - sem_t readSem; - channel_t activeChannels; }; /** @@ -112,6 +110,9 @@ int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on); */ void eismultiplexer_disconnect(struct eismultiplexer* muliplexer); +int eismultiplexer_write_eeprom(struct eismultiplexer* muliplexer, uint16_t addr, uint16_t value); +uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t addr); + #ifdef __cplusplus } #endif diff --git a/main.c b/main.c index 05aab0b6373a13e1d827ec90fad0abda4385e65d..846676dd86468f3438c6961f179ff58c4be4176c 100644 --- a/main.c +++ b/main.c @@ -25,6 +25,7 @@ * SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE. */ +#include <stdint.h> #include <stdio.h> #include <stdlib.h> #include <string.h> @@ -33,7 +34,7 @@ void print_help(const char* progname) { printf("usage: %s [OPERATION] [CHANNEL] [VALUE]\n", progname); - printf("available operations: connect disconnect help\n"); + printf("available operations: connect disconnect clear connect_all get help\n"); } channel_t char_to_channel(char ch) @@ -67,13 +68,20 @@ channel_t char_to_channel(char ch) case 'g': case 'G': case '7': - return CHANNEL_NONE; + return CHANNEL_G; default: return CHANNEL_NONE; } } +void disconnect(struct eismultiplexer* multiplexer) +{ + eismultiplexer_set_led(multiplexer, false); + eismultiplexer_disconnect(multiplexer); +} + + int main(int argc, char* argv[]) { if(argc < 2 || strcmp(argv[1], "help") == 0) @@ -90,40 +98,72 @@ int main(int argc, char* argv[]) return 1; } - if(argc != 4) + eismultiplexer_set_led(&multiplexer, true); + + if(strcmp(argv[1], "clear") == 0) { - print_help(argv[0]); - eismultiplexer_disconnect(&multiplexer); - return 2; + eismultiplexer_disconnect_channel(&multiplexer, CHANNEL_NONE); } - - channel_t channel = char_to_channel(argv[2][0]); - if(channel == CHANNEL_NONE) + else if(strcmp(argv[1], "write") == 0) { - printf("%c is not a valid channel", argv[2][0]); - eismultiplexer_disconnect(&multiplexer); - return 2; + eismultiplexer_write_eeprom(&multiplexer, 0, 42); } - - if(strcmp(argv[1], "connect") == 0) + else if(strcmp(argv[1], "read") == 0) + { + uint16_t value = eismultiplexer_read_eeprom(&multiplexer, 0); + printf("0: %u\n", value); + } + else if(strcmp(argv[1], "connect_all") == 0) { - if(eismultiplexer_connect_channel(&multiplexer, channel)) + eismultiplexer_connect_channel(&multiplexer, 0xff); + } + else if(strcmp(argv[1], "get") == 0) + { + channel_t channels = eismultiplexer_get_connected(&multiplexer); + printf("%d\n", channels); + for(size_t i = 0; i < 7; ++i) { - printf("could not connect channel %c", argv[2][0]); - eismultiplexer_disconnect(&multiplexer); - return 3; + bool connected = channels & (1 << i); + printf("Channel %c: %s\n", (char)('A'+i), connected ? "on" : "off"); } } - else if(strcmp(argv[1], "disconnect") == 0) + else { - if(eismultiplexer_disconnect_channel(&multiplexer, channel)) + if(argc != 3) + { + printf("Usage %s %s [CHANNEL]\n", argv[0], argv[1]); + disconnect(&multiplexer); + return 2; + } + + channel_t channel = char_to_channel(argv[2][0]); + if(channel == CHANNEL_NONE) + { + printf("%c is not a valid channel\n", argv[2][0]); + disconnect(&multiplexer); + return 2; + } + + if(strcmp(argv[1], "connect") == 0) + { + if(eismultiplexer_connect_channel(&multiplexer, channel)) + { + printf("could not connect channel %c\n", argv[2][0]); + disconnect(&multiplexer); + return 3; + } + } + else if(strcmp(argv[1], "disconnect") == 0) { - printf("could not connect channel %c", argv[2][0]); - eismultiplexer_disconnect(&multiplexer); - return 3; + if(eismultiplexer_disconnect_channel(&multiplexer, channel)) + { + printf("could not disconnect channel %c\n", argv[2][0]); + disconnect(&multiplexer); + return 3; + } } } - eismultiplexer_disconnect(&multiplexer); + disconnect(&multiplexer); return 0; } diff --git a/usbshm.c b/usbshm.c index f6c880ef57f195c064c9d00b8d0f4d4928343213..ae2516ec22d0aca852803b8c1a3b8aaa42e46368 100644 --- a/usbshm.c +++ b/usbshm.c @@ -27,6 +27,7 @@ #include "usbshm.h" +#include <stdint.h> #include <stdio.h> #include <stdatomic.h> #include <stdbool.h> @@ -98,7 +99,6 @@ int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, u instance->user_data = user_data; if(objectCounter == 0) { - printf("Usb Init\n"); ret = libusb_init(NULL) < 0 ? USBSHM_ERROR_ERR : 0; libusbDataMutex = malloc(sizeof(*libusbDataMutex)); pthread_mutex_init(libusbDataMutex, NULL); @@ -118,7 +118,6 @@ int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char { instance->priv->handle = NULL; pthread_mutex_lock(libusbDataMutex); - printf("Listing Devices\n"); libusb_device** list; int count = libusb_get_device_list(NULL, &list); int errorCode = 0; @@ -141,7 +140,7 @@ int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char pthread_mutex_unlock(libusbDataMutex); return USBSHM_ERROR_ERR; } - + if(usbshm_isOpen(instance)) { instance->vendorID = vendorID; @@ -162,8 +161,7 @@ int usbshm_open(struct usbshm* instance, int vendorID, int productID, const char printf("Opening usb device failed\n"); errorCode = USBSHM_ERROR_ERR; } - - + libusb_free_device_list(list, count); pthread_mutex_unlock(libusbDataMutex); return errorCode; @@ -221,7 +219,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 uint8_t length) +int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t length) { if(!usbshm_isOpen(instance)) return USBSHM_ERROR_NOT_CONNECTED; @@ -231,7 +229,8 @@ 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); + libusb_fill_control_setup(instance->priv->buffer, LIBUSB_REQUEST_TYPE_VENDOR | LIBUSB_RECIPIENT_DEVICE | LIBUSB_ENDPOINT_IN, + request, request, request, 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,3 +264,9 @@ static void usbshm_transferCallBack(struct libusb_transfer *transfer) libusb_free_transfer(context->priv->transfer); context->priv->transfer = NULL; } + +int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, 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); +} diff --git a/usbshm.h b/usbshm.h index c9f5c3a4d7e31727e7481f5bb64fda4f8c54dd88..add9a7ff34c4da5acfd58ea8228f43be5354a5f3 100644 --- a/usbshm.h +++ b/usbshm.h @@ -28,6 +28,7 @@ #include <libusb-1.0/libusb.h> #include <pthread.h> #include <stdatomic.h> +#include <stdint.h> #include <time.h> #include <stdbool.h> @@ -67,5 +68,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 uint8_t length); +int usbshm_readControlTransfer(struct usbshm* instance, const uint8_t request, const uint16_t length); + +int usbshm_readControlTransferSync(struct usbshm* instance, const uint8_t request, uint8_t* buffer, const uint16_t length);