]> mj.ucw.cz Git - home-hw.git/commitdiff
SSR: Control program run on Turris
authorMartin Mares <mj@ucw.cz>
Thu, 9 Aug 2018 22:05:12 +0000 (22:05 +0000)
committerMartin Mares <mj@ucw.cz>
Thu, 9 Aug 2018 22:05:12 +0000 (22:05 +0000)
ssr/turris/Makefile [new file with mode: 0644]
ssr/turris/ssr-control.c [new file with mode: 0644]

diff --git a/ssr/turris/Makefile b/ssr/turris/Makefile
new file mode 100644 (file)
index 0000000..82a5498
--- /dev/null
@@ -0,0 +1,23 @@
+TOPDIR=/root/turris
+
+include $(TOPDIR)/rules.mk
+include $(TOPDIR)/include/package.mk
+
+PC := PATH=$(STAGING_DIR_HOST)/bin:$(PATH) PKG_CONFIG_PATH=$(PKG_CONFIG_PATH) PKG_CONFIG_LIBDIR=$(PKG_CONFIG_PATH) STAGING_PREFIX=$(STAGING_DIR)/usr $(PKG_CONFIG)
+USB_CFLAGS := $(shell $(PC) --cflags libusb-1.0)
+USB_LDFLAGS := $(shell $(PC) --libs libusb-1.0)
+
+export PATH=$(TARGET_PATH_PKG)
+CC=$(TARGET_CC_NOCACHE)
+LD=$(TARGET_LD_NOCACHE)
+CFLAGS=$(TARGET_CFLAGS) $(USB_CFLAGS) -std=gnu99
+LDFLAGS=$(TARGET_LDFLAGS) $(USB_LDFLAGS)
+
+all: ssr-control upload
+
+ssr-control: ssr-control.c
+
+upload:
+       rsync -av ssr-control micac:
+
+.PHONY: upload
diff --git a/ssr/turris/ssr-control.c b/ssr/turris/ssr-control.c
new file mode 100644 (file)
index 0000000..0b680a0
--- /dev/null
@@ -0,0 +1,151 @@
+/*
+ *     Control utility for the Solid State Relay module
+ *
+ *     (c) 2018 Martin Mares <mj@ucw.cz>
+ */
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdarg.h>
+#include <stdint.h>
+#include <unistd.h>
+#include <getopt.h>
+#include <time.h>
+#include <libusb-1.0/libusb.h>
+
+typedef uint8_t byte;
+typedef uint16_t u16;
+typedef uint32_t u32;
+
+struct libusb_context *usb_ctxt;
+struct libusb_device_handle *devh;
+
+static void __attribute__((noreturn)) die(char *msg, ...)
+{
+       va_list args;
+       va_start(args, msg);
+       vfprintf(stderr, msg, args);
+       fputc('\n', stderr);
+       exit(1);
+}
+
+static inline u32 get_u32_be(const void *p)
+{
+       const byte *c = (const byte *)p;
+       return (c[0] << 24) | (c[1] << 16) | (c[2] << 8) | c[3];
+}
+
+static inline void put_u32_be(void *p, u32 x)
+{
+       byte *c = (byte *)p;
+       c[0] = x >> 24;
+       c[1] = x >> 16;
+       c[2] = x >> 8;
+       c[3] = x;
+}
+
+void open_device(void)
+{
+       int err;
+       libusb_device **devlist;
+       ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
+       if (devn < 0)
+               die("Cannot enumerate USB devices: error %d", (int) devn);
+
+       for (ssize_t i=0; i<devn; i++) {
+               struct libusb_device_descriptor desc;
+               libusb_device *dev = devlist[i];
+               if (!libusb_get_device_descriptor(dev, &desc)) {
+                       if (desc.idVendor == 0x4242 && desc.idProduct == 0x0002) {
+                               printf("Found device at usb%d.%d\n", libusb_get_bus_number(dev), libusb_get_device_address(dev));
+
+                               if (err = libusb_open(dev, &devh))
+                                       die("Cannot open device: error %d", err);
+                               libusb_reset_device(devh);
+                               if (err = libusb_claim_interface(devh, 0))
+                                       die("Cannot claim interface: error %d", err);
+
+                               libusb_free_device_list(devlist, 1);
+                               return;
+                       }
+               }
+       }
+
+       libusb_free_device_list(devlist, 1);
+       die("Device not found");
+}
+
+static byte req[64], resp[64];
+
+static int transaction(uint req_len, uint resp_len)
+{
+       int err, transferred;
+       if (err = libusb_bulk_transfer(devh, 0x01, req, req_len, &transferred, 2000))
+               die("Transfer failed: error %d\n", err);
+       // printf("Transferred %d bytes\n", transferred);
+
+       int received;
+       if (err = libusb_bulk_transfer(devh, 0x82, resp, 64, &received, 2000))
+               die("Receive failed: error %d\n", err);
+       // printf("Received %d bytes\n", received);
+
+       if ((uint) received < resp_len)
+               die("Received short packet (%u out of %u bytes)", received, resp_len);
+
+       if (received >= 4) {
+               uint status = get_u32_be(resp);
+               if (status)
+                       die("Received error status %08x", status);
+       }
+
+       return received;
+}
+
+static void usage(void)
+{
+       fprintf(stderr, "Usage: ssr-control [-t] [-s <mask>]\n");
+       exit(1);
+}
+
+int main(int argc, char **argv)
+{
+       int get_temp = 0;
+       int set_relays = -1;
+
+       int opt;
+       while ((opt = getopt(argc, argv, "ts:")) >= 0) {
+               switch (opt) {
+                       case 't':
+                               get_temp = 1;
+                               break;
+                       case 's':
+                               set_relays = atoi(optarg);
+                               break;
+                       default:
+                               usage();
+               }
+       }
+       if (optind < argc)
+               usage();
+
+       int err;
+       if (err = libusb_init(&usb_ctxt))
+               die("Cannot initialize libusb: error %d", err);
+       libusb_set_debug(usb_ctxt, 3);
+       open_device();
+
+       if (get_temp) {
+               put_u32_be(req, 2);
+               transaction(8, 8);
+               int t = get_u32_be(resp+4);
+               printf("Temp: %d\n", t);
+       }
+
+       if (set_relays >= 0) {
+               put_u32_be(req, 1);
+               put_u32_be(req+4, set_relays);
+               transaction(8, 4);
+       }
+
+       return 0;
+}