Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
82 changes: 82 additions & 0 deletions src/advancedcmd.c
Original file line number Diff line number Diff line change
@@ -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 <http://www.gnu.org/licenses/>.
*/

#include <stdint.h>
#include <stdio.h>
#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);
}
30 changes: 30 additions & 0 deletions src/advancedcmd.h
Original file line number Diff line number Diff line change
@@ -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_*/
20 changes: 20 additions & 0 deletions src/circbuffer.c
Original file line number Diff line number Diff line change
Expand Up @@ -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;

Expand Down
3 changes: 3 additions & 0 deletions src/circbuffer.h
Original file line number Diff line number Diff line change
Expand Up @@ -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);

Expand Down
72 changes: 70 additions & 2 deletions src/main.c
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@
#include <stdio.h>
#include <string.h>
#include "serial.h"
#include "advancedcmd.h"
#include "lcd.h"
#include "io.h"
#include "sched.h"
Expand Down Expand Up @@ -65,6 +66,10 @@ static char* help_text = \
" about Show about + debug information\n" \
" bake <setpoint> Enter Bake mode with setpoint\n" \
" bake <setpoint> <time> Enter Bake mode with setpoint for <time> seconds\n" \
" set OpMode <mode> Set Operational Mode (0-AMBIENT, 1-MAXTEMPOVERRIDE, 2-SPLIT)\n" \
" set OpThresh <thresh> Set MAXTEMPOVERRIDE or SPLIT mode threshold in C (0-255)\n" \
" get OpMode Get Operational Mode\n" \
" get OpThresh Get MAXTEMPOVERRIDE or SPLIT mode threshold in C\n" \
" help Display help text\n" \
" list profiles List available reflow profiles\n" \
" list settings List machine settings\n" \
Expand Down Expand Up @@ -130,6 +135,8 @@ int main(void) {
SPI_TC_Init();
Reflow_Init();
SystemFan_Init();
printf("\nCurrent Operational Mode: "); Sensor_printOpMode(); printf("\n");
printf("Current Operational Mode Threshold: %u C\n", Sensor_getOpModeThreshold());

Sched_SetWorkfunc(MAIN_WORK, Main_Work);
Sched_SetState(MAIN_WORK, 1, TICKS_SECS(2)); // Enable in 2 seconds
Expand Down Expand Up @@ -183,8 +190,44 @@ static int32_t Main_Work(void) {
char* cmd_bake = "bake %d %d";
char* cmd_dump_profile = "dump profile %d";
char* cmd_setting = "setting %d %f";

if (uart_isrxready()) {
char* cmd_setOpMode = "set OpMode %d";
char* cmd_setOpModeThresh = "set OpThresh %d";

advancedSerialCMD advCmd = { 0 };

if (uart_chkAdvCmd(&advCmd)) {
switch (advCmd.cmd) {
case SetEEProfileCmd:
{
EEProfileCMD EEcmd;
memcpy(&EEcmd, &advCmd.data, sizeof(advCmd.data));

if (EEcmd.profileNum == 1 || EEcmd.profileNum == 2) {
printf("\nSetting EE profile %d:\n ", advCmd.data[0]);
Reflow_SelectEEProfileIdx(EEcmd.profileNum);
for (unsigned char i = 0; i < NUMPROFILETEMPS; ++i) {
Reflow_SetSetpointAtIdx(i, EEcmd.tempData[i]);
}
Reflow_SaveEEProfile();
if (EEcmd.profileNum == 1) Reflow_DumpProfile(5); //CUSTOM#1
else Reflow_DumpProfile(6); //CUSTOM#2
}
else {
printf("\nOnly EEPROM profile 1 and 2 are supported for this command.\n");
}
//reset advCmd
//memset(&advCmd, 0, sizeof(advCmd));
break;
}
//Add more advanced commands here
//case ...
default: {
printf("\nUnknown Advanced Command entered.\n");
//memset(&advCmd, 0, sizeof(advCmd));
uart_rxflush();
}
}
} else if (uart_available() > 3) {
int len = uart_readline(serial_cmd, 255);

if (len > 0) {
Expand Down Expand Up @@ -238,6 +281,31 @@ static int32_t Main_Work(void) {
Sensor_ListAll();
printf("\n");

} else if (strcmp(serial_cmd, "get OpMode") == 0) {
printf("\nCurrent Operational Mode: "); Sensor_printOpMode(); printf("\n");

} else if (strcmp(serial_cmd, "get OpThresh") == 0) {
printf("\nCurrent Operational Mode Threshold: %u C\n", Sensor_getOpModeThreshold());

} else if (sscanf(serial_cmd, cmd_setOpMode, &param) > 0) {
// set operational mode
if (param > 2 || param < 0) {
printf("\nOnly options are 0-2. See Help.\n");

} else {
Sensor_setOpMode((OperationMode_t)param);
printf("\nOperational Mode Set: "); Sensor_printOpMode(); printf("\n");
}

} else if (sscanf(serial_cmd, cmd_setOpModeThresh, &param) > 0) {
// set operational mode threshold
if (param > 255 || param < 0) {
printf("\nOnly options are 0-255\n");
} else {
Sensor_setOpModeThreshold((uint8_t)param);
printf("\nOperational Mode Threshold Set: %d C\n", param);
}

} else if (sscanf(serial_cmd, cmd_select_profile, &param) > 0) {
// select profile
Reflow_SelectProfileIdx(param);
Expand Down
2 changes: 2 additions & 0 deletions src/nvstorage.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,8 @@ typedef enum eNVItem {
REFLOW_MIN_FAN_SPEED,
REFLOW_BAKE_SETPOINT_H,
REFLOW_BAKE_SETPOINT_L,
OP_MODE,
MODE_THRESH,
NVITEM_NUM_ITEMS // Last value
} NVItem_t;

Expand Down
Loading