Add trigger functionality
This commit is contained in:
parent
5c42094b06
commit
ba13899644
107
eismultiplexer.c
107
eismultiplexer.c
|
@ -33,6 +33,39 @@
|
|||
#include <stdlib.h>
|
||||
#include <time.h>
|
||||
#include <stdio.h>
|
||||
#include <sys/time.h>
|
||||
|
||||
#ifdef WIND32
|
||||
#include <synchapi.h>
|
||||
#endif
|
||||
|
||||
typedef enum
|
||||
{
|
||||
COMMAND_LED_OFF = 0,
|
||||
COMMAND_LED_ON,
|
||||
COMMAND_SET_OUTPUTS,
|
||||
COMMAND_GET_OUTPUTS,
|
||||
COMMAND_EEPROM_READ,
|
||||
COMMAND_EEPROM_WRITE,
|
||||
COMMAND_GET_GITREV,
|
||||
COMMAND_GET_CHANNEL_COUNT,
|
||||
COMMAND_GET_PROTO_VERSION,
|
||||
COMMAND_SET_TRIG,
|
||||
COMMAND_GET_TRIG,
|
||||
COMMAND_GET_TRIG_COUNT
|
||||
} command_t;
|
||||
|
||||
static void msleep(uint64_t milliseconds)
|
||||
{
|
||||
#ifdef WIN32
|
||||
Sleep(milliseconds);
|
||||
#else
|
||||
struct timespec ts;
|
||||
ts.tv_sec = milliseconds / 1000;
|
||||
ts.tv_nsec = (milliseconds % 1000) * 1000000;
|
||||
nanosleep(&ts, NULL);
|
||||
#endif
|
||||
}
|
||||
|
||||
uint16_t* eismultiplexer_list_available_devices(size_t* count)
|
||||
{
|
||||
|
@ -130,6 +163,80 @@ uint16_t eismultiplexer_read_eeprom(struct eismultiplexer* muliplexer, uint16_t
|
|||
return *((uint16_t*)buffer);
|
||||
}
|
||||
|
||||
int eismultiplexer_set_trigger_state(struct eismultiplexer* muliplexer, uint16_t index, trigger_state_t state)
|
||||
{
|
||||
int ret;
|
||||
ret = usbshm_write_control_transfer(muliplexer->priv, COMMAND_SET_TRIG, NULL, 0, state, index);
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eismultiplexer_get_trigger_state(struct eismultiplexer* muliplexer, uint16_t index, trigger_state_t* state, bool* level)
|
||||
{
|
||||
uint8_t buffer[2] = {};
|
||||
int ret = usbshm_read_control_transfer(muliplexer->priv, COMMAND_GET_TRIG, 0, index, buffer, 2);
|
||||
if(ret == 2) {
|
||||
if(state)
|
||||
*state = buffer[1];
|
||||
if(level)
|
||||
*level = buffer[0];
|
||||
}
|
||||
return ret;
|
||||
}
|
||||
|
||||
int eismultiplexer_wait_trigger(struct eismultiplexer* muliplexer, uint16_t index, trigger_wait_t wait, uint64_t timeout)
|
||||
{
|
||||
bool level;
|
||||
bool prevlevel;
|
||||
int ret = eismultiplexer_get_trigger_state(muliplexer, index, NULL, &prevlevel);
|
||||
if(ret != 2)
|
||||
return ret;
|
||||
|
||||
struct timeval start;
|
||||
struct timeval current;
|
||||
gettimeofday(&start, NULL);
|
||||
gettimeofday(¤t, NULL);
|
||||
while((current.tv_sec - start.tv_sec)*1000 + (current.tv_usec - start.tv_usec)/1000 < timeout) {
|
||||
int ret = eismultiplexer_get_trigger_state(muliplexer, index, NULL, &level);
|
||||
if(ret != 2)
|
||||
return ret;
|
||||
switch(wait) {
|
||||
case TRIGGER_WAIT_HIGH_LEVEL:
|
||||
if(level)
|
||||
return 0;
|
||||
break;
|
||||
case TRIGGER_WAIT_LOW_LEVEL:
|
||||
if(!level)
|
||||
return 0;
|
||||
break;
|
||||
case TRIGGER_WAIT_EDGE:
|
||||
if(prevlevel != level)
|
||||
return 0;
|
||||
break;
|
||||
case TRIGGER_WAIT_HIGH:
|
||||
if(!prevlevel && level)
|
||||
return 0;
|
||||
break;
|
||||
case TRIGGER_WAIT_LOW:
|
||||
if(prevlevel && !level)
|
||||
return 0;
|
||||
break;
|
||||
}
|
||||
msleep(100);
|
||||
gettimeofday(¤t, NULL);
|
||||
}
|
||||
return 1;
|
||||
}
|
||||
|
||||
int eismultiplexer_get_trigger_count(struct eismultiplexer* muliplexer)
|
||||
{
|
||||
uint8_t buffer[1] = {};
|
||||
int ret = usbshm_read_control_transfer(muliplexer->priv, COMMAND_GET_TRIG, 0, 0, buffer, 1);
|
||||
if(ret >= 0)
|
||||
return buffer[0];
|
||||
else
|
||||
return 0;
|
||||
}
|
||||
|
||||
void eismultiplexer_disconnect(struct eismultiplexer* muliplexer)
|
||||
{
|
||||
usbshm_close(muliplexer->priv);
|
||||
|
|
|
@ -54,6 +54,23 @@ typedef enum {
|
|||
CHANNEL_NONE = 0,
|
||||
} channel_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRIGGER_INPUT = 0, /*** Trigger is high impedance and set as an input*/
|
||||
TRIGGER_LOW, /*** Trigger output is logic low*/
|
||||
TRIGGER_HIGH, /*** Trigger output is logic high*/
|
||||
TRIGGER_STATE_COUNT
|
||||
} trigger_state_t;
|
||||
|
||||
typedef enum
|
||||
{
|
||||
TRIGGER_WAIT_LOW = 0, /*** Waits until the trigger falls from high to low*/
|
||||
TRIGGER_WAIT_HIGH, /*** Waits until the trigger rises from low to high*/
|
||||
TRIGGER_WAIT_EDGE, /*** Waits until the trigger changes from low to high or high to low*/
|
||||
TRIGGER_WAIT_LOW_LEVEL, /*** Waits until the trigger is low*/
|
||||
TRIGGER_WAIT_HIGH_LEVEL /*** Waits until the trigger is high*/
|
||||
} trigger_wait_t;
|
||||
|
||||
struct eismultiplexer {
|
||||
struct usbshm* priv;
|
||||
};
|
||||
|
@ -113,6 +130,41 @@ channel_t eismultiplexer_get_connected(struct eismultiplexer* muliplexer);
|
|||
*/
|
||||
int eismultiplexer_set_led(struct eismultiplexer* muliplexer, bool on);
|
||||
|
||||
/**
|
||||
* @brief Sets the state of the trigger pin
|
||||
* @param multiplexer pointer to a eismultiplexer struct
|
||||
* @param state state to put the trigger in
|
||||
* @param index the index of the trigger to set
|
||||
* @return 0 on success and < 0 on failure
|
||||
*/
|
||||
int eismultiplexer_set_trigger_state(struct eismultiplexer* muliplexer, uint16_t index, trigger_state_t state);
|
||||
|
||||
/**
|
||||
* @brief Gets the logic level and state of the trigger pin
|
||||
* @param multiplexer pointer to a eismultiplexer struct
|
||||
* @param index the index of the trigger
|
||||
* @param state a pointer where the current state of the trigger will be stored, can be NULL
|
||||
* @param level a pointer where the current logic level of the trigger will be stored, only relevant if state is TRIGGER_INPUT, can be NULL
|
||||
* @return 0 on success and < 0 on failure
|
||||
*/
|
||||
int eismultiplexer_get_trigger_state(struct eismultiplexer* muliplexer, uint16_t index, trigger_state_t* state, bool* level);
|
||||
|
||||
/**
|
||||
* @brief Sets the state of the trigger pin
|
||||
* @param multiplexer pointer to a eismultiplexer struct
|
||||
* @param index the index of the trigger
|
||||
* @param wait wait type
|
||||
* @param timeout maximum time in milliseconds to wait
|
||||
* @return 0 on success and < 0 on failure
|
||||
*/
|
||||
int eismultiplexer_wait_trigger(struct eismultiplexer* muliplexer, uint16_t index, trigger_wait_t wait, uint64_t timeout);
|
||||
|
||||
/**
|
||||
* @brief gets the nummber of trigger pins available on the device
|
||||
* @return the nummber of trigger pins on success and < 0 on failure
|
||||
*/
|
||||
int eismultiplexer_get_trigger_count(struct eismultiplexer* muliplexer);
|
||||
|
||||
/**
|
||||
* @brief Gets the number of channels on the device
|
||||
* @param multiplexer pointer to an eismultiplexer struct
|
||||
|
|
40
main.c
40
main.c
|
@ -80,8 +80,9 @@ void print_commands(void)
|
|||
puts("get\t\t\t | get the state of all channels");
|
||||
puts("read [ADDRESS] [LENGTH]\t | read from the device eeprom at address");
|
||||
puts("write [ADDRESS] [LENGTH] | write to the device eeprom at address");
|
||||
puts("list | list the serial nummbers of the connected devices");
|
||||
puts("channels | get the channel of the device");
|
||||
puts("trigger [INDEX] [STATE]\t | set the trigger state input (0), output and low (1) or output and high(2)");
|
||||
puts("list\t\t\t | list the serial nummbers of the connected devices");
|
||||
puts("channels\t\t | get the number of channels the device has");
|
||||
}
|
||||
|
||||
static int process_commands(char** commands, size_t command_count, struct eismultiplexer* multiplexer, char* name)
|
||||
|
@ -160,6 +161,14 @@ static int process_commands(char** commands, size_t command_count, struct eismul
|
|||
bool connected = channels & (1 << i);
|
||||
printf("Channel %c: %s\n", (char)('A'+i), connected ? "on" : "off");
|
||||
}
|
||||
int trigger_count = eismultiplexer_get_trigger_count(multiplexer);
|
||||
for(int i = 0; i < trigger_count; ++i)
|
||||
{
|
||||
trigger_state_t state;
|
||||
bool level;
|
||||
eismultiplexer_get_trigger_state(multiplexer, i, &state, &level);
|
||||
printf("Trigger %i: state: %i level: %i\n", i, state, level);
|
||||
}
|
||||
}
|
||||
else if(strcmp(commands[0], "channels") == 0)
|
||||
{
|
||||
|
@ -187,6 +196,33 @@ static int process_commands(char** commands, size_t command_count, struct eismul
|
|||
|
||||
free(serials);
|
||||
}
|
||||
else if(strcmp(commands[0], "trigger") == 0)
|
||||
{
|
||||
if(command_count < 2)
|
||||
{
|
||||
printf("Usage %s %s [INDEX] [STATE]\n", name, commands[0]);
|
||||
return 2;
|
||||
}
|
||||
int trigger_count = eismultiplexer_get_trigger_count(multiplexer);
|
||||
long index = strtol(commands[1], NULL, 10);
|
||||
long state = strtol(commands[2], NULL, 10);
|
||||
if(state >= TRIGGER_STATE_COUNT)
|
||||
{
|
||||
printf("%li is an invalid state\n", state);
|
||||
return 2;
|
||||
}
|
||||
if(index >= trigger_count)
|
||||
{
|
||||
printf("%li is out of range as the device has only %i triggers\n", index, trigger_count);
|
||||
return 2;
|
||||
}
|
||||
int ret = eismultiplexer_set_trigger_state(multiplexer, index, state);
|
||||
if(ret < 0)
|
||||
{
|
||||
puts("Unable to set trigger state");
|
||||
return 3;
|
||||
}
|
||||
}
|
||||
else
|
||||
{
|
||||
if(command_count != 2)
|
||||
|
|
Loading…
Reference in a new issue