Adding directly settable commands (instead of volume up/down, set volume to xx)

This commit is contained in:
2026-01-30 17:20:57 -06:00
parent 87ece7eb14
commit 936f71b737
6 changed files with 264 additions and 115 deletions

View File

@@ -263,58 +263,12 @@ unsigned long Hex2Dec(uint8_t *p, int dig);
void GetAndSendCustomMessage();
void GetAndSendOSDMessage();
void EmitRuntimeHelp();
bool UserExitRequested = false;
bool SystemExitRequested = false;
typedef struct {
const char *pMsg;
uint16_t MsgLen;
} Message_T;
typedef struct {
const char Char;
const char *pDescription;
Message_T TxMsg;
} UserCmd_T;
// Runtime commands from the keyboard to send to the AVR
//
const UserCmd_T UserCommands[] = {
{ 'R', "Ready", {"\x11" "000" "\x03", 5 } },
//{ 'P', "Power On", {"\x02" "07A1D" "\x03", 7} },
//{ 'p', "Power Off", {"\x02" "07A1E" "\x03", 7} },
{ '1', "Zone 1 On", {"\x02" "07E7E" "\x03", 7} },
{ '!', "Zone 1 Standby", {"\x02" "07E7F" "\x03", 7} },
{ '2', "Zone 2 On", {"\x02" "07EBA" "\x03", 7} },
{ '@', "Zone 2 Standby", {"\x02" "07EBB" "\x03", 7} },
{ '3', "Zone 3 On", {"\x02" "07AED" "\x03", 7} },
{ '#', "Zone 3 Standby", {"\x02" "07AEE" "\x03", 7} },
{ 'V', "Vol 1 Up", {"\x02" "07A1A" "\x03", 7} },
{ 'v', "Vol 1 Down", {"\x02" "07A1B" "\x03", 7} },
{ 'M', "Vol 1 Mute", {"\x02" "07EA2" "\x03", 7} },
{ 'm', "Vol 1 UnMute", {"\x02" "07EA3" "\x03", 7} },
{ 'O', "OSD Test Message", },
{ 'T', "Tuning freq rqst", {"\x02" "22000" "\x03", 7} },
{ 'Y', "Zone 1 Vol rqst", {"\x02" "22001" "\x03", 7} },
{ 'y', "Zone 2 Vol rqst", {"\x02" "22002" "\x03", 7} },
{ 'U', "Zone 1 Input rqst", {"\x02" "22003" "\x03", 7} },
{ 'u', "Zone 2 Input rqst", {"\x02" "22004" "\x03", 7} },
{ 'I', "Zone 3 Vol rqst", {"\x02" "22005" "\x03", 7} },
{ 'i', "Zone 3 Input rqst", {"\x02" "22006" "\x03", 7} },
//{ 'J', "Dual Mono - Main", {"\x02" "07E93" "\x03", 7} },
//{ 'K', "Dual Mono - Sub", {"\x02" "07E94" "\x03", 7} },
//{ 'L', "Dual Mono - All", {"\x02" "07E95" "\x03", 7} },
{ ':', "Custom Message" },
{ '/', "Show All" },
{ '?', "Help on runtime commands" },
{ 'S', "Set RTS" },
{ 's', "Clear RTS" },
{ '\x1B', "Quit App" },
};
typedef struct {
//uint8_t type; // 0 to 4, and 0xFF for don't care
//uint8_t guard; // 0 to 2, and 0xFF for don't care
uint8_t rCmd;
uint8_t configOffset; // offset into the Config DT0 - DT155 array, or 0xFF for no action
uint8_t numToTransfer; // number of bytes to transfer into the Config array, or 0 for no action
@@ -323,24 +277,6 @@ typedef struct {
const char *(*fncValueToText)(uint8_t rDat);
} MessageHandler_T;
void UserCommandsSanityCheck() {
uint8_t usedKey[256] = { 0 };
bool fail = false;
size_t numCommands = sizeof(UserCommands) / sizeof(UserCmd_T);
for (size_t i = 0; i < numCommands; i++) {
usedKey[UserCommands[i].Char]++;
if (usedKey[UserCommands[i].Char] > 1) {
printf("UserCommandsSanityCheck: Command key %c used more than once\n", UserCommands[i].Char);
fail = true;
}
}
if (fail) {
printf("***** UserCommandsSanityCheck: Errors found in UserCommands table\n");
exit(EXIT_InternalSanityCheckFail);
}
}
int CS_KeyHit() {
int h = _kbhit();
@@ -401,37 +337,59 @@ void EmitSpinner() {
if (x == 8) x = 0;
}
typedef struct {
const char *pMsg;
uint16_t MsgLen;
} Message_T;
void EmitRuntimeHelp() {
for (int i = 0; i < sizeof(UserCommands) / sizeof(UserCmd_T); i++) {
char tinyBuf[6];
if (isprint(UserCommands[i].Char)) {
sprintf_s(tinyBuf, sizeof(tinyBuf), "%c", UserCommands[i].Char);
} else if (UserCommands[i].Char == '\x1B') {
sprintf_s(tinyBuf, sizeof(tinyBuf), "%s", "<esc>");
} else if (UserCommands[i].Char < ' ') {
sprintf_s(tinyBuf, sizeof(tinyBuf), "^%c", UserCommands[i].Char + 64);
} else {
sprintf_s(tinyBuf, sizeof(tinyBuf), "0x%02X", (unsigned char)UserCommands[i].Char);
}
char buf[MAXTEXTLEN];
sprintf_s(buf, MAXTEXTLEN, " %5s %-25s", tinyBuf, UserCommands[i].pDescription);
Console_AdvanceToNextLineIfNotRoomFor((short)strlen(buf), 1);
Console_Write(buf);
}
if (avrPort.IsOpen()) {
Console_ScrollBottomRegion();
Console_SetCursor(0, -1);
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);
}
}
typedef struct {
const char Char;
const char *pDescription;
Message_T TxMsg;
} UserCmd_T;
// Runtime commands from the keyboard to send to the AVR
//
// [ESC]
// [1!] [2@] [3#] 4 5 6 7 8 9 0 - =
// qQ wW eE r[R] t[T] [yY] [uU] [iI] o[O] [pP] [{ ]} \|
// aA [sS] dD f[F] gG hH jJ kK lL ;[:] '"
// zZ xX cC [vV] bB nN [mM] ,< .> [/?]
//
const UserCmd_T UserCommands[] = {
{ 'R', "Ready", {"\x11" "000" "\x03", 5 } },
{ 'P', "Power On", },
{ 'p', "Power Off", },
{ '1', "Zone 1 On", {"\x02" "07E7E" "\x03", 7} },
{ '!', "Zone 1 Standby", {"\x02" "07E7F" "\x03", 7} },
{ '2', "Zone 2 On", {"\x02" "07EBA" "\x03", 7} },
{ '@', "Zone 2 Standby", {"\x02" "07EBB" "\x03", 7} },
{ '3', "Zone 3 On", {"\x02" "07AED" "\x03", 7} },
{ '#', "Zone 3 Standby", {"\x02" "07AEE" "\x03", 7} },
{ 'V', "Vol 1 Up", {"\x02" "07A1A" "\x03", 7} },
{ 'v', "Vol 1 Down", {"\x02" "07A1B" "\x03", 7} },
{ 'M', "Vol 1 Mute", {"\x02" "07EA2" "\x03", 7} },
{ 'm', "Vol 1 UnMute", {"\x02" "07EA3" "\x03", 7} },
{ 'O', "OSD Test Message", },
{ 'T', "Tuning freq rqst", {"\x02" "22000" "\x03", 7} },
{ 'Y', "Zone 1 Vol rqst", {"\x02" "22001" "\x03", 7} },
{ 'y', "Zone 2 Vol rqst", {"\x02" "22002" "\x03", 7} },
{ 'U', "Zone 1 Input rqst", {"\x02" "22003" "\x03", 7} },
{ 'u', "Zone 2 Input rqst", {"\x02" "22004" "\x03", 7} },
{ 'I', "Zone 3 Vol rqst", {"\x02" "22005" "\x03", 7} },
{ 'i', "Zone 3 Input rqst", {"\x02" "22006" "\x03", 7} },
{ 'F', "Factory Reset", {"\x13" "\x7F\x7F\x7F" "\x03", 5} },
//{ 'J', "Dual Mono - Main", {"\x02" "07E93" "\x03", 7} },
//{ 'K', "Dual Mono - Sub", {"\x02" "07E94" "\x03", 7} },
//{ 'L', "Dual Mono - All", {"\x02" "07E95" "\x03", 7} },
{ ':', "Custom Message" },
{ '/', "Show All" },
{ '?', "Help on runtime commands" },
{ 'S', "Set RTS" },
{ 's', "Clear RTS" },
{ '\x1B', "Quit App" },
};
void ProcessKeyboard(void) {
static uint32_t spin = 0;
@@ -497,6 +455,55 @@ void ProcessKeyboard(void) {
return;
}
void UserCommandsSanityCheck() {
uint8_t usedKey[256] = { 0 };
bool fail = false;
size_t numCommands = sizeof(UserCommands) / sizeof(UserCmd_T);
for (size_t i = 0; i < numCommands; i++) {
usedKey[UserCommands[i].Char]++;
if (usedKey[UserCommands[i].Char] > 1) {
printf("UserCommandsSanityCheck: Command key %c used more than once\n", UserCommands[i].Char);
fail = true;
}
}
if (fail) {
printf("***** UserCommandsSanityCheck: Errors found in UserCommands table\n");
exit(EXIT_InternalSanityCheckFail);
}
}
void EmitRuntimeHelp() {
for (int i = 0; i < sizeof(UserCommands) / sizeof(UserCmd_T); i++) {
char tinyBuf[6];
if (isprint(UserCommands[i].Char)) {
sprintf_s(tinyBuf, sizeof(tinyBuf), "%c", UserCommands[i].Char);
} else if (UserCommands[i].Char == '\x1B') {
sprintf_s(tinyBuf, sizeof(tinyBuf), "%s", "<esc>");
} else if (UserCommands[i].Char < ' ') {
sprintf_s(tinyBuf, sizeof(tinyBuf), "^%c", UserCommands[i].Char + 64);
} else {
sprintf_s(tinyBuf, sizeof(tinyBuf), "0x%02X", (unsigned char)UserCommands[i].Char);
}
char buf[MAXTEXTLEN];
sprintf_s(buf, MAXTEXTLEN, " %5s %-25s", tinyBuf, UserCommands[i].pDescription);
Console_AdvanceToNextLineIfNotRoomFor((short)strlen(buf), 1);
Console_Write(buf);
}
if (avrPort.IsOpen()) {
Console_ScrollBottomRegion();
Console_SetCursor(0, -1);
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);
}
}
void HexUppercase(char *p) {
const char *hex = "0123456789ABCDEF";
while (*p) {
@@ -604,11 +611,12 @@ void EmitCommandLineHelp() {
printf(" Options:\n");
printf(" -SerialPort=X[,yyyy] Set to Com port X to baud rate yyyy.\n");
printf(" Defaults baud is %d\n", avrBaud);
printf(" -Command=S,F,V Execute a command and exit (based on the numeric values):\n");
printf(" S - Subsystem\n");
printf(" F - Function\n");
printf(" V - Value\n");
printf(" Use the -ExportInfo command to see the values.\n");
printf(" -Command=S,F,O[,V] Execute a command and exit (based on the numeric values):\n");
printf(" S - Subsystem,\n");
printf(" F - Function,\n");
printf(" O - Operation,\n");
printf(" V - Value used by only certain command.\n");
printf(" Use the -ExportInfo command to see the Command List.\n");
printf(" NOTE: Program will auto-exit after performing the command,\n");
printf(" or after 5 seconds without obvious success.\n");
printf(" -Verbose Shows progress during -Command operation.\n");
@@ -663,7 +671,7 @@ int __cdecl main(int argc, char *argv[]) {
short consoleScrollHeight = 30;
short consoleLeft = 15;
short consoleTop = 15;
int CommandToExecute[3] = { -1, -1, -1 };
int CommandToExecute[4] = { -1, -1, -1, -1 };
// MessageHandlerSanityCheck(); // If the table is bad, we exit here
GetProgName(argv[0]);
@@ -681,6 +689,8 @@ int __cdecl main(int argc, char *argv[]) {
avrBaud = param2;
} else if (3 == sscanf_s(argv[i], "-Command=%d,%d,%d", &CommandToExecute[0], &CommandToExecute[1], &CommandToExecute[2])) {
// After the port is open, execute this and exit
} else if (4 == sscanf_s(argv[i], "-Command=%d,%d,%d,%d", &CommandToExecute[0], &CommandToExecute[1], &CommandToExecute[2], &CommandToExecute[3])) {
// After the port is open, execute this and exit
} else if (0 == strcmp(argv[i], "-Verbose")) {
verboseMode = true;
} else if (0 == strcmp(argv[i], "-ExportInfo")) {
@@ -732,7 +742,7 @@ int __cdecl main(int argc, char *argv[]) {
state = avr->Tick(nowTime);
} while (((nowTime - refTime) < 5000) && (state != AVRInterface::stReady));
} else {
printf("%u\n", elapsedTime);
// printf("%u\n", elapsedTime);
}
DetachSerialPort();
exit(EXIT_OK);