aboutsummaryrefslogtreecommitdiffstats
path: root/sw
diff options
context:
space:
mode:
authorSam Anthony <sam@samanthony.xyz>2025-08-16 14:59:36 -0230
committerSam Anthony <sam@samanthony.xyz>2025-08-16 14:59:36 -0230
commitee61ef56f775e44fd0b857a960102148910e6dce (patch)
tree9063a6a74af17d9a0ef45392dc28eaf770a22d69 /sw
parent478a91bd82e27d8d6b2e597fd659e484ca6b205a (diff)
downloadcan-gauge-interface-ee61ef56f775e44fd0b857a960102148910e6dce.zip
usbcom: modified libusb example
Diffstat (limited to 'sw')
-rw-r--r--sw/.gitignore12
-rw-r--r--sw/Makefile38
-rw-r--r--sw/config.h21
-rw-r--r--sw/eeprom.c123
-rw-r--r--sw/eeprom.h23
-rw-r--r--sw/init.c17
-rw-r--r--sw/init.h11
-rw-r--r--sw/main.c26
-rw-r--r--sw/spi.c30
-rw-r--r--sw/spi.h12
-rw-r--r--sw/sys.h9
-rw-r--r--sw/tests/system/eeprom_systest.c21
-rw-r--r--sw/types.c13
-rw-r--r--sw/types.h16
-rw-r--r--sw/usbcom/Makefile9
-rw-r--r--sw/usbcom/usbcom.c188
16 files changed, 197 insertions, 372 deletions
diff --git a/sw/.gitignore b/sw/.gitignore
deleted file mode 100644
index b228a86..0000000
--- a/sw/.gitignore
+++ /dev/null
@@ -1,12 +0,0 @@
-*.cmf
-*.d
-*.elf
-*.hex
-*.hxl
-*.lst
-*.o
-*.p1
-*.rlf
-*.s
-*.sdb
-*.sym
diff --git a/sw/Makefile b/sw/Makefile
deleted file mode 100644
index b4b0ae9..0000000
--- a/sw/Makefile
+++ /dev/null
@@ -1,38 +0,0 @@
-CC = xc8-cc
-INCLUDES = -I./ -I/home/sam/prog/mla/v2018_11_26/framework/usb/inc
-CFLAGS = -mcpu=pic16f1459 -std=c99 $(INCLUDES) -Wall
-LDFLAGS =
-
-SYSTEST_DIR = tests/system
-
-OUT = can_gauge
-SRC = $(shell find . -name "*.c" ! -name "main.c" -maxdepth 1)
-HDR = $(wildcard *.h)
-
-OBJ = $(SRC:.c=.p1)
-HEX = $(OUT).hex
-
-SYSTEST_SRC = $(wildcard $(SYSTEST_DIR)/*.c)
-SYSTEST_OBJ = $(notdir $(SYSTEST_SRC:.c=.p1))
-SYSTEST_HEX = $(SYSTEST_OBJ:.p1=.hex)
-
-$(HEX): $(OBJ) main.p1
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
-
-%.p1: %.c
- $(CC) $(CFLAGS) -c $<
-
-$(SYSTEST_HEX): %.hex: %.p1 $(OBJ)
- $(CC) $(CFLAGS) $(LDFLAGS) -o $@ $^
-
-$(SYSTEST_OBJ): %.p1: $(SYSTEST_DIR)/%.c
- $(CC) $(CFLAGS) -c $<
-
-clean:
- rm -f $(OBJ) $(HEX) *.d *.p1 *.lst *.rlf *.o *.s *.sdb *.sym *.hxl *.elf *.cmf
-
-systest: $(SYSTEST_HEX)
-
-$(OBJ): $(HDR)
-
-.PHONY: clean systest
diff --git a/sw/config.h b/sw/config.h
deleted file mode 100644
index f369673..0000000
--- a/sw/config.h
+++ /dev/null
@@ -1,21 +0,0 @@
-// CONFIG1
-#pragma config FOSC = INTOSC // Oscillator Selection Bits (INTOSC oscillator: I/O function on CLKIN pin)
-#pragma config WDTE = OFF // Watchdog Timer Enable (WDT disabled)
-#pragma config PWRTE = OFF // Power-up Timer Enable (PWRT disabled)
-#pragma config MCLRE = ON // MCLR Pin Function Select (MCLR pin is MCLR)
-#pragma config CP = OFF // Flash Program Memory Code Protection (Program memory code protection is disabled)
-#pragma config BOREN = ON // Brown-out Reset Enable (Brown-out Reset enabled)
-#pragma config CLKOUTEN = OFF // Clock Out Enable (CLKOUT function is disabled. I/O or oscillator function on the CLKOUT pin)
-#pragma config IESO = OFF // Internal/External Switchover Mode (Internal/External Switchover Mode is disabled)
-#pragma config FCMEN = OFF // Fail-Safe Clock Monitor Enable (Fail-Safe Clock Monitor is disabled)
-
-// CONFIG2
-#pragma config WRT = OFF // Flash Memory Self-Write Protection (Write protection off)
-#pragma config CPUDIV = NOCLKDIV// CPU System Clock Selection Bit (NO CPU system divide)
-#pragma config USBLSCLK = 48MHz // USB Low SPeed Clock Selection bit (System clock expects 48 MHz, FS/LS USB CLKENs divide-by is set to 8.)
-#pragma config PLLMULT = 3x // PLL Multipler Selection Bit (3x Output Frequency Selected)
-#pragma config PLLEN = ENABLED // PLL Enable Bit (3x or 4x PLL Enabled)
-#pragma config STVREN = ON // Stack Overflow/Underflow Reset Enable (Stack Overflow or Underflow will cause a Reset)
-#pragma config BORV = LO // Brown-out Reset Voltage Selection (Brown-out Reset Voltage (Vbor), low trip point selected.)
-#pragma config LPBOR = OFF // Low-Power Brown Out Reset (Low-Power BOR is disabled)
-#pragma config LVP = ON // Low-Voltage Programming Enable
diff --git a/sw/eeprom.c b/sw/eeprom.c
deleted file mode 100644
index ce8aed7..0000000
--- a/sw/eeprom.c
+++ /dev/null
@@ -1,123 +0,0 @@
-#include <xc.h>
-
-#include <stdbool.h>
-#include <stdint.h>
-
-#include "sys.h"
-#include "types.h"
-#include "spi.h"
-
-#include "eeprom.h"
-
-// 16-byte page ('C' variant)
-#define PAGE_SIZE 16u
-
-// Commands
-enum {
- CMD_READ = 0x03,
- CMD_WRITE = 0x02,
- CMD_WRITE_DISABLE = 0x04,
- CMD_WRITE_ENABLE = 0x06,
- CMD_READ_STATUS = 0x05,
- CMD_WRITE_STATUS = 0x01,
-};
-
-// Status register masks
-enum {
- STATUS_WIP = 0x1, // write in progress
- STATUS_WEL = 0x2, // write enable latch
- STATUS_BP0 = 0x4, // block protection 0
- STATUS_BP1 = 0x8, // block protection 1
-};
-
-// Timing
-enum {
- TIME_WRITE_CYCLE_MS = 5,
-};
-
-void
-eepromInit(void) {
- EEPROM_CS_TRIS = OUT;
- EEPROM_CS = 1;
-
- eepromWriteDisable();
-}
-
-void
-eepromWriteEnable(void) {
- EEPROM_CS = 0;
- (void)spiTx(CMD_WRITE_ENABLE);
- EEPROM_CS = 1;
-}
-
-void
-eepromWriteDisable(void) {
- EEPROM_CS = 0;
- (void)spiTx(CMD_WRITE_DISABLE);
- EEPROM_CS = 1;
-}
-
-static bool
-isWriteInProgress(void) {
- U8 status;
-
- EEPROM_CS = 0;
- (void)spiTx(CMD_READ_STATUS);
- status = spiTx(0x00);
- EEPROM_CS = 1;
- return status & STATUS_WIP;
-}
-
-static void
-spiTxAddr(U16 addr) {
- (void)spiTx(addr.hi);
- (void)spiTx(addr.lo);
-}
-
-static bool
-isPageStart(U16 addr) {
- return (addr.lo % PAGE_SIZE) == 0;
-}
-
-void
-eepromWrite(U16 addr, U8 *data, U8 size) {
- while (isWriteInProgress()) {} // wait for previous write to finish
-
- EEPROM_CS = 0; // pull chip-select low
-
- (void)spiTx(CMD_WRITE);
- spiTxAddr(addr);
- while (size--) {
- (void)spiTx(*data);
- data++;
- incU16(&addr);
-
- // Check if write crosses page boundary
- if (isPageStart(addr) && size) {
- // Write current page to memory
- EEPROM_CS = 1;
- while (isWriteInProgress()) {}
- EEPROM_CS = 0;
-
- // Start next page
- (void)spiTx(CMD_WRITE);
- spiTxAddr(addr);
- }
- }
-
- EEPROM_CS = 1; // release chip-select
-}
-
-void
-eepromRead(U16 addr, U8 *data, U8 size) {
- EEPROM_CS = 0; // pull chip-select low
-
- (void)spiTx(CMD_READ);
- spiTxAddr(addr);
- while (size--) {
- *data = spiTx(0x00);
- data++;
- }
-
- EEPROM_CS = 1; // release chip-select
-}
diff --git a/sw/eeprom.h b/sw/eeprom.h
deleted file mode 100644
index 07438a0..0000000
--- a/sw/eeprom.h
+++ /dev/null
@@ -1,23 +0,0 @@
-/* Microchip 25LC160C 2KiB EEPROM
- *
- * Device: PIC16F1459
- * Compiler: XC8 v3.00
- *
- * Usage:
- *
- * #include <xc.h>
- * #include <stdint.h>
- * #include "types.h"
- * #include "spi.h"
- * #include "eeprom.h"
- */
-
-// Pin mapping
-#define EEPROM_CS_TRIS TRISAbits.TRISA5
-#define EEPROM_CS LATAbits.LATA5
-
-void eepromInit(void);
-void eepromWriteEnable(void);
-void eepromWriteDisable(void);
-void eepromWrite(U16 addr, U8 data[], U8 size);
-void eepromRead(U16 addr, U8 data[], U8 size);
diff --git a/sw/init.c b/sw/init.c
deleted file mode 100644
index 9c89bee..0000000
--- a/sw/init.c
+++ /dev/null
@@ -1,17 +0,0 @@
-#include <xc.h>
-
-#include "init.h"
-
-void
-clockInit(void) {
- OSCCON = 0xFC; // HFINTOSC @ 16MHz, 3x PLL, PLL enabled
- ACTCON = 0x90; // active clock tuning enabled for USB
-}
-
-void
-pinsInit(void) {
- // Disable all analog pin functions
- ANSELA = 0;
- ANSELB = 0;
- ANSELC = 0;
-}
diff --git a/sw/init.h b/sw/init.h
deleted file mode 100644
index 0dc8dc3..0000000
--- a/sw/init.h
+++ /dev/null
@@ -1,11 +0,0 @@
-/* Device: PIC16F1459
- * Compiler: XC8 v3.00
- *
- * Usage:
- *
- * #include <xc8.h>
- * #include "init.h"
- */
-
-void clockInit(void);
-void pinsInit(void);
diff --git a/sw/main.c b/sw/main.c
deleted file mode 100644
index cdc3fc2..0000000
--- a/sw/main.c
+++ /dev/null
@@ -1,26 +0,0 @@
-#include <xc.h>
-
-#include <stdint.h>
-
-#include "types.h"
-#include "init.h"
-#include "spi.h"
-#include "eeprom.h"
-#include "config.h"
-
-void
-main(void) {
- clockInit();
- pinsInit();
- spiInit();
- eepromInit();
-
- for (;;) {
-
- }
-}
-
-void
-__interrupt() isr(void) {
-
-}
diff --git a/sw/spi.c b/sw/spi.c
deleted file mode 100644
index 1793c4d..0000000
--- a/sw/spi.c
+++ /dev/null
@@ -1,30 +0,0 @@
-#include <xc.h>
-
-#include <stdint.h>
-
-#include "sys.h"
-#include "types.h"
-
-#include "spi.h"
-
-void
-spiInit(void) {
- U8 junk;
-
- TRISBbits.TRISB4 = IN; // SDI
- TRISCbits.TRISC7 = OUT; // SDO
- TRISBbits.TRISB6 = OUT; // SCK
-
- SSPSTAT = 0x00;
- SSPCON1 = 0x01; // FOSC/16 => 3MHz SPI clock
- SSPCON1bits.SSPEN = 1; // enable
- junk = SSPBUF; // dummy read to clear BF
- (void)junk;
-}
-
-U8
-spiTx(U8 c) {
- SSPBUF = c;
- while (!SSPSTATbits.BF) {}
- return SSPBUF;
-}
diff --git a/sw/spi.h b/sw/spi.h
deleted file mode 100644
index 1da0fcc..0000000
--- a/sw/spi.h
+++ /dev/null
@@ -1,12 +0,0 @@
-/* Device: PIC16F1459
- * Compiler: XC8 v3.00
- *
- * Usage:
- *
- * #include <stdint.h>
- * #include "types.h"
- * #include "spi.h"
- */
-
-void spiInit(void);
-U8 spiTx(U8 c);
diff --git a/sw/sys.h b/sw/sys.h
deleted file mode 100644
index 8a71edb..0000000
--- a/sw/sys.h
+++ /dev/null
@@ -1,9 +0,0 @@
-/* Device: PIC16F1459
- * Compiler: XC8 v3.00
- */
-
-// TRIS
-enum {
- OUT = 0,
- IN = 1,
-};
diff --git a/sw/tests/system/eeprom_systest.c b/sw/tests/system/eeprom_systest.c
deleted file mode 100644
index 9099345..0000000
--- a/sw/tests/system/eeprom_systest.c
+++ /dev/null
@@ -1,21 +0,0 @@
-#include <xc.h>
-
-#include <stdint.h>
-
-#include "types.h"
-#include "init.h"
-#include "spi.h"
-#include "eeprom.h"
-#include "config.h"
-
-void
-main(void) {
- clockInit();
- pinsInit();
- spiInit();
- eepromInit();
-
- for (;;) {
-
- }
-}
diff --git a/sw/types.c b/sw/types.c
deleted file mode 100644
index c18392e..0000000
--- a/sw/types.c
+++ /dev/null
@@ -1,13 +0,0 @@
-#include <xc.h>
-
-#include <stdint.h>
-
-#include "types.h"
-
-void
-incU16(U16 *x) {
- x->lo++;
- if (x->lo == 0u) {
- x->hi++;
- }
-}
diff --git a/sw/types.h b/sw/types.h
deleted file mode 100644
index 22a651e..0000000
--- a/sw/types.h
+++ /dev/null
@@ -1,16 +0,0 @@
-/* Device: PIC16F1459
- * Compiler: XC8 v3.00
- *
- * Usage:
- *
- * #include <stdint.h>
- * #include "types.h"
- */
-
-typedef uint8_t U8;
-
-typedef struct {
- U8 lo, hi;
-} U16;
-
-void incU16(U16 *x);
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;
+}