Major changes - refactoring the AVRInterface class to take on more responsibility.

This commit is contained in:
2026-01-25 21:39:10 -06:00
parent 30f4047b7c
commit 152e0c2d80
3 changed files with 858 additions and 82 deletions

View File

@@ -11,7 +11,8 @@
#include <time.h>
#include <timeapi.h>
#include "SerialPort\SerialPort.h"
#include "AVRCommandDecoder.h"
#include "AVRInterface.h"
//#include "AVRCommandDecoder.h"
#include "ConsoleHandler.h"
enum
@@ -20,12 +21,14 @@ enum
COM_MIN_PORT = 1,
COM_MAX_PORT = 99
};
CSerialPort avr;
CSerialPort avrPort;
int avrOnPort = COM_NO_PORT; // Serial Port 1, 2, ... taking note that some USB adapters can be up toward channel 11, 12, ...
unsigned avrBaud = 9600;
const uint32_t retryInterval = 1000; // ms
AVRInterface *avr;
// Each DT is the hex-character from the stream
//
//
@@ -176,7 +179,7 @@ typedef struct {
} AVR_Configuration_T;
// 264 total
typedef struct {
uint8_t type[5]; // Model ID
uint8_t version; // A-Z
@@ -224,7 +227,7 @@ bool SerialSend(const uint8_t *p, uint16_t len);
// Just big enough to hold an OSD message which is a 1 message command, 4 messages with text
#define SERIALQUEUESIZE 5
typedef struct {
uint8_t *messageToSend;
uint8_t *message;
uint16_t len;
} SerialQueue_T;
@@ -250,11 +253,13 @@ bool ProcessSerialQueue(const uint8_t *p = NULL, uint16_t len = 0);
//
// @returns true if a message was processed.
//
bool ProcessSerialReceive(void);
SerialQueue_T ProcessSerialReceive(void);
void HandleMessage(uint8_t *szBuffer, uint32_t num);
void EnumerateComPorts();
unsigned long Hex2Dec(uint8_t *p, int dig);
void ShowAllStatusInfo();
//void ShowAllStatusInfo();
bool UserWantsToExitCanSniff = false;
DWORD progStartTime_ms;
@@ -330,6 +335,7 @@ void UserCommandsSanityCheck() {
}
}
#if 0
// rCmd: 2-ASCII Hex Bytes converted to uint8_t
// configOffset: offset into avrStatus.config.DTxx
// numToTransfer: number of bytes to transfer from message to config (0 = none)
@@ -484,7 +490,7 @@ void MessageHandlerSanityCheck() {
exit(EXIT_ConfigError);
}
}
#endif
int CS_KeyHit() {
int h = _kbhit();
@@ -580,7 +586,7 @@ bool SerialSend(const uint8_t *p, uint16_t len) {
Console_SetCursor(0, -1);
EmitBuffer("> ", p, len);
Console_ScrollBottomRegion();
if (avr.Write((const LPVOID)p, len) == len) {
if (avrPort.Write((const LPVOID)p, len) == len) {
retVal = true;
} else {
Console_SetCursor(0, -1);
@@ -596,9 +602,9 @@ bool ProcessSerialQueue(const uint8_t *p, uint16_t len) {
if (p && len) {
if (serialQueueCount < SERIALQUEUESIZE) {
serialQueue[serialQueueCount].messageToSend = (uint8_t *)malloc(len);
if (serialQueue[serialQueueCount].messageToSend) {
memcpy(serialQueue[serialQueueCount].messageToSend, p, len);
serialQueue[serialQueueCount].message = (uint8_t *)malloc(len);
if (serialQueue[serialQueueCount].message) {
memcpy(serialQueue[serialQueueCount].message, p, len);
serialQueue[serialQueueCount].len = len;
serialQueueCount++;
retVal = true;
@@ -607,9 +613,9 @@ bool ProcessSerialQueue(const uint8_t *p, uint16_t len) {
}
}
if (serialQueueCount) {
if (SerialSend((const uint8_t *)serialQueue[0].messageToSend, serialQueue[0].len)) {
if (SerialSend((const uint8_t *)serialQueue[0].message, serialQueue[0].len)) {
--serialQueueCount;
free(serialQueue[0].messageToSend);
free(serialQueue[0].message);
for (int i = 0; i < serialQueueCount; i++) {
serialQueue[i] = serialQueue[i + 1];
}
@@ -645,14 +651,14 @@ void EmitRuntimeHelp() {
Console_AdvanceToNextLineIfNotRoomFor((short)strlen(buf), 1);
Console_Write(buf);
}
if (avr.IsOpen()) {
if (avrPort.IsOpen()) {
Console_ScrollBottomRegion();
Console_SetCursor(0, -1);
printf(" Com Status: RTS: %-3s ", avr.Get_RTS_State() ? "ON" : "OFF");
printf("DTR: %-3s ", avr.Get_DTR_State() ? "ON" : "OFF");
printf("CTS: %-3s ", avr.Get_CTS_State() ? "ON" : "OFF");
printf("DSR: %-3s ", avr.Get_DSR_State() ? "ON" : "OFF");
printf("RI: %-3s", avr.Get_RI_State() ? "ON" : "OFF");
printf(" Com Status: RTS: %-3s ", avrPort.Get_RTS_State() ? "ON" : "OFF");
printf("DTR: %-3s ", avrPort.Get_DTR_State() ? "ON" : "OFF");
printf("CTS: %-3s ", avrPort.Get_CTS_State() ? "ON" : "OFF");
printf("DSR: %-3s ", avrPort.Get_DSR_State() ? "ON" : "OFF");
printf("RI: %-3s", avrPort.Get_RI_State() ? "ON" : "OFF");
Console_ScrollBottomRegion();
Console_SetCursor(0, -1);
}
@@ -692,7 +698,7 @@ static void PCMessage(const char *msg, int len, uint8_t **src, const char * (fnc
#if 0
void ShowAllStatusInfo(void) {
if (avrStatus.headerValid) {
bool priorState = Console_SetCursorVisibility(false);
@@ -807,7 +813,7 @@ void ShowAllStatusInfo(void) {
Console_SetCursorVisibility(priorState);
}
}
#endif
void ProcessKeyboard(void) {
static uint32_t spin = 0;
@@ -819,6 +825,12 @@ void ProcessKeyboard(void) {
if (CS_KeyHit()) {
int c = CS_GetChar();
switch (c) {
case 'P':
avr->Power(AVRInterface::avrPowerOn);
break;
case 'p':
avr->Power(AVRInterface::avrPowerOff);
break;
case 'O':
ProcessSerialQueue((const uint8_t *)"\x02" "21000" "\x03", 7);
ProcessSerialQueue((const uint8_t *)"\x02" "3Test" "\x03", 7);
@@ -830,19 +842,20 @@ void ProcessKeyboard(void) {
EmitRuntimeHelp();
break;
case '/':
ShowAllStatusInfo();
avr->ReportAllStatus();
//ShowAllStatusInfo();
break;
case '\x1B':
UserWantsToExitCanSniff = true;
break;
case 'S':
avr.Set_RTS_State(TRUE);
avrPort.Set_RTS_State(TRUE);
Console_SetCursor(0, -1);
printf("RTS set ON");
Console_ScrollBottomRegion();
break;
case 's':
avr.Set_RTS_State(FALSE);
avrPort.Set_RTS_State(FALSE);
Console_SetCursor(0, -1);
printf("RTS set OFF");
Console_ScrollBottomRegion();
@@ -894,7 +907,31 @@ void EmitCommandLineHelp() {
exit(EXIT_OK);
}
void InformationUpdate(AVRInterface::AVRMessageType_T type, const char *msg) {
char buf[MAXTEXTLEN] = "";
switch (type) {
case AVRInterface::AVRMessageType_T::mtStatus:
sprintf_s(buf, MAXTEXTLEN, "AVR Status: %-60s", msg);
Console_WriteAt(0, 1, buf);
break;
case AVRInterface::AVRMessageType_T::mtInfo:
Console_WriteAt(0, -1, msg);
Console_ScrollBottomRegion();
break;
case AVRInterface::AVRMessageType_T::mtModelInfo:
Console_WriteAt(0, 2, msg);
break;
case AVRInterface::AVRMessageType_T::mtStreamStart:
Console_SetCursor(0, 3);
// break; // fall through
case AVRInterface::AVRMessageType_T::mtStream:
Console_AdvanceToNextLineIfNotRoomFor(26); // @TODO hard-coded - ick
Console_Write(msg);
break;
default:
break;
}
}
/******************************************************/
/* m a i n ( ) */
@@ -903,9 +940,8 @@ void EmitCommandLineHelp() {
// 0 99
// +---------------------------------------------------------------+
// | Program banner information | 0
// | on two lines |
// | Current status information starts on line 3 |
// | and down a ways... |
// | State machine status information starts on line 2 |
// | Overall information is on line 3 and onward |
// | |
// | |
// | |
@@ -921,7 +957,7 @@ int __cdecl main(int argc, char *argv[]) {
short consoleScrollHeight = 30;
progStartTime_ms = timeGetTime();
MessageHandlerSanityCheck(); // If the table is bad, we exit here
// MessageHandlerSanityCheck(); // If the table is bad, we exit here
UserCommandsSanityCheck(); // If the table is bad, we exit here
Console_Init(consoleWidth, consoleHeight, consoleScrollHeight);
@@ -956,9 +992,29 @@ int __cdecl main(int argc, char *argv[]) {
printf("[COM%i at %i baud]", avrOnPort, avrBaud);
Console_WriteAt(0, consoleHeight - consoleScrollHeight -1, "----------------------------------------");
avr = new AVRInterface(SerialSend);
avr->RegisterInformationCallback(InformationUpdate);
do {
avr->Tick(timeGetTime());
ProcessKeyboard();
/* bool anyRcvdMsg = */ ProcessSerialReceive();
SerialQueue_T anyRcvdMsg = ProcessSerialReceive();
if (anyRcvdMsg.len) {
// Show to the user
EchoSerialRecv(anyRcvdMsg.message);
// Let the AVR interface handle it first
bool showAllFlag = avr->HandleMessage(anyRcvdMsg.message, anyRcvdMsg.len);
if (showAllFlag) {
bool priorState = Console_SetCursorVisibility(false);
avr->ReportAllStatus();
Console_SetCursorVisibility(priorState);
}
// old way to parse the message
//HandleMessage(anyRcvdMsg.message, anyRcvdMsg.len);
}
ProcessSerialQueue();
ProcessWindowsMessage();
} while (!UserWantsToExitCanSniff);
@@ -1018,8 +1074,8 @@ bool CheckTheChecksum(uint8_t *szBuffer, uint32_t num) {
}
// ProcessResponse
#if 0
// ProcessReportResponse
//
// @param[in] szBuffer is the received message
// @param[in] len is the null terminated string length of the message
@@ -1028,7 +1084,7 @@ bool CheckTheChecksum(uint8_t *szBuffer, uint32_t num) {
// '\x02' 'type' 'guard' 'rcmd0' 'rcmd1' 'rdat0' 'rdat1' '\x03'
// [0] [1] [2] [3] [4] [5] [6] [7]
//
void ProcessResponse(uint8_t *szBuffer, uint32_t len) {
void ProcessReportResponse(uint8_t *szBuffer, uint32_t len) {
// These don't have a checksum ...
// Example: [02] 4026 66[03]
// 4 - controlled by encoder
@@ -1052,9 +1108,6 @@ void ProcessResponse(uint8_t *szBuffer, uint32_t len) {
if (MessageHandlers[i].numToTransfer == 2) {
memcpy(&avrStatus.config.DT0 + MessageHandlers[i].configOffset, &szBuffer[5], 2);
}
//if (MessageHandlers[i].fncHelper) {
// (*MessageHandlers[i].fncHelper)(rcmd, rdat, szBuffer, len);
//}
if (MessageHandlers[i].TextFormatter && MessageHandlers[i].fncValueToText) {
sprintf_s(buf, MAXTEXTLEN, MessageHandlers[i].TextFormatter, MessageHandlers[i].fncValueToText(rdat));
Console_Write(buf);
@@ -1071,10 +1124,11 @@ void ProcessResponse(uint8_t *szBuffer, uint32_t len) {
Console_Write(buf);
Console_ScrollBottomRegion();
}
}
#endif
// AnalyzeResponse
// HandleMessage
//
// Given a response string, typically of the form:
// [11] .... [03]
@@ -1082,10 +1136,10 @@ void ProcessResponse(uint8_t *szBuffer, uint32_t len) {
// ... etc
//
//
void AnalyzeResponse(uint8_t *szBuffer, uint32_t num) {
void HandleMessage(uint8_t *szBuffer, uint32_t num) {
switch (szBuffer[0]) {
case 0x02: // STX
ProcessResponse(szBuffer, num);
//ProcessReportResponse(szBuffer, num);
break;
case 0x11: // DC1
break;
@@ -1107,9 +1161,8 @@ void AnalyzeResponse(uint8_t *szBuffer, uint32_t num) {
} else {
printf("***** Received message of unexpected length [%u]\n", num);
}
ShowAllStatusInfo();
} else {
printf("Checksum failure on Status Header\n");
Console_WriteAt(0, -1, "Checksum failure on Status Header");
}
//PrintConfiguration(szBuffer);
break;
@@ -1132,34 +1185,34 @@ void AnalyzeResponse(uint8_t *szBuffer, uint32_t num) {
// All character sequences end with \x03 (this is the equiv of a <cr>)
//
//
bool ProcessSerialReceive() {
bool anythingReceived = false;
uint8_t rcv_buff[MAXTEXTLEN] = { 0 };
static uint8_t messageBuf[MAXTEXTLEN] = { 0 };
static uint8_t *p = messageBuf; // used to fill the rcv_buff as data comes in
SerialQueue_T ProcessSerialReceive() {
uint8_t partialRx[MAXTEXTLEN] = { 0 };
uint32_t num = avr.Read(rcv_buff, MAXTEXTLEN);
static uint8_t bufInUse = 0;
static uint8_t messageBuf[2][MAXTEXTLEN] = { 0 };
static uint8_t *p = messageBuf[bufInUse]; // used to fill the partialRx as data comes in
SerialQueue_T retInfo = { NULL, 0 };
uint32_t num = avrPort.Read(partialRx, MAXTEXTLEN);
if (num) {
for (uint32_t i = 0; i < num; i++) {
*p = rcv_buff[i];
*p = partialRx[i];
if (*p++ == '\x03') { // End of message
*p = '\0'; // null terminate it
EchoSerialRecv(messageBuf);
//
// @TODO Now do something with the received message
//
AnalyzeResponse(messageBuf, (uint32_t)strlen((char *)messageBuf));
p = messageBuf; // Reset the buffer for the next message, which might be in rcv_buff
*p = '\0'; // null terminate it
// It is ready to return now
retInfo.message = messageBuf[bufInUse];
retInfo.len = (uint16_t)(p - messageBuf[bufInUse]);
// Prepare the alternate buffer for the next message
bufInUse = (++bufInUse & 1);
p = messageBuf[bufInUse]; // Reset the buffer for the next message, which might be in partialRx
*p = '\0';
anythingReceived = true;
}
}
if (messageBuf[0]) {
//EmitBuffer("~", messageBuf, 0, true); // Show them the partial receipt if anything is there
}
}
return anythingReceived;
return retInfo;
}
@@ -1196,8 +1249,8 @@ void EnumerateComPorts() {
int DetachSerialPort() {
if (avr.IsOpen()) {
avr.Close();
if (avrPort.IsOpen()) {
avrPort.Close();
}
return true;
}
@@ -1209,11 +1262,11 @@ int AttachToSerialPort() {
sprintf_s(buf, sizeof(buf), "\\\\.\\COM%d", avrOnPort);
uint32_t Access = GENERIC_WRITE | GENERIC_READ;
if (avr.Open(buf, avrBaud, 8, NOPARITY, ONESTOPBIT, Access)) {
if (avrPort.Open(buf, avrBaud, 8, NOPARITY, ONESTOPBIT, Access)) {
success = true;
avr.Set_RTS_State(false);
avrPort.Set_RTS_State(false);
Sleep(250);
avr.Set_RTS_State(true);
avrPort.Set_RTS_State(true);
}
}
return success;