diff --git a/src/advancedcmd.c b/src/advancedcmd.c
new file mode 100644
index 0000000..7550960
--- /dev/null
+++ b/src/advancedcmd.c
@@ -0,0 +1,82 @@
+/*
+* advancedcmd.c - Advanced Command Interface for T-962 reflow controller
+*
+* Author: Ryan Densberger - radensb
+*
+* This program is free software: you can redistribute it and/or modify
+* it under the terms of the GNU General Public License as published by
+* the Free Software Foundation, either version 3 of the License, or
+* (at your option) any later version.
+
+* This program is distributed in the hope that it will be useful,
+* but WITHOUT ANY WARRANTY; without even the implied warranty of
+* MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
+* GNU General Public License for more details.
+
+* You should have received a copy of the GNU General Public License
+* along with this program. If not, see .
+*/
+
+#include
+#include
+#include "circbuffer.h"
+#include "serial.h"
+#include "advancedcmd.h"
+
+//chkAdvCmd - See if an Advanced Command had been sent. If a valid command is buffered,
+//read the data into the struct and return 1.
+uint8_t chkAdvCmd(tcirc_buf* buf, advancedSerialCMD* cmd) {
+ //check for a full header worth of bytes
+ if (circ_buf_count(buf) < ADVCMD_OVERHEAD) return 0;
+ //See if it is an advanced command
+ if (circ_buf_peek(buf, ADVCMD_SYNC1_LOC) == 0xFF && circ_buf_peek(buf, ADVCMD_SYNC2_LOC) == 0x55) {
+ //Check the header CRC
+ if (calcCkSum(buf, ADVCMD_OVERHEAD - 1) != circ_buf_peek(buf, ADVCMD_OVERHEAD - 1)) {
+ //header CRC failed, corrupt size byte -> flush and abort
+ circ_buf_flush(buf);
+ return 0;
+ }
+ //verify we have enough bytes buffered to verify a CRC -> if not, abort and try again next time
+ if (circ_buf_count(buf) < ((unsigned)circ_buf_peek(buf, ADVCMD_SIZE_LOC) + ADVCMD_OVERHEAD)) return 0;
+
+ //there is a full, verifyable command in the ring - lets go!
+ uart_readc(); uart_readc(); // flush the 0xFF55
+ cmd->cmdSize = uart_readc();
+ uart_readc(); // flush the valid header CRC
+ //check the CRC for the data section
+ if (calcCkSum(buf, cmd->cmdSize) != circ_buf_peek(buf, cmd->cmdSize)) {
+ //CMD in ring failed CRC -> Flush and abort
+ /*DEBUG*/
+ //printf("Calculated CRC: %02X\n", calcCkSum(buf, cmd->cmdSize));
+ //printf("Received CRC : %02X\n", circ_buf_peek(buf, cmd->cmdSize));
+ //for (int i = 0; i < cmd->cmdSize + 1; ++i) {
+ // if (i % 16 == 0) printf("\n");
+ // printf("%02X, ", circ_buf_peek(buf, i));
+ //}
+ //printf("Corrupt. Flushing...\n");
+ circ_buf_flush(buf); //corrupt
+ return 0;
+ } else {
+ //CMD in ring passed CRC -> ACK, transfer data to cmd struct, flush, and report success
+ printf("%c", ADVCMD_ACK);
+ //get CMD
+ cmd->cmd = uart_readc();
+ //Get Data
+ for (uint8_t i = 0; i < cmd->cmdSize; ++i) {
+ cmd->data[i] = uart_readc();
+ }
+ circ_buf_flush(buf); //scrub clean
+ return 1;
+ }
+ }
+ return 0;
+}
+
+//Fast and easy checksum
+uint8_t calcCkSum(tcirc_buf* buf, int length) {
+ unsigned datSum = 0;
+ for (uint8_t i = 0; i < length; ++i) {
+ datSum += circ_buf_peek(buf, i);
+ }
+ return 0x100 - (datSum & 0xFF);
+}
\ No newline at end of file
diff --git a/src/advancedcmd.h b/src/advancedcmd.h
new file mode 100644
index 0000000..733f370
--- /dev/null
+++ b/src/advancedcmd.h
@@ -0,0 +1,30 @@
+#ifndef ADVANCEDCMD_H_
+#define ADVANCEDCMD_H_
+#include "circbuffer.h"
+
+#define ADVCMD_SYNC1_LOC 0
+#define ADVCMD_SYNC2_LOC 1
+#define ADVCMD_SIZE_LOC 2
+#define ADVCMD_OVERHEAD 4
+#define ADVCMD_ACK 0x85
+
+typedef enum eAdvancedCMDs {
+ SetEEProfileCmd = 0xEE
+ //add more advcmds here...
+} advcmd_t;
+
+typedef struct {
+ uint8_t cmdSize;
+ uint8_t cmd;
+ uint8_t data[256];
+} advancedSerialCMD;
+
+typedef struct {
+ uint8_t profileNum;
+ uint16_t tempData[48];
+} EEProfileCMD;
+
+uint8_t chkAdvCmd(tcirc_buf* buf, advancedSerialCMD* cmd);
+uint8_t calcCkSum(tcirc_buf* buf, int length);
+
+#endif /*ADVANCEDCMD_H_*/
\ No newline at end of file
diff --git a/src/circbuffer.c b/src/circbuffer.c
index 834a136..ea82028 100644
--- a/src/circbuffer.c
+++ b/src/circbuffer.c
@@ -59,6 +59,26 @@ int circ_buf_has_char(tcirc_buf *cbuf) {
return (head != cbuf->tail);
}
+void circ_buf_flush(tcirc_buf * cbuf) {
+ cbuf->tail = cbuf->head;
+}
+
+char circ_buf_peek(tcirc_buf * cbuf, int offset) {
+ unsigned peekTail = cbuf->tail + offset;
+ if (peekTail >= CIRCBUFSIZE) {
+ peekTail -= CIRCBUFSIZE;
+ }
+ return cbuf->buf[peekTail];
+}
+
+char* circ_buf_getAddr(tcirc_buf * cbuf, int offset) {
+ unsigned addrTail = cbuf->tail + offset;
+ if (addrTail >= CIRCBUFSIZE) {
+ addrTail -= CIRCBUFSIZE;
+ }
+ return &cbuf->buf[addrTail];
+}
+
unsigned int circ_buf_count(tcirc_buf *cbuf) {
int count;
diff --git a/src/circbuffer.h b/src/circbuffer.h
index c873fd3..f4db591 100644
--- a/src/circbuffer.h
+++ b/src/circbuffer.h
@@ -20,6 +20,9 @@ typedef struct {
void init_circ_buf(tcirc_buf * cbuf);
void add_to_circ_buf(tcirc_buf *cbuf, char ch, int block);
int circ_buf_has_char(tcirc_buf *cbuf);
+void circ_buf_flush(tcirc_buf *cbuf);
+char circ_buf_peek(tcirc_buf * cbuf, int offset);
+char* circ_buf_getAddr(tcirc_buf * cbuf, int offset);
char get_from_circ_buf(tcirc_buf *cbuf);
unsigned int circ_buf_count(tcirc_buf *cbuf);
diff --git a/src/main.c b/src/main.c
index ed0376a..ef3d9ad 100644
--- a/src/main.c
+++ b/src/main.c
@@ -22,6 +22,7 @@
#include
#include
#include "serial.h"
+#include "advancedcmd.h"
#include "lcd.h"
#include "io.h"
#include "sched.h"
@@ -65,6 +66,10 @@ static char* help_text = \
" about Show about + debug information\n" \
" bake Enter Bake mode with setpoint\n" \
" bake