]> mj.ucw.cz Git - home-hw.git/commitdiff
test-shutters: USB interface via control requests
authorMartin Mares <mj@ucw.cz>
Sat, 22 Jul 2023 16:35:45 +0000 (18:35 +0200)
committerMartin Mares <mj@ucw.cz>
Sat, 22 Jul 2023 16:35:45 +0000 (18:35 +0200)
test-shutters/config.h
test-shutters/host/Makefile [new file with mode: 0644]
test-shutters/host/test.c [new file with mode: 0644]
test-shutters/main.c

index fe39e28caa5bf33ab643ffbcdd5e1ce978ff10e1..312c7beeca7f3bfd15953990be38c0d02ffe7fbf 100644 (file)
@@ -12,7 +12,3 @@
 
 #define DEBUG_USART USART1
 #define DEBUG_LED_BLUEPILL
-
-// Testing of IR receiver
-
-#undef IR_TEST
diff --git a/test-shutters/host/Makefile b/test-shutters/host/Makefile
new file mode 100644 (file)
index 0000000..5e6e00c
--- /dev/null
@@ -0,0 +1,12 @@
+UCWCF:=$(shell PKG_CONFIG_PATH=$(LIBUCW)/lib/pkgconfig pkg-config --cflags libucw)
+UCWLF:=$(shell PKG_CONFIG_PATH=$(LIBUCW)/lib/pkgconfig pkg-config --libs libucw)
+
+CFLAGS=-std=gnu99 -O2 -Wall -Wextra -Wno-parentheses $(UCWCF)
+LDLIBS=-lusb-1.0 $(UCWLF)
+
+all: test
+
+test: test.c
+
+clean:
+       rm -f test
diff --git a/test-shutters/host/test.c b/test-shutters/host/test.c
new file mode 100644 (file)
index 0000000..5462fe5
--- /dev/null
@@ -0,0 +1,75 @@
+#include <ucw/lib.h>
+#include <ucw/unaligned.h>
+
+#include <stdio.h>
+#include <stdlib.h>
+#include <stdint.h>
+#include <string.h>
+#include <unistd.h>
+#include <time.h>
+#include <libusb-1.0/libusb.h>
+
+struct libusb_context *usb_ctxt;
+struct libusb_device_handle *devh;
+
+static libusb_device *find_device(void)
+{
+  libusb_device **devlist;
+  ssize_t devn = libusb_get_device_list(usb_ctxt, &devlist);
+  if (devn < 0)
+    {
+      fprintf(stderr, "Cannot enumerate USB devices: error %d\n", (int) devn);
+      exit(1);
+    }
+
+  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 == 0x0007)
+           {
+             printf("Found device at usb%d.%d\n", libusb_get_bus_number(dev), libusb_get_device_address(dev));
+             // FIXME: Free device list
+             return dev;
+           }
+       }
+    }
+
+  libusb_free_device_list(devlist, 1);
+  fprintf(stderr, "Device not found\n");
+  exit(1);
+}
+
+int main(void)
+{
+  int err;
+  if (err = libusb_init(&usb_ctxt))
+    die("Cannot initialize libusb: error %d", err);
+  // libusb_set_debug(usb_ctxt, 3);
+
+  libusb_device *dev = find_device();
+
+  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);
+
+  byte buf[64];
+  uint ssr = 0;
+  if ((err = libusb_control_transfer(devh, LIBUSB_ENDPOINT_OUT | LIBUSB_REQUEST_TYPE_VENDOR, 1, ssr, 0, buf, 0, 1000)) < 0)
+    die("Control transfer failed: error %d", err);
+
+  for (;;)
+    {
+      memset(buf, 0, 8);
+      if ((err = libusb_control_transfer(devh, LIBUSB_ENDPOINT_IN | LIBUSB_REQUEST_TYPE_VENDOR, 0, 0, 0, buf, 8, 1000)) != 8)
+       die("Control transfer failed: error %d", err);
+      printf("counters: %u %u\n", get_u32_le(buf), get_u32_le(buf+4));
+      sleep(1);
+    }
+
+  return 0;
+}
index 275b9ba7860d00b78ad4fed9633f08361efb006a..fd7b72858ac390d87fb3bcc5a7c9b952c27fa42d 100644 (file)
@@ -131,27 +131,17 @@ static const struct usb_device_descriptor device = {
        .bNumConfigurations = 1,
 };
 
-static const struct usb_endpoint_descriptor endpoints[] = {{
-       // Bulk end-point for sending values to the display
-       .bLength = USB_DT_ENDPOINT_SIZE,
-       .bDescriptorType = USB_DT_ENDPOINT,
-       .bEndpointAddress = 0x01,
-       .bmAttributes = USB_ENDPOINT_ATTR_BULK,
-       .wMaxPacketSize = 64,
-       .bInterval = 1,
-}};
-
 static const struct usb_interface_descriptor iface = {
        .bLength = USB_DT_INTERFACE_SIZE,
        .bDescriptorType = USB_DT_INTERFACE,
        .bInterfaceNumber = 0,
        .bAlternateSetting = 0,
-       .bNumEndpoints = 1,
+       .bNumEndpoints = 0,
        .bInterfaceClass = 0xFF,
        .bInterfaceSubClass = 0,
        .bInterfaceProtocol = 0,
        .iInterface = 0,
-       .endpoint = endpoints,
+       .endpoint = NULL,
 };
 
 static const struct usb_dfu_descriptor dfu_function = {
@@ -201,6 +191,8 @@ static const struct usb_config_descriptor config = {
 static byte usb_configured;
 static uint8_t usbd_control_buffer[64];
 
+uint csense_counters[2] = { 0, 0 };
+
 static void dfu_detach_complete(usbd_device *dev UNUSED, struct usb_setup_data *req UNUSED)
 {
        // Reset to bootloader, which implements the rest of DFU
@@ -222,22 +214,69 @@ static enum usbd_request_return_codes dfu_control_cb(usbd_device *dev UNUSED,
        return USBD_REQ_HANDLED;
 }
 
-static void ep01_cb(usbd_device *dev, uint8_t ep UNUSED)
+static enum usbd_request_return_codes control_cb(
+       usbd_device *dev UNUSED,
+       struct usb_setup_data *req,
+       uint8_t **buf,
+       uint16_t *len,
+       void (**complete)(usbd_device *dev, struct usb_setup_data *req) UNUSED)
 {
-       // We received a frame from the USB host
-       byte buf[8];
-       uint len = usbd_ep_read_packet(dev, 0x01, buf, 8);
-       debug_printf("USB: Host sent %u bytes\n", len);
+       uint index = req->wIndex;
+       uint value = req->wValue;
+
+       if (req->bmRequestType == (USB_REQ_TYPE_IN | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) {
+               debug_printf("Control request IN %02x (index=%d, len=%d)\n", req->bRequest, index, *len);
+
+               const byte *reply = NULL;
+               uint reply_len = 0;
+
+               switch (req->bRequest) {
+                       case 0:
+                               reply = (const byte *) &csense_counters;
+                               reply_len = sizeof(csense_counters);
+                               break;
+                       default:
+                               return USBD_REQ_NOTSUPP;
+               }
+
+               uint n = MIN(*len, reply_len);
+               memcpy(*buf, reply, n);
+               *len = n;
+               return USBD_REQ_HANDLED;
+       } else if (req->bmRequestType == (USB_REQ_TYPE_OUT | USB_REQ_TYPE_VENDOR | USB_REQ_TYPE_DEVICE)) {
+               debug_printf("Control request OUT %02x (index=%d, val=%d, len=%d)\n", req->bRequest, index, value, *len);
+
+               switch (req->bRequest) {
+                       case 1:
+                               if (*len != 0)
+                                       return USBD_REQ_NOTSUPP;
+                               if (value & 1)
+                                       gpio_clear(GPIOB, GPIO6);
+                               else
+                                       gpio_set(GPIOB, GPIO6);
+                               break;
+                       default:
+                               return USBD_REQ_NOTSUPP;
+               }
+
+               return USBD_REQ_HANDLED;
+       } else {
+               return USBD_REQ_NOTSUPP;
+       }
 }
 
 static void set_config_cb(usbd_device *dev, uint16_t wValue UNUSED)
 {
+       usbd_register_control_callback(
+               dev,
+               USB_REQ_TYPE_VENDOR,
+               USB_REQ_TYPE_TYPE,
+               control_cb);
        usbd_register_control_callback(
                dev,
                USB_REQ_TYPE_CLASS | USB_REQ_TYPE_INTERFACE,
                USB_REQ_TYPE_TYPE | USB_REQ_TYPE_RECIPIENT,
                dfu_control_cb);
-       usbd_ep_setup(dev, 0x01, USB_ENDPOINT_ATTR_BULK, 64, ep01_cb);
        usb_configured = 1;
 }
 
@@ -300,17 +339,15 @@ int main(void)
        usb_init();
 
        u32 last_blink = 0;
-       uint csense[2] = { 0, 0 };
 
        for (;;) {
                if (ms_ticks - last_blink >= 1000) {
                        debug_led_toggle();
                        last_blink = ms_ticks;
-                       debug_printf("C: %u %u\n", csense[0], csense[1]);
-                       csense[0] = csense[1] = 0;
+                       debug_printf("C: %u %u\n", csense_counters[0], csense_counters[1]);
                }
 
-               csense[gpio_get(GPIOA, GPIO0)]++;
+               csense_counters[gpio_get(GPIOA, GPIO0)]++;
 
                if (usart_get_flag(USART1, USART_SR_RXNE)) {
                        uint ch = usart_recv(USART1);