]> mj.ucw.cz Git - home-hw.git/blob - ssr/host/ssr-control.c
Protab: More PWM
[home-hw.git] / ssr / host / ssr-control.c
1 /*
2  *      Control utility for the Solid State Relay module
3  *
4  *      (c) 2018 Martin Mares <mj@ucw.cz>
5  */
6
7 #include <ucw/lib.h>
8 #include <ucw/unaligned.h>
9
10 #include <stdio.h>
11 #include <stdlib.h>
12 #include <stdarg.h>
13 #include <stdint.h>
14 #include <unistd.h>
15 #include <getopt.h>
16 #include <time.h>
17
18 #include <libusb-1.0/libusb.h>
19
20 struct libusb_context *usb_ctxt;
21 struct libusb_device_handle *devh;
22
23 void open_device(void)
24 {
25         int err;
26         libusb_device **devlist;
27         ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
28         if (devn < 0)
29                 die("Cannot enumerate USB devices: error %d", (int) devn);
30
31         for (ssize_t i=0; i<devn; i++) {
32                 struct libusb_device_descriptor desc;
33                 libusb_device *dev = devlist[i];
34                 if (!libusb_get_device_descriptor(dev, &desc)) {
35                         if (desc.idVendor == 0x4242 && desc.idProduct == 0x0002) {
36                                 printf("Found device at usb%d.%d\n", libusb_get_bus_number(dev), libusb_get_device_address(dev));
37
38                                 if (err = libusb_open(dev, &devh))
39                                         die("Cannot open device: error %d", err);
40                                 libusb_reset_device(devh);
41                                 if (err = libusb_claim_interface(devh, 0))
42                                         die("Cannot claim interface: error %d", err);
43
44                                 libusb_free_device_list(devlist, 1);
45                                 return;
46                         }
47                 }
48         }
49
50         libusb_free_device_list(devlist, 1);
51         die("Device not found");
52 }
53
54 static byte req[64], resp[64];
55
56 static int transaction(uint req_len, uint resp_len)
57 {
58         int err, transferred;
59         if (err = libusb_bulk_transfer(devh, 0x01, req, req_len, &transferred, 2000))
60                 die("Transfer failed: error %d\n", err);
61         // printf("Transferred %d bytes\n", transferred);
62
63         int received;
64         if (err = libusb_bulk_transfer(devh, 0x82, resp, 64, &received, 2000))
65                 die("Receive failed: error %d\n", err);
66         // printf("Received %d bytes\n", received);
67
68         if ((uint) received < resp_len)
69                 die("Received short packet (%u out of %u bytes)", received, resp_len);
70
71         if (received >= 4) {
72                 uint status = get_u32_be(resp);
73                 if (status)
74                         die("Received error status %08x", status);
75         }
76
77         return received;
78 }
79
80 static void usage(void)
81 {
82         fprintf(stderr, "Usage: ssr-control [-t] [-s <mask>]\n");
83         exit(1);
84 }
85
86 int main(int argc, char **argv)
87 {
88         int get_temp = 0;
89         int set_relays = -1;
90
91         int opt;
92         while ((opt = getopt(argc, argv, "ts:")) >= 0) {
93                 switch (opt) {
94                         case 't':
95                                 get_temp = 1;
96                                 break;
97                         case 's':
98                                 set_relays = atoi(optarg);
99                                 break;
100                         default:
101                                 usage();
102                 }
103         }
104         if (optind < argc)
105                 usage();
106
107         int err;
108         if (err = libusb_init(&usb_ctxt))
109                 die("Cannot initialize libusb: error %d", err);
110         libusb_set_debug(usb_ctxt, 3);
111         open_device();
112
113         if (get_temp) {
114                 put_u32_be(req, 2);
115                 transaction(8, 8);
116                 int t = get_u32_be(resp+4);
117                 printf("Temp: %d\n", t);
118         }
119
120         if (set_relays >= 0) {
121                 put_u32_be(req, 1);
122                 put_u32_be(req+4, set_relays);
123                 transaction(8, 4);
124         }
125
126         return 0;
127 }