From ee61ef56f775e44fd0b857a960102148910e6dce Mon Sep 17 00:00:00 2001 From: Sam Anthony Date: Sat, 16 Aug 2025 14:59:36 -0230 Subject: usbcom: modified libusb example --- fw/.gitignore | 12 ++++ fw/Makefile | 38 ++++++++++++ fw/config.h | 21 +++++++ fw/eeprom.c | 123 +++++++++++++++++++++++++++++++++++++++ fw/eeprom.h | 23 ++++++++ fw/init.c | 17 ++++++ fw/init.h | 11 ++++ fw/main.c | 26 +++++++++ fw/spi.c | 30 ++++++++++ fw/spi.h | 12 ++++ fw/sys.h | 9 +++ fw/tests/system/eeprom_systest.c | 21 +++++++ fw/types.c | 13 +++++ fw/types.h | 16 +++++ 14 files changed, 372 insertions(+) create mode 100644 fw/.gitignore create mode 100644 fw/Makefile create mode 100644 fw/config.h create mode 100644 fw/eeprom.c create mode 100644 fw/eeprom.h create mode 100644 fw/init.c create mode 100644 fw/init.h create mode 100644 fw/main.c create mode 100644 fw/spi.c create mode 100644 fw/spi.h create mode 100644 fw/sys.h create mode 100644 fw/tests/system/eeprom_systest.c create mode 100644 fw/types.c create mode 100644 fw/types.h (limited to 'fw') diff --git a/fw/.gitignore b/fw/.gitignore new file mode 100644 index 0000000..b228a86 --- /dev/null +++ b/fw/.gitignore @@ -0,0 +1,12 @@ +*.cmf +*.d +*.elf +*.hex +*.hxl +*.lst +*.o +*.p1 +*.rlf +*.s +*.sdb +*.sym diff --git a/fw/Makefile b/fw/Makefile new file mode 100644 index 0000000..b4b0ae9 --- /dev/null +++ b/fw/Makefile @@ -0,0 +1,38 @@ +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/fw/config.h b/fw/config.h new file mode 100644 index 0000000..f369673 --- /dev/null +++ b/fw/config.h @@ -0,0 +1,21 @@ +// 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/fw/eeprom.c b/fw/eeprom.c new file mode 100644 index 0000000..ce8aed7 --- /dev/null +++ b/fw/eeprom.c @@ -0,0 +1,123 @@ +#include + +#include +#include + +#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/fw/eeprom.h b/fw/eeprom.h new file mode 100644 index 0000000..07438a0 --- /dev/null +++ b/fw/eeprom.h @@ -0,0 +1,23 @@ +/* Microchip 25LC160C 2KiB EEPROM + * + * Device: PIC16F1459 + * Compiler: XC8 v3.00 + * + * Usage: + * + * #include + * #include + * #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/fw/init.c b/fw/init.c new file mode 100644 index 0000000..9c89bee --- /dev/null +++ b/fw/init.c @@ -0,0 +1,17 @@ +#include + +#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/fw/init.h b/fw/init.h new file mode 100644 index 0000000..0dc8dc3 --- /dev/null +++ b/fw/init.h @@ -0,0 +1,11 @@ +/* Device: PIC16F1459 + * Compiler: XC8 v3.00 + * + * Usage: + * + * #include + * #include "init.h" + */ + +void clockInit(void); +void pinsInit(void); diff --git a/fw/main.c b/fw/main.c new file mode 100644 index 0000000..cdc3fc2 --- /dev/null +++ b/fw/main.c @@ -0,0 +1,26 @@ +#include + +#include + +#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/fw/spi.c b/fw/spi.c new file mode 100644 index 0000000..1793c4d --- /dev/null +++ b/fw/spi.c @@ -0,0 +1,30 @@ +#include + +#include + +#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/fw/spi.h b/fw/spi.h new file mode 100644 index 0000000..1da0fcc --- /dev/null +++ b/fw/spi.h @@ -0,0 +1,12 @@ +/* Device: PIC16F1459 + * Compiler: XC8 v3.00 + * + * Usage: + * + * #include + * #include "types.h" + * #include "spi.h" + */ + +void spiInit(void); +U8 spiTx(U8 c); diff --git a/fw/sys.h b/fw/sys.h new file mode 100644 index 0000000..8a71edb --- /dev/null +++ b/fw/sys.h @@ -0,0 +1,9 @@ +/* Device: PIC16F1459 + * Compiler: XC8 v3.00 + */ + +// TRIS +enum { + OUT = 0, + IN = 1, +}; diff --git a/fw/tests/system/eeprom_systest.c b/fw/tests/system/eeprom_systest.c new file mode 100644 index 0000000..9099345 --- /dev/null +++ b/fw/tests/system/eeprom_systest.c @@ -0,0 +1,21 @@ +#include + +#include + +#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/fw/types.c b/fw/types.c new file mode 100644 index 0000000..c18392e --- /dev/null +++ b/fw/types.c @@ -0,0 +1,13 @@ +#include + +#include + +#include "types.h" + +void +incU16(U16 *x) { + x->lo++; + if (x->lo == 0u) { + x->hi++; + } +} diff --git a/fw/types.h b/fw/types.h new file mode 100644 index 0000000..22a651e --- /dev/null +++ b/fw/types.h @@ -0,0 +1,16 @@ +/* Device: PIC16F1459 + * Compiler: XC8 v3.00 + * + * Usage: + * + * #include + * #include "types.h" + */ + +typedef uint8_t U8; + +typedef struct { + U8 lo, hi; +} U16; + +void incU16(U16 *x); -- cgit v1.2.3