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)
|
||||
|
||||
project(uvosled)
|
||||
project(eismultiplexer)
|
||||
|
||||
set(SRC_FILES uvosled.c usbshm.c)
|
||||
set(LIBS -pthread -lusb-1.0 )
|
||||
find_package(PkgConfig REQUIRED)
|
||||
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})
|
||||
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")
|
||||
|
||||
set(CMAKE_INSTALL_PREFIX "/usr")
|
||||
install(TARGETS ${PROJECT_NAME} DESTINATION lib)
|
||||
install(FILES ./uvosled.h DESTINATION include)
|
||||
install(FILES ./eismultiplexer.h DESTINATION include)
|
||||
|
||||
link_directories(${CMAKE_CURRENT_BINARY_DIR})
|
||||
set(SRC_FILES_TEST_APP main.c)
|
||||
set(LIBS_TEST -l${PROJECT_NAME})
|
||||
add_executable(${PROJECT_NAME}_test ${SRC_FILES_TEST_APP})
|
||||
add_executable(${PROJECT_NAME}_test main.c)
|
||||
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")
|
||||
|
||||
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")
|
||||
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()
|
||||
|
|
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
|
||||
|
||||
/**
|
||||
....
|
||||
* @}
|
||||
*/
|
142
main.c
142
main.c
|
@ -18,18 +18,54 @@
|
|||
*/
|
||||
|
||||
#include <stdio.h>
|
||||
#include <unistd.h>
|
||||
#include <math.h>
|
||||
#include <stdlib.h>
|
||||
#include <string.h>
|
||||
#include "uvosled.h"
|
||||
#include "eismultiplexer.h"
|
||||
|
||||
void print_help(const char* 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[])
|
||||
{
|
||||
if(argc < 2 || strcmp(argv[1], "help") == 0)
|
||||
|
@ -38,72 +74,48 @@ int main(int argc, char* argv[])
|
|||
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");
|
||||
return -1;
|
||||
printf("Can not connect to EISmultiplexer device\n");
|
||||
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)
|
||||
{
|
||||
printf("usage: %s set [CHANNEL] [VALUE]\n", argv[0]);
|
||||
uvosled_poweroff(&led);
|
||||
return 0;
|
||||
}
|
||||
|
||||
uint8_t mask = 0;
|
||||
|
||||
switch(argv[2][0])
|
||||
{
|
||||
case 'a':
|
||||
case 'A':
|
||||
case '1':
|
||||
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)
|
||||
{
|
||||
char* end;
|
||||
float value = strtof(argv[3], &end);
|
||||
if(isnan(value) || value < 0 || value > 1.0f)
|
||||
printf("A channel value between 0 and 1.0 must be supplied\n");
|
||||
else if(uvosled_set_current(&led, mask, value))
|
||||
printf("Failed to set current\n");
|
||||
}
|
||||
}
|
||||
|
||||
uvosled_disconnect(&led);
|
||||
print_help(argv[0]);
|
||||
eismulitplexer_disconnect(&multiplexer);
|
||||
return 2;
|
||||
}
|
||||
|
||||
channel_t channel = char_to_channel(argv[2][0]);
|
||||
if(channel == CHANNEL_NONE)
|
||||
{
|
||||
printf("%c is not a valid channel", argv[2][0]);
|
||||
eismulitplexer_disconnect(&multiplexer);
|
||||
return 2;
|
||||
}
|
||||
|
||||
if(strcmp(argv[1], "connect") == 0)
|
||||
{
|
||||
if(eismulitplexer_connect_channel(&multiplexer, channel))
|
||||
{
|
||||
printf("could not connect channel %c", argv[2][0]);
|
||||
eismulitplexer_disconnect(&multiplexer);
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
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;
|
||||
}
|
||||
}
|
||||
|
||||
eismulitplexer_disconnect(&multiplexer);
|
||||
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;
|
||||
}
|
||||
|
||||
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;
|
||||
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->productName = NULL;
|
||||
instance->dataCallback = dataCallback;
|
||||
instance->user_data = user_data;
|
||||
if(objectCounter == 0)
|
||||
{
|
||||
printf("Usb Init\n");
|
||||
|
@ -249,7 +250,7 @@ static void usbshm_transferCallBack(struct libusb_transfer *transfer)
|
|||
else if(transfer->type == LIBUSB_TRANSFER_TYPE_CONTROL)
|
||||
{
|
||||
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);
|
||||
libusb_free_transfer(context->priv->transfer);
|
||||
|
|
5
usbshm.h
5
usbshm.h
|
@ -36,12 +36,13 @@ struct usbshm {
|
|||
int vendorID;
|
||||
int productID;
|
||||
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);
|
||||
|
||||
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);
|
||||
|
||||
|
|
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