aboutsummaryrefslogtreecommitdiffstats
path: root/fw
diff options
context:
space:
mode:
Diffstat (limited to 'fw')
-rw-r--r--fw/.gitignore12
-rw-r--r--fw/Makefile38
-rw-r--r--fw/config.h21
-rw-r--r--fw/eeprom.c123
-rw-r--r--fw/eeprom.h23
-rw-r--r--fw/init.c17
-rw-r--r--fw/init.h11
-rw-r--r--fw/main.c26
-rw-r--r--fw/spi.c30
-rw-r--r--fw/spi.h12
-rw-r--r--fw/sys.h9
-rw-r--r--fw/tests/system/eeprom_systest.c21
-rw-r--r--fw/types.c13
-rw-r--r--fw/types.h16
14 files changed, 372 insertions, 0 deletions
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 <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/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 <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/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 <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/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 <xc8.h>
+ * #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 <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/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 <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/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 <stdint.h>
+ * #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 <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/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 <xc.h>
+
+#include <stdint.h>
+
+#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 <stdint.h>
+ * #include "types.h"
+ */
+
+typedef uint8_t U8;
+
+typedef struct {
+ U8 lo, hi;
+} U16;
+
+void incU16(U16 *x);