diff options
| author | Sam Anthony <sam@samanthony.xyz> | 2025-08-16 14:59:36 -0230 |
|---|---|---|
| committer | Sam Anthony <sam@samanthony.xyz> | 2025-08-16 14:59:36 -0230 |
| commit | ee61ef56f775e44fd0b857a960102148910e6dce (patch) | |
| tree | 9063a6a74af17d9a0ef45392dc28eaf770a22d69 | |
| parent | 478a91bd82e27d8d6b2e597fd659e484ca6b205a (diff) | |
| download | can-gauge-interface-ee61ef56f775e44fd0b857a960102148910e6dce.zip | |
usbcom: modified libusb example
| -rw-r--r-- | .gitignore | 1 | ||||
| -rw-r--r-- | fw/.gitignore (renamed from sw/.gitignore) | 0 | ||||
| -rw-r--r-- | fw/Makefile (renamed from sw/Makefile) | 0 | ||||
| -rw-r--r-- | fw/config.h (renamed from sw/config.h) | 0 | ||||
| -rw-r--r-- | fw/eeprom.c (renamed from sw/eeprom.c) | 0 | ||||
| -rw-r--r-- | fw/eeprom.h (renamed from sw/eeprom.h) | 0 | ||||
| -rw-r--r-- | fw/init.c (renamed from sw/init.c) | 0 | ||||
| -rw-r--r-- | fw/init.h (renamed from sw/init.h) | 0 | ||||
| -rw-r--r-- | fw/main.c (renamed from sw/main.c) | 0 | ||||
| -rw-r--r-- | fw/spi.c (renamed from sw/spi.c) | 0 | ||||
| -rw-r--r-- | fw/spi.h (renamed from sw/spi.h) | 0 | ||||
| -rw-r--r-- | fw/sys.h (renamed from sw/sys.h) | 0 | ||||
| -rw-r--r-- | fw/tests/system/eeprom_systest.c (renamed from sw/tests/system/eeprom_systest.c) | 0 | ||||
| -rw-r--r-- | fw/types.c (renamed from sw/types.c) | 0 | ||||
| -rw-r--r-- | fw/types.h (renamed from sw/types.h) | 0 | ||||
| -rw-r--r-- | sw/usbcom/Makefile | 9 | ||||
| -rw-r--r-- | sw/usbcom/usbcom.c | 188 |
17 files changed, 198 insertions, 0 deletions
@@ -3,3 +3,4 @@ *.aux *.png *.bak +usbcom diff --git a/sw/.gitignore b/fw/.gitignore index b228a86..b228a86 100644 --- a/sw/.gitignore +++ b/fw/.gitignore diff --git a/sw/Makefile b/fw/Makefile index b4b0ae9..b4b0ae9 100644 --- a/sw/Makefile +++ b/fw/Makefile diff --git a/sw/config.h b/fw/config.h index f369673..f369673 100644 --- a/sw/config.h +++ b/fw/config.h diff --git a/sw/eeprom.c b/fw/eeprom.c index ce8aed7..ce8aed7 100644 --- a/sw/eeprom.c +++ b/fw/eeprom.c diff --git a/sw/eeprom.h b/fw/eeprom.h index 07438a0..07438a0 100644 --- a/sw/eeprom.h +++ b/fw/eeprom.h diff --git a/sw/tests/system/eeprom_systest.c b/fw/tests/system/eeprom_systest.c index 9099345..9099345 100644 --- a/sw/tests/system/eeprom_systest.c +++ b/fw/tests/system/eeprom_systest.c diff --git a/sw/usbcom/Makefile b/sw/usbcom/Makefile new file mode 100644 index 0000000..e496736 --- /dev/null +++ b/sw/usbcom/Makefile @@ -0,0 +1,9 @@ +CC = tcc +CFLAGS = -std=c99 -Wall +LDFLAGS = -lusb-1.0 + +usbcom: usbcom.c + $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^ + +clean: + rm usbcom diff --git a/sw/usbcom/usbcom.c b/sw/usbcom/usbcom.c new file mode 100644 index 0000000..55ee395 --- /dev/null +++ b/sw/usbcom/usbcom.c @@ -0,0 +1,188 @@ +#include <assert.h> +#include <stdio.h> +#include <stdlib.h> +#include <string.h> +#include <unistd.h> + +#include <libusb-1.0/libusb.h> + +#define VENDOR_ID 0x04d8 +#define PRODUCT_ID 0x000a + +#define ACM_CTRL_DTR 0x01 +#define ACM_CTRL_RTS 0x02 + +#define TIMEOUT 1000 + +#define BUF_SIZE 64 + +// line encoding: 9600 8N1 +// 9600 = 0x2580 LE +static unsigned char encoding[] = {0x80, 0x25, 0x00, 0x00, 0x00, 0x00, 0x08}; + +static struct libusb_device_handle *devh = NULL; + +static int ep_in_addr = 0x82; +static int ep_out_addr = 0x02; + +// Returns 0 on success +static int +setup(void) { + int res; + + res = libusb_init(NULL); + if (res < 0) { + fprintf(stderr, "Error initializing libusb: %s\n", libusb_error_name(res)); + return -1; + } + + libusb_set_debug(NULL, 3); + + devh = libusb_open_device_with_vid_pid(NULL, VENDOR_ID, PRODUCT_ID); + if (!devh) { + fprintf(stderr, "Error finding USB device\n"); + return -1; + } + + for (int ifNum = 0; ifNum < 2; ifNum++) { + if (libusb_kernel_driver_active(devh, ifNum)) { + libusb_detach_kernel_driver(devh, ifNum); + } + res = libusb_claim_interface(devh, ifNum); + if (res < 0) { + fprintf(stderr, "error claiming interface: %s\n", libusb_error_name(res)); + return -1; + } + } + + res = libusb_control_transfer(devh, 0x21, 0x22, ACM_CTRL_DTR | ACM_CTRL_RTS, 0, NULL, 0, 0); + if (res < 0) { + fprintf(stderr, "Error during control transfer: %s\n", libusb_error_name(res)); + return -1; + } + + res = libusb_control_transfer(devh, 0x21, 0x20, 0, 0, encoding, sizeof(encoding), 0); + if (res < 0) { + fprintf(stderr, "Error during control transfer: %s\n", libusb_error_name(res)); + return -1; + } + + return 0; +} + +static void +teardown(void) { + if (devh) { + libusb_close(devh); + } + libusb_exit(NULL); +} + +// Send bytes to USB +static void +txChars(unsigned char *data, int n) { + int actualLen, res; + + actualLen = 0; + while (actualLen < n) { + res = libusb_bulk_transfer(devh, ep_out_addr, data, n, &actualLen, TIMEOUT); + if (res == LIBUSB_ERROR_TIMEOUT) { + printf("Timeout (%d)\n", actualLen); + } else if (res < 0) { + fprintf(stderr, "Error sending data\n"); + } + assert(actualLen <= n); + n -= actualLen; + data += actualLen; + } +} + +// Read data from USB +// Returns number of bytes read, or -1 on error +static int +rxChars(unsigned char *data, int size) { + int res, actualLen; + + res = libusb_bulk_transfer(devh, ep_in_addr, data, size, &actualLen, TIMEOUT); + if (res == LIBUSB_ERROR_TIMEOUT) { + fprintf(stderr, "Timeout\n"); + return -1; + } else if (res < 0) { + fprintf(stderr, "Error receiving data\n"); + return -1; + } + return actualLen; +} + +// Get line from stdin +// Includes '\n' +// Returns number of chars prior to NUL, or EOF on end of file or error +static int +scanline(char *buf, size_t size) { + int c, n; + + c = '\0'; + n = 0; + while (n+1 < size) { + c = getchar(); + if (c == EOF) { + break; + } + buf[n++] = c; + if (c == '\n') { + break; + } + } + + if (size > 0) { + buf[n] = '\0'; + } + + return ((c == EOF) && (n < 1)) ? EOF : n; +} + +static void +sendCommand(void) { + unsigned char buf[BUF_SIZE]; + int len; + + while ((len = scanline(buf, sizeof(buf))) != EOF) { + txChars(buf, len); + if (len > 0 && buf[len-1] == '\n') { + break; + } + } +} + +static void +printResponse(void) { + unsigned char buf[BUF_SIZE]; + int len; + + while ((len = rxChars(buf, sizeof(buf)-1)) >= 0) { + buf[len] = '\0'; + printf("%s", buf); + if (buf[len] == '\n') { + return; + } + } +} + +int +main(int argc, char *argv[]) { + int res; + if ((res = setup()) != 0) { + teardown(); + return res; + } + + for (;;) { + sendCommand(); + printResponse(); + } + + libusb_release_interface(devh, 0); + + teardown(); + return 0; +} |