Rework for new eismulitplexer pcb
add documentation add pkg-config files
This commit is contained in:
parent
dbbf1068dc
commit
e4af92276c
|
@ -1,29 +1,33 @@
|
||||||
cmake_minimum_required(VERSION 3.0)
|
cmake_minimum_required(VERSION 3.0)
|
||||||
|
|
||||||
project(uvosled)
|
project(eismultiplexer)
|
||||||
|
|
||||||
set(SRC_FILES uvosled.c usbshm.c)
|
find_package(PkgConfig REQUIRED)
|
||||||
set(LIBS -pthread -lusb-1.0 )
|
pkg_check_modules(LIBUSB REQUIRED libusb-1.0)
|
||||||
|
|
||||||
|
if(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
set(CMAKE_INSTALL_PREFIX "/usr" CACHE PATH "..." FORCE)
|
||||||
|
endif(CMAKE_INSTALL_PREFIX_INITIALIZED_TO_DEFAULT)
|
||||||
|
|
||||||
|
set(SRC_FILES eismultiplexer.c usbshm.c)
|
||||||
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
add_library(${PROJECT_NAME} SHARED ${SRC_FILES})
|
||||||
target_link_libraries( ${PROJECT_NAME} ${LIBS})
|
target_link_libraries(${PROJECT_NAME} ${LIBUSB_LIBRARIES} -pthread)
|
||||||
|
target_include_directories(${PROJECT_NAME} PUBLIC ${LIBUSB_INCLUDE_DIRS})
|
||||||
add_definitions("-std=c17 -Wall -O2 -fno-strict-aliasing")
|
add_definitions("-std=c17 -Wall -O2 -fno-strict-aliasing")
|
||||||
|
|
||||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
|
||||||
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
|
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
|
||||||
install(FILES ./uvosled.h DESTINATION include)
|
install(FILES ./eismultiplexer.h DESTINATION include)
|
||||||
|
|
||||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||||
set(SRC_FILES_TEST_APP main.c)
|
add_executable(${PROJECT_NAME}_test main.c)
|
||||||
set(LIBS_TEST -l${PROJECT_NAME})
|
|
||||||
add_executable(${PROJECT_NAME}_test ${SRC_FILES_TEST_APP})
|
|
||||||
add_dependencies(${PROJECT_NAME}_test ${PROJECT_NAME})
|
add_dependencies(${PROJECT_NAME}_test ${PROJECT_NAME})
|
||||||
target_link_libraries( ${PROJECT_NAME}_test ${LIBS_TEST})
|
target_link_libraries( ${PROJECT_NAME}_test -l${PROJECT_NAME})
|
||||||
add_definitions("-std=c17 -Wall -O2 -fno-strict-aliasing")
|
add_definitions("-std=c17 -Wall -O2 -fno-strict-aliasing")
|
||||||
|
|
||||||
install(TARGETS ${PROJECT_NAME}_test DESTINATION bin)
|
install(TARGETS ${PROJECT_NAME}_test DESTINATION bin)
|
||||||
|
|
||||||
|
configure_file(pkgconfig/eismuliplexer.pc.in pkgconfig/eismuliplexer.pc @ONLY)
|
||||||
|
install(FILES ${CMAKE_CURRENT_BINARY_DIR}/pkgconfig/eismuliplexer.pc DESTINATION lib/pkgconfig)
|
||||||
|
|
||||||
if(CMAKE_SYSTEM_NAME MATCHES "^Linux")
|
if(CMAKE_SYSTEM_NAME MATCHES "^Linux")
|
||||||
set(UDEV_RULES_INSTALL_DIR /lib/udev/rules.d CACHE PATH "install directory for linux udev config")
|
set(UDEV_RULES_INSTALL_DIR /lib/udev/rules.d CACHE PATH "install directory for linux udev config")
|
||||||
install(FILES 90-usbled.rules DESTINATION ${UDEV_RULES_INSTALL_DIR})
|
install(FILES 90-eismultiplexer.rules DESTINATION ${UDEV_RULES_INSTALL_DIR})
|
||||||
endif()
|
endif()
|
||||||
|
|
113
eismultiplexer.c
Normal file
113
eismultiplexer.c
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2023 Carl Klemm
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#define _POSIX_C_SOURCE 199309L
|
||||||
|
#include "eismultiplexer.h"
|
||||||
|
#include "usbshm.h"
|
||||||
|
#include <stdlib.h>
|
||||||
|
#include <time.h>
|
||||||
|
|
||||||
|
static void usleep(uint64_t microseconds)
|
||||||
|
{
|
||||||
|
struct timespec ts;
|
||||||
|
ts.tv_sec = microseconds / 1000000;
|
||||||
|
ts.tv_nsec = (microseconds % 1000000) * 1000;
|
||||||
|
nanosleep(&ts, NULL);
|
||||||
|
}
|
||||||
|
|
||||||
|
static void dataCallback(uint8_t request, unsigned char* data, size_t length, void* user_data)
|
||||||
|
{
|
||||||
|
struct eismulitplexer* muliplexer = user_data;
|
||||||
|
|
||||||
|
if(length >= 1)
|
||||||
|
muliplexer->activeChannels = data[0];
|
||||||
|
|
||||||
|
sem_post(&muliplexer->readSem);
|
||||||
|
}
|
||||||
|
|
||||||
|
int eismulitplexer_connect(struct eismulitplexer* muliplexer, int serial)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
muliplexer->priv = malloc(sizeof(*muliplexer->priv));
|
||||||
|
if(!muliplexer->priv)
|
||||||
|
return -1;
|
||||||
|
|
||||||
|
ret = usbshm_init(muliplexer->priv, &dataCallback, 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;
|
||||||
|
}
|
||||||
|
|
||||||
|
int eismulitplexer_connect_channel_exclusive(struct eismulitplexer* muliplexer, channel_t channel)
|
||||||
|
{
|
||||||
|
uint16_t wValue;
|
||||||
|
// we compile with fno-strict-aliasing
|
||||||
|
uint8_t* wValChar = (uint8_t*)&wValue;
|
||||||
|
wValChar[0] = channel;
|
||||||
|
wValChar[1] = 0;
|
||||||
|
int ret;
|
||||||
|
while((ret = usbshm_writeControlTransfer(muliplexer->priv, 2, NULL, 0, wValue, 0)) == USBSHM_ERROR_AGAIN)
|
||||||
|
usleep(1000000);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
int eismulitplexer_connect_channel(struct eismulitplexer* muliplexer, channel_t channel)
|
||||||
|
{
|
||||||
|
channel_t channels = eismulitplexer_get_connected(muliplexer);
|
||||||
|
channels |= channel;
|
||||||
|
return eismulitplexer_connect_channel_exclusive(muliplexer, channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
int eismulitplexer_disconnect_channel(struct eismulitplexer* muliplexer, channel_t channel)
|
||||||
|
{
|
||||||
|
channel_t channels = eismulitplexer_get_connected(muliplexer);
|
||||||
|
channels &= ~channel;
|
||||||
|
return eismulitplexer_connect_channel_exclusive(muliplexer, channels);
|
||||||
|
}
|
||||||
|
|
||||||
|
channel_t eismulitplexer_get_connected(struct eismulitplexer* muliplexer)
|
||||||
|
{
|
||||||
|
usbshm_readControlTransfer(muliplexer->priv, 3, 1);
|
||||||
|
sem_wait(&muliplexer->readSem);
|
||||||
|
return muliplexer->activeChannels;
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
|
int eismulitplexer_set_led(struct eismulitplexer* muliplexer, bool on)
|
||||||
|
{
|
||||||
|
int ret;
|
||||||
|
while((ret = usbshm_writeControlTransfer(muliplexer->priv, on, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN)
|
||||||
|
usleep(1000000);
|
||||||
|
return ret;
|
||||||
|
}
|
||||||
|
|
||||||
|
void eismulitplexer_disconnect(struct eismulitplexer* muliplexer)
|
||||||
|
{
|
||||||
|
usbshm_distroy(muliplexer->priv);
|
||||||
|
free(muliplexer->priv);
|
||||||
|
muliplexer->priv = NULL;
|
||||||
|
sem_destroy(&muliplexer->readSem);
|
||||||
|
}
|
113
eismultiplexer.h
Normal file
113
eismultiplexer.h
Normal file
|
@ -0,0 +1,113 @@
|
||||||
|
/**
|
||||||
|
* Copyright (C) 2023 Carl Klemm
|
||||||
|
*
|
||||||
|
* This program is free software; you can redistribute it and/or
|
||||||
|
* modify it under the terms of the GNU General Public License
|
||||||
|
* version 3 as published by the Free Software Foundation.
|
||||||
|
*
|
||||||
|
* This program is distributed in the hope that it will be useful,
|
||||||
|
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
||||||
|
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
||||||
|
* GNU General Public License for more details.
|
||||||
|
*
|
||||||
|
* You should have received a copy of the GNU General Public License
|
||||||
|
* along with this program; if not, write to the
|
||||||
|
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
||||||
|
* Boston, MA 02110-1301, USA.
|
||||||
|
*/
|
||||||
|
|
||||||
|
#pragma once
|
||||||
|
|
||||||
|
#include <stdint.h>
|
||||||
|
#include <semaphore.h>
|
||||||
|
#include <stdbool.h>
|
||||||
|
|
||||||
|
/**
|
||||||
|
Api for use by libscipaper eismulitplexer.
|
||||||
|
* @defgroup API User API
|
||||||
|
* This api allows you to controll the EISmulitplexer device.
|
||||||
|
* @{
|
||||||
|
*/
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
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_NONE = 0,
|
||||||
|
} channel_t;
|
||||||
|
|
||||||
|
struct eismulitplexer {
|
||||||
|
struct usbshm* priv;
|
||||||
|
sem_t readSem;
|
||||||
|
channel_t activeChannels;
|
||||||
|
};
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Attempts to connect to a EISmulitplexer device and initalizes a eismulitplexer struct
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct to initalize
|
||||||
|
* @param serial The serial number of the device to connect to, or 0 for any
|
||||||
|
* @return 0 on sucess and < 0 on failure
|
||||||
|
*/
|
||||||
|
int eismulitplexer_connect(struct eismulitplexer* muliplexer, int serial);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Conects the given channel(s) to the common inputs
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct
|
||||||
|
* @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B)
|
||||||
|
* @return 0 on sucess and < 0 on failure
|
||||||
|
*/
|
||||||
|
int eismulitplexer_connect_channel(struct eismulitplexer* muliplexer, channel_t channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Conects the given channel(s) to the common inputs disconnecting all others
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct
|
||||||
|
* @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B)
|
||||||
|
* @return 0 on sucess and < 0 on failure
|
||||||
|
*/
|
||||||
|
int eismulitplexer_connect_channel_exclusive(struct eismulitplexer* muliplexer, channel_t channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnect the given channel(s) to the common inputs disconnecting all others
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct
|
||||||
|
* @param channel A channel to connect, multiple channels can be specified by or'ing together the chanel flags e.g. (CHANNEL_A | CHANNEL_B)
|
||||||
|
* All channels can be dissconnected by passing CHANNEL_NONE
|
||||||
|
* @return 0 on sucess and < 0 on failure
|
||||||
|
*/
|
||||||
|
int eismulitplexer_disconnect_channel(struct eismulitplexer* muliplexer, channel_t channel);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Returns the channels currently connected
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct
|
||||||
|
* @return channels connected as a bitfield
|
||||||
|
*/
|
||||||
|
channel_t eismulitplexer_get_connected(struct eismulitplexer* muliplexer);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Turns the led on the pcb on or off
|
||||||
|
* @param muliplexer pointer to a eismulitplexer struct
|
||||||
|
* @param on true to turn the led on, false to turn it off
|
||||||
|
* @return 0 on sucess and < 0 on failure
|
||||||
|
*/
|
||||||
|
int eismulitplexer_set_led(struct eismulitplexer* muliplexer, bool on);
|
||||||
|
|
||||||
|
/**
|
||||||
|
* @brief Disconnects from the eismulitplexer
|
||||||
|
*/
|
||||||
|
void eismulitplexer_disconnect(struct eismulitplexer* muliplexer);
|
||||||
|
|
||||||
|
#ifdef __cplusplus
|
||||||
|
}
|
||||||
|
#endif
|
||||||
|
|
||||||
|
/**
|
||||||
|
....
|
||||||
|
* @}
|
||||||
|
*/
|
126
main.c
126
main.c
|
@ -18,92 +18,104 @@
|
||||||
*/
|
*/
|
||||||
|
|
||||||
#include <stdio.h>
|
#include <stdio.h>
|
||||||
#include <unistd.h>
|
|
||||||
#include <math.h>
|
|
||||||
#include <stdlib.h>
|
#include <stdlib.h>
|
||||||
#include <string.h>
|
#include <string.h>
|
||||||
#include "uvosled.h"
|
#include "eismultiplexer.h"
|
||||||
|
|
||||||
void print_help(const char* progname)
|
void print_help(const char* progname)
|
||||||
{
|
{
|
||||||
printf("usage: %s [OPERATION] [CHANNEL] [VALUE]\n", progname);
|
printf("usage: %s [OPERATION] [CHANNEL] [VALUE]\n", progname);
|
||||||
printf("available operations: set on off help\n");
|
printf("available operations: connect disconnect help\n");
|
||||||
}
|
}
|
||||||
|
|
||||||
|
channel_t char_to_channel(char ch)
|
||||||
|
{
|
||||||
|
switch(ch)
|
||||||
|
{
|
||||||
|
case 'a':
|
||||||
|
case 'A':
|
||||||
|
case '1':
|
||||||
|
return CHANNEL_A;
|
||||||
|
case 'b':
|
||||||
|
case 'B':
|
||||||
|
case '2':
|
||||||
|
return CHANNEL_B;
|
||||||
|
case 'c':
|
||||||
|
case 'C':
|
||||||
|
case '3':
|
||||||
|
return CHANNEL_C;
|
||||||
|
case 'd':
|
||||||
|
case 'D':
|
||||||
|
case '4':
|
||||||
|
return CHANNEL_D;
|
||||||
|
case 'e':
|
||||||
|
case 'E':
|
||||||
|
case '5':
|
||||||
|
return CHANNEL_E;
|
||||||
|
case 'f':
|
||||||
|
case 'F':
|
||||||
|
case '6':
|
||||||
|
return CHANNEL_F;
|
||||||
|
case 'g':
|
||||||
|
case 'G':
|
||||||
|
case '7':
|
||||||
|
return CHANNEL_NONE;
|
||||||
|
default:
|
||||||
|
return CHANNEL_NONE;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
|
||||||
int main(int argc, char* argv[])
|
int main(int argc, char* argv[])
|
||||||
{
|
{
|
||||||
if(argc < 2 || strcmp (argv[1], "help") == 0)
|
if(argc < 2 || strcmp(argv[1], "help") == 0)
|
||||||
{
|
{
|
||||||
print_help(argv[0]);
|
print_help(argv[0]);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
||||||
struct uvosled led;
|
struct eismulitplexer multiplexer;
|
||||||
|
|
||||||
if(uvosled_connect(&led))
|
if(eismulitplexer_connect(&multiplexer, 0))
|
||||||
{
|
{
|
||||||
printf("Can not connect to UVOS usbled device\n");
|
printf("Can not connect to EISmultiplexer device\n");
|
||||||
return -1;
|
return 1;
|
||||||
}
|
}
|
||||||
|
|
||||||
if(strcmp(argv[1], "on") == 0)
|
|
||||||
{
|
|
||||||
if(uvosled_poweron(&led))
|
|
||||||
printf("cant power on \n");
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[1], "off") == 0)
|
|
||||||
{
|
|
||||||
uvosled_set_current(&led, 0xff , 0);
|
|
||||||
uvosled_poweroff(&led);
|
|
||||||
}
|
|
||||||
else if(strcmp(argv[1], "set") == 0)
|
|
||||||
{
|
|
||||||
if(argc != 4)
|
if(argc != 4)
|
||||||
{
|
{
|
||||||
printf("usage: %s set [CHANNEL] [VALUE]\n", argv[0]);
|
print_help(argv[0]);
|
||||||
uvosled_poweroff(&led);
|
eismulitplexer_disconnect(&multiplexer);
|
||||||
return 0;
|
return 2;
|
||||||
}
|
}
|
||||||
|
|
||||||
uint8_t mask = 0;
|
channel_t channel = char_to_channel(argv[2][0]);
|
||||||
|
if(channel == CHANNEL_NONE)
|
||||||
switch(argv[2][0])
|
|
||||||
{
|
{
|
||||||
case 'a':
|
printf("%c is not a valid channel", argv[2][0]);
|
||||||
case 'A':
|
eismulitplexer_disconnect(&multiplexer);
|
||||||
case '1':
|
return 2;
|
||||||
mask = CHANNEL_A;
|
|
||||||
break;
|
|
||||||
case 'b':
|
|
||||||
case 'B':
|
|
||||||
case '2':
|
|
||||||
mask = CHANNEL_B;
|
|
||||||
break;
|
|
||||||
case 'c':
|
|
||||||
case 'C':
|
|
||||||
case '3':
|
|
||||||
mask = CHANNEL_C;
|
|
||||||
break;
|
|
||||||
case 'd':
|
|
||||||
case 'D':
|
|
||||||
case '4':
|
|
||||||
mask = CHANNEL_D;
|
|
||||||
break;
|
|
||||||
default:
|
|
||||||
printf("A channel must be selected out of A, B, C or D\n");
|
|
||||||
}
|
}
|
||||||
|
|
||||||
if(mask)
|
if(strcmp(argv[1], "connect") == 0)
|
||||||
{
|
{
|
||||||
char* end;
|
if(eismulitplexer_connect_channel(&multiplexer, channel))
|
||||||
float value = strtof(argv[3], &end);
|
{
|
||||||
if(isnan(value) || value < 0 || value > 1.0f)
|
printf("could not connect channel %c", argv[2][0]);
|
||||||
printf("A channel value between 0 and 1.0 must be supplied\n");
|
eismulitplexer_disconnect(&multiplexer);
|
||||||
else if(uvosled_set_current(&led, mask, value))
|
return 3;
|
||||||
printf("Failed to set current\n");
|
}
|
||||||
|
}
|
||||||
|
else if(strcmp(argv[1], "disconnect") == 0)
|
||||||
|
{
|
||||||
|
if(eismulitplexer_disconnect_channel(&multiplexer, channel))
|
||||||
|
{
|
||||||
|
printf("could not connect channel %c", argv[2][0]);
|
||||||
|
eismulitplexer_disconnect(&multiplexer);
|
||||||
|
return 3;
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
uvosled_disconnect(&led);
|
eismulitplexer_disconnect(&multiplexer);
|
||||||
return 0;
|
return 0;
|
||||||
}
|
}
|
||||||
|
|
7
pkgconfig/eismuliplexer.pc.in
Normal file
7
pkgconfig/eismuliplexer.pc.in
Normal file
|
@ -0,0 +1,7 @@
|
||||||
|
includedir=@CMAKE_INSTALL_PREFIX@/include
|
||||||
|
|
||||||
|
Name: libeismuliplexer
|
||||||
|
Description: C lib to control EISmultiplexer devices
|
||||||
|
Version: 1.0
|
||||||
|
Libs: -L${libdir} -leismultiplexer
|
||||||
|
Cflags: -I${includedir}
|
5
usbshm.c
5
usbshm.c
|
@ -75,7 +75,7 @@ bool usbshm_isOpen(struct usbshm* instance)
|
||||||
return instance->priv->handle != NULL;
|
return instance->priv->handle != NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, unsigned char* data, size_t length))
|
int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, unsigned char* data, size_t length, void* user_data), void* user_data)
|
||||||
{
|
{
|
||||||
int ret=0;
|
int ret=0;
|
||||||
instance->priv = malloc(sizeof(*instance->priv));
|
instance->priv = malloc(sizeof(*instance->priv));
|
||||||
|
@ -86,6 +86,7 @@ int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, u
|
||||||
instance->productID = 0;
|
instance->productID = 0;
|
||||||
instance->productName = NULL;
|
instance->productName = NULL;
|
||||||
instance->dataCallback = dataCallback;
|
instance->dataCallback = dataCallback;
|
||||||
|
instance->user_data = user_data;
|
||||||
if(objectCounter == 0)
|
if(objectCounter == 0)
|
||||||
{
|
{
|
||||||
printf("Usb Init\n");
|
printf("Usb Init\n");
|
||||||
|
@ -249,7 +250,7 @@ static void usbshm_transferCallBack(struct libusb_transfer *transfer)
|
||||||
else if(transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
|
else if(transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
|
||||||
{
|
{
|
||||||
if(context->dataCallback && transfer->length-8 >= transfer->actual_length)
|
if(context->dataCallback && transfer->length-8 >= transfer->actual_length)
|
||||||
context->dataCallback(transfer->buffer[1], transfer->buffer+8, transfer->actual_length);
|
context->dataCallback(transfer->buffer[1], transfer->buffer+8, transfer->actual_length, context->user_data);
|
||||||
}
|
}
|
||||||
free(context->priv->buffer);
|
free(context->priv->buffer);
|
||||||
libusb_free_transfer(context->priv->transfer);
|
libusb_free_transfer(context->priv->transfer);
|
||||||
|
|
5
usbshm.h
5
usbshm.h
|
@ -36,12 +36,13 @@ struct usbshm {
|
||||||
int vendorID;
|
int vendorID;
|
||||||
int productID;
|
int productID;
|
||||||
char* productName;
|
char* productName;
|
||||||
void (*dataCallback)(uint8_t request, unsigned char* data, size_t length);
|
void* user_data;
|
||||||
|
void (*dataCallback)(uint8_t request, unsigned char* data, size_t length, void* user_data);
|
||||||
};
|
};
|
||||||
|
|
||||||
void usbshm_distroy(struct usbshm* instance);
|
void usbshm_distroy(struct usbshm* instance);
|
||||||
|
|
||||||
int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, unsigned char* data, size_t length));
|
int usbshm_init(struct usbshm* instance, void (*dataCallback)(uint8_t request, unsigned char* data, size_t length, void* user_data), void* user_data);
|
||||||
|
|
||||||
bool usbshm_ready(struct usbshm* instance);
|
bool usbshm_ready(struct usbshm* instance);
|
||||||
|
|
||||||
|
|
124
uvosled.c
124
uvosled.c
|
@ -1,124 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (C) 2023 Carl Klemm
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* version 3 as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#define _POSIX_C_SOURCE 199309L
|
|
||||||
#include "uvosled.h"
|
|
||||||
#include "usbshm.h"
|
|
||||||
#include <stdlib.h>
|
|
||||||
#include <time.h>
|
|
||||||
|
|
||||||
void usleep(uint64_t microseconds)
|
|
||||||
{
|
|
||||||
struct timespec ts;
|
|
||||||
ts.tv_sec = microseconds / 1000000;
|
|
||||||
ts.tv_nsec = (microseconds % 1000000) * 1000;
|
|
||||||
nanosleep(&ts, NULL);
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_connect(struct uvosled* led)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
led->priv = malloc(sizeof(*led->priv));
|
|
||||||
if(!led->priv)
|
|
||||||
return -1;
|
|
||||||
|
|
||||||
ret = usbshm_init(led->priv, NULL);
|
|
||||||
if(ret)
|
|
||||||
return -2;
|
|
||||||
|
|
||||||
ret = usbshm_open(led->priv, 0xfe17, 0x06dc , NULL);
|
|
||||||
if(ret)
|
|
||||||
return -3;
|
|
||||||
return 0;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_poweron(struct uvosled* led)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 0, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_poweroff(struct uvosled* led)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 1, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_set_current(struct uvosled* led, uint8_t channels, float current)
|
|
||||||
{
|
|
||||||
if(current < 0)
|
|
||||||
return -1;
|
|
||||||
else if(current > 1)
|
|
||||||
return -2;
|
|
||||||
uint8_t currentU = current * 255;
|
|
||||||
// TODO: implment endianess
|
|
||||||
uint16_t wValue;
|
|
||||||
// we compile with fno-strict-aliasing
|
|
||||||
uint8_t* wValChar = (uint8_t*)&wValue;
|
|
||||||
wValChar[0] = channels;
|
|
||||||
wValChar[1] = currentU;
|
|
||||||
int ret;
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 2, NULL, 0, wValue, 0)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_trigger(struct uvosled* led)
|
|
||||||
{
|
|
||||||
int ret;
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 1, NULL, 0, 0, 0)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
int uvosled_capture(struct uvosled* led, int channels, float current, double time, double cameraOffset)
|
|
||||||
{
|
|
||||||
if(current < 0 || current > 1 || time > 1 || cameraOffset < -1 || cameraOffset > 1)
|
|
||||||
return USBSHM_ERROR_PARAM;
|
|
||||||
|
|
||||||
uint8_t currentU = current * 255;
|
|
||||||
uint16_t timeU = time * 1000;
|
|
||||||
int16_t cameraOffsetU = cameraOffset * 1000;
|
|
||||||
int ret;
|
|
||||||
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 5, NULL, 0, *((uint16_t*)&cameraOffsetU), 0)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
if(ret < 0)
|
|
||||||
return ret;
|
|
||||||
|
|
||||||
// TODO: implment endianess
|
|
||||||
uint16_t wValue;
|
|
||||||
// we compile with fno-strict-aliasing
|
|
||||||
uint8_t* wValChar = (uint8_t*)&wValue;
|
|
||||||
wValChar[0] = channels;
|
|
||||||
wValChar[1] = currentU;
|
|
||||||
while((ret = usbshm_writeControlTransfer(led->priv, 1, NULL, 0, wValue, timeU)) == USBSHM_ERROR_AGAIN)
|
|
||||||
usleep(1000000);
|
|
||||||
return ret;
|
|
||||||
}
|
|
||||||
|
|
||||||
void uvosled_disconnect(struct uvosled* led)
|
|
||||||
{
|
|
||||||
usbshm_distroy(led->priv);
|
|
||||||
free(led->priv);
|
|
||||||
led->priv = NULL;
|
|
||||||
}
|
|
65
uvosled.h
65
uvosled.h
|
@ -1,65 +0,0 @@
|
||||||
/**
|
|
||||||
* Copyright (C) 2023 Carl Klemm
|
|
||||||
*
|
|
||||||
* This program is free software; you can redistribute it and/or
|
|
||||||
* modify it under the terms of the GNU General Public License
|
|
||||||
* version 3 as published by the Free Software Foundation.
|
|
||||||
*
|
|
||||||
* This program is distributed in the hope that it will be useful,
|
|
||||||
* but WITHOUT ANY WARRANTY; without even the implied warranty of
|
|
||||||
* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
|
|
||||||
* GNU General Public License for more details.
|
|
||||||
*
|
|
||||||
* You should have received a copy of the GNU General Public License
|
|
||||||
* along with this program; if not, write to the
|
|
||||||
* Free Software Foundation, Inc., 51 Franklin Street, Fifth Floor,
|
|
||||||
* Boston, MA 02110-1301, USA.
|
|
||||||
*/
|
|
||||||
|
|
||||||
#pragma once
|
|
||||||
|
|
||||||
#include <stdint.h>
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
extern "C" {
|
|
||||||
#endif
|
|
||||||
|
|
||||||
#define CHANNEL_A 1
|
|
||||||
#define CHANNEL_B (1 << 1)
|
|
||||||
#define CHANNEL_C (1 << 2)
|
|
||||||
#define CHANNEL_D (1 << 3)
|
|
||||||
|
|
||||||
struct uvosled {
|
|
||||||
struct usbshm* priv;
|
|
||||||
};
|
|
||||||
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_connect(struct uvosled* led);
|
|
||||||
|
|
||||||
// power on cameras
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_poweron(struct uvosled* led);
|
|
||||||
|
|
||||||
// power off cameras
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_poweroff(struct uvosled* led);
|
|
||||||
|
|
||||||
// channels is a mask of bits, you can set it like this: CHANNEL_A | CHANNEL_C to activate channels A and C
|
|
||||||
// current is in percent of the values selected by the linear regulator resistors
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_set_current(struct uvosled* led, uint8_t channels, float current);
|
|
||||||
|
|
||||||
// causes the cameras to take an image
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_trigger(struct uvosled* led);
|
|
||||||
|
|
||||||
// leds are lit for time seconds and the camera is activated cameraOffset seconds after they are lit
|
|
||||||
// real time guarenteed by microcontroller
|
|
||||||
// returns 0 on sucess and < 0 on failure
|
|
||||||
int uvosled_capture(struct uvosled* led, int channels, float current, double time, double cameraOffset);
|
|
||||||
|
|
||||||
void uvosled_disconnect(struct uvosled* led);
|
|
||||||
|
|
||||||
#ifdef __cplusplus
|
|
||||||
}
|
|
||||||
#endif
|
|
Loading…
Reference in a new issue