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 /sw | |
| parent | 478a91bd82e27d8d6b2e597fd659e484ca6b205a (diff) | |
| download | can-gauge-interface-ee61ef56f775e44fd0b857a960102148910e6dce.zip | |
usbcom: modified libusb example
Diffstat (limited to 'sw')
| -rw-r--r-- | sw/.gitignore | 12 | ||||
| -rw-r--r-- | sw/Makefile | 38 | ||||
| -rw-r--r-- | sw/config.h | 21 | ||||
| -rw-r--r-- | sw/eeprom.c | 123 | ||||
| -rw-r--r-- | sw/eeprom.h | 23 | ||||
| -rw-r--r-- | sw/init.c | 17 | ||||
| -rw-r--r-- | sw/init.h | 11 | ||||
| -rw-r--r-- | sw/main.c | 26 | ||||
| -rw-r--r-- | sw/spi.c | 30 | ||||
| -rw-r--r-- | sw/spi.h | 12 | ||||
| -rw-r--r-- | sw/sys.h | 9 | ||||
| -rw-r--r-- | sw/tests/system/eeprom_systest.c | 21 | ||||
| -rw-r--r-- | sw/types.c | 13 | ||||
| -rw-r--r-- | sw/types.h | 16 | ||||
| -rw-r--r-- | sw/usbcom/Makefile | 9 | ||||
| -rw-r--r-- | sw/usbcom/usbcom.c | 188 |
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; +} |