aboutsummaryrefslogtreecommitdiffhomepage
path: root/backends
diff options
context:
space:
mode:
Diffstat (limited to 'backends')
-rw-r--r--backends/visca.c57
-rw-r--r--backends/visca.h1
-rw-r--r--backends/visca.md2
3 files changed, 56 insertions, 4 deletions
diff --git a/backends/visca.c b/backends/visca.c
index ba81f8d..611d142 100644
--- a/backends/visca.c
+++ b/backends/visca.c
@@ -2,7 +2,10 @@
#define DEBUG
#include <string.h>
-#include <math.h>
+#include <math.h>
+#include <sys/ioctl.h>
+#include <asm/termbits.h>
+
#include "visca.h"
#include "libmmbackend.h"
@@ -81,11 +84,41 @@ static int ptz_configure_instance(instance* inst, char* option, char* value){
LOG("Direct device connections are not possible on Windows");
return 1;
#else
- data->fd = open(value, O_NONBLOCK);
+
+ struct termios2 device_config;
+
+ options = strchr(value, ' ');
+ if(options){
+ //terminate port name
+ *options = 0;
+ options++;
+ }
+
+ data->fd = open(value, O_RDWR | O_NONBLOCK);
if(data->fd < 0){
LOGPF("Failed to connect instance %s to device %s", inst->name, value);
return 1;
}
+ data->direct_device = 1;
+
+ //configure baudrate
+ if(options){
+ //get current port config
+ if(ioctl(data->fd, TCGETS2, &device_config)){
+ LOGPF("Failed to get port configuration data for %s: %s", value, strerror(errno));
+ return 0;
+ }
+
+ device_config.c_cflag &= ~CBAUD;
+ device_config.c_cflag |= BOTHER;
+ device_config.c_ispeed = strtoul(options, NULL, 10);
+ device_config.c_ospeed = strtoul(options, NULL, 10);
+
+ //set updated config
+ if(ioctl(data->fd, TCSETS2, &device_config)){
+ LOGPF("Failed to set port configuration data for %s: %s", value, strerror(errno));
+ }
+ }
return 0;
#endif
}
@@ -315,6 +348,21 @@ static size_t ptz_set_memory_store(instance* inst, channel* c, channel_value* v,
return ptz_channels[store].bytes;
}
+static int ptz_write_serial(int fd, uint8_t* data, size_t bytes){
+ ssize_t total = 0, sent;
+
+ while(total < bytes){
+ sent = write(fd, data + total, bytes - total);
+ if(sent < 0){
+ LOGPF("Failed to write to serial port: %s", strerror(errno));
+ return 1;
+ }
+ total += sent;
+ }
+
+ return 0;
+}
+
static int ptz_set(instance* inst, size_t num, channel** c, channel_value* v){
ptz_instance_data* data = (ptz_instance_data*) inst->impl;
size_t n = 0, bytes = 0;
@@ -336,7 +384,10 @@ static int ptz_set(instance* inst, size_t num, channel** c, channel_value* v){
bytes = ptz_channels[command].set(inst, c[n], v + n, tx);
}
- if(bytes && mmbackend_send(data->fd, tx, bytes)){
+ if(data->direct_device && bytes && ptz_write_serial(data->fd, tx, bytes)){
+ LOGPF("Failed to write %s command on instance %s", ptz_channels[command].name, inst->name);
+ }
+ else if(!data->direct_device && bytes && mmbackend_send(data->fd, tx, bytes)){
LOGPF("Failed to push %s command on instance %s", ptz_channels[command].name, inst->name);
}
}
diff --git a/backends/visca.h b/backends/visca.h
index 1004076..1b8c0e5 100644
--- a/backends/visca.h
+++ b/backends/visca.h
@@ -30,6 +30,7 @@ typedef struct /*_ptz_instance_data*/ {
uint8_t tiltspeed;
uint8_t relative_movement;
double deadzone;
+ uint8_t direct_device;
} ptz_instance_data;
enum /*ptz_channels*/ {
diff --git a/backends/visca.md b/backends/visca.md
index cf5906d..101aa20 100644
--- a/backends/visca.md
+++ b/backends/visca.md
@@ -18,7 +18,7 @@ The `visca` backend does not take any global configuration.
|---------------|-----------------------|-----------------------|---------------------------------------------------------------|
| `id` | `5` | `1` | VISCA Camera address (normally 1 for network communication |
| `connect` | `10.10.10.1 5678` | none | Camera network address and port. Default connection is TCP, when optionally suffixed with the `udp` keyword, connection will be UDP |
-| `device` | `/dev/ttyUSB0` | none | (Linux only) Device node for a serial port adapter connecting to the camera |
+| `device` | `/dev/ttyUSB0 115200` | none | (Linux only) Device node for a serial port adapter connecting to the camera, optionally followed by the baudrate |
| `deadzone` | `0.1` | `0.1` | Amount of event value variation to be ignored for relative movement commands |
#### Channel specification