[Hamlib-commits] Hamlib -- Ham radio control libraries branch master updated. be44ddc83055418110984
Library to control radio transceivers and receivers
Brought to you by:
n0nb
From: n0nb <n0...@us...> - 2024-10-30 21:33:32
|
This is an automated email from the git hooks/post-receive script. It was generated because a ref change was pushed to the repository containing the project "Hamlib -- Ham radio control libraries". The branch, master has been updated via be44ddc83055418110984c009dd6cf923136cc86 (commit) via ab883be8504c61568ef383e1aa3061e99199d0d6 (commit) via da5e490b2406676a27afc5157390de896c5b1533 (commit) via eead7a572ab579b68ef884d37fb870056cfa0e3b (commit) via 671d45f33775851bbcf4bf8bcf951a0be8fee2b2 (commit) via 3445d94c8d9bff1f57473d275135b46e744da15c (commit) via d209c655b0bb32706d2e1b96907ada54fa3205eb (commit) via 8bbf60d5c87f556a2093b7088b5cc14203c292e0 (commit) via 7aa739a97d5b5f3803a0940ac74f6955d77b26ed (commit) via ddf51e6b52361c870a377de43a3dd4be0a76a32d (commit) via 2b99b9d2ef04867166b9682709e8b508e168e3ec (commit) via ebe685125e5d728969113dbaf35a0f76138a7b93 (commit) via 5b1df09ad00d0cb1ef7faf66dda561ed76133745 (commit) via 3e34acc1e036ca13de01ee4c2dd43d49c79a56c1 (commit) via 65ae33845461e24f667d5acdc8d0bdbdf790da4b (commit) via 536cf13c698489bb112f93002f3235a40306fa3a (commit) via aa6d028b73934a307aae3b6d8a0cb7ca11f554ef (commit) from e3b067307a93bebd3eab6c5d11687f6adc482d27 (commit) Those revisions listed above that are new to this repository have not appeared on any other notification email; so we list those revisions in full, below. - Log ----------------------------------------------------------------- commit be44ddc83055418110984c009dd6cf923136cc86 Merge: 5b1df09ad ab883be85 Author: Michael Black <mdb...@ya...> Date: Wed Oct 30 12:13:58 2024 -0500 Merge pull request #1626 from GeoBaltz/fix21 Loads of code for simts890.c commit ab883be8504c61568ef383e1aa3061e99199d0d6 Author: George Baltz N3GB <Geo...@gm...> Date: Tue Oct 29 14:38:19 2024 -0400 Make FR & FT commands aware of new vfo structs. Get rid of vfo_rx & vfo_tx; find both thru vfoLR. diff --git a/simulators/simts890.c b/simulators/simts890.c index 34af7d616..55224df45 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -36,7 +36,7 @@ int mysleep = 20; int filternum1 = 7; int filternum2 = 8; -int vfo_rx, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; +int ptt, ptt_data, ptt_mic, ptt_tune; int keyspd = 20; int sl=3, sh=3; int nr=0; @@ -434,7 +434,7 @@ int main(int argc, char *argv[]) { int temp = -1; sscanf(buf + 8, "%3d", &temp); - if (temp < 2 && temp >= 0) + if (temp <= 2 && temp >= 0) { nummems = temp * 2 + 1; } else { cmd_err = 1; } @@ -535,26 +535,48 @@ int main(int argc, char *argv[]) *vfoAB[tmpvfo] = nvfo; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } - else if (strcmp(buf, "FR;") == 0) - { - snprintf(buf, sizeof(buf), "FR%d;", vfo_rx); - OUTPUT(buf); - } else if (strncmp(buf, "FR", 2) == 0) - { - sscanf(buf, "FR%d", &vfo_rx); - } - else if (strcmp(buf, "FT;") == 0) - { - snprintf(buf, sizeof(buf), "FT%d;", vfo_tx); - OUTPUT(buf); + { // Receiver Function (VFO A / VFO B / Memory channel) + int idx; + + if (buf[2] == ';') + { // Read + idx = sp && tfset; + snprintf(buf, sizeof(buf), "FR%d;", (*vfoLR[idx])->vfo); + OUTPUT(buf); + } + else + { // Set + idx = buf[2] - '0'; + if (idx == 3) + { //TODO: Memory channels are a long way off + puts("Memory channels not implemented.\n"); + cmd_err = 3; + continue; + } + if (idx < 0 || idx > 1) {cmd_err = 1; continue; } + sp = 0; // Turn off split + if ((*vfoLR[0])->vfo != idx) // If the selected vfo is not the operational one + { + swapvfos(vfoLR); // Make it so + } + } } else if (strncmp(buf, "FT", 2) == 0) - { - sscanf(buf, "FT%d", &vfo_tx); - if (vfo_tx != vfo_rx) - { - sp = 1; + { // Transmitter Function ( VFO A / VFO B ) + int idx; + + if (buf[2] == ';') + { // Read + idx = sp && !tfset; + snprintf(buf, sizeof(buf), "FT%d;", (*vfoLR[idx])->vfo); + OUTPUT(buf); + } + else + { // Set + idx = buf[2] - '0'; + if (idx < 0 || idx > 1) {cmd_err = 1; continue; } + sp = idx != (*vfoLR[0])->vfo; // Turn split on if vfos differ, else off } } else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD @@ -678,7 +700,7 @@ int main(int argc, char *argv[]) /* This section needs a lot of work, and a lot * of cooperation from other commands. * AFAICT the split freq can be set by spinning - * the big knob, or by other means. When oper=1 + * the big knob, or by other means. When oper=0 * is sent, the current freq is used as the split * value. See page 5-1 of the IM, blinking SPLIT */ commit da5e490b2406676a27afc5157390de896c5b1533 Author: George Baltz N3GB <Geo...@gm...> Date: Fri Oct 25 17:05:26 2024 -0400 Clean up Fix up NB commands. Update VFO in case copy caused a band change. Change MODEL to TYPE to match Kenwood nomenclature, make it easier to change via cli. Comments diff --git a/simulators/simts890.c b/simulators/simts890.c index e1a2545dc..34af7d616 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -22,8 +22,10 @@ struct ip_mreq #define BUFSIZE 256 #define NBANDS 11 -/* Model we're emulating - K=The Americas, E=Europe */ -#define MODEL K +/* Type we're emulating - K=The Americas(default), E=Europe */ +#if !defined(TYPE) +#define TYPE K +#endif /* Define a macro for sending response back to the app * This will allow us to reroute output to a buffering routine * Needed to handle multiple commands in a single message @@ -44,7 +46,7 @@ int sm = 35; int nt = 0; int ag = 100; int ac = 0; -int nb1=0,nb2=0; +int nb[2] = {0, 0}; // NB1/NB2 OFF/ON int sq=0; int rg=0; int mg=0; @@ -90,7 +92,7 @@ int bandslot[2][NBANDS]; // 0-based band memory: ((bandslot[i] + 1) % nummems) * selection is by BD/BU command */ struct kvfo band_mem[2][NBANDS][5] = { { -#if MODEL==K +#if TYPE==K /* 160M */ { { 1800000, 3}, { 1810000, 3}, { 1820000, 3}, { 1830000, 3}, { 1840000, 3} }, /* 80M */ { { 3500000, 1}, { 3600000, 1}, { 3700000, 1}, { 3800000, 1}, { 3900000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, @@ -102,7 +104,7 @@ struct kvfo band_mem[2][NBANDS][5] = { { /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { { 135700, 3}, { 472000, 3}, { 1000000, 5}, { 5305500, 2}, { 5403500, 2} } -#else // MODEL==E +#else // TYPE==E /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1810000, 3}, { 1820000, 3} }, /* 80M */ { { 3500000, 1}, { 3550000, 1}, { 3600000, 1}, { 3650000, 1}, { 3700000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, @@ -125,7 +127,7 @@ struct band_def { int high; }; const struct band_def band_limits[NBANDS] = { -#if MODEL == K +#if TYPE == K { 1800000, 2000000}, { 3500000, 4000000}, { 7000000, 7300000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, @@ -253,7 +255,7 @@ int main(int argc, char *argv[]) "%1X" // P9 Operating mode (See OM command) "0" // P10 Function? "0" // P11 Scan status? - "%1d" // P12 Simplex/Split + "%1d" // P12 Simplex=0/Split=1 "0" // P13 Tone/CTCSS (not on TS-890S) "00" // P14 Tone/CTCSS freq (not on TS-890S) "0;"; // P15 Always zero @@ -324,27 +326,31 @@ int main(int argc, char *argv[]) if (buf[5] != '9') antout = buf[5]; } } - else if (strcmp(buf, "NB1;") == 0) - { - hl_usleep(mysleep * 20); - sprintf(buf, "NB1%d;", nb1); - OUTPUT(buf); - } - else if (strncmp(buf, "NB1", 3) == 0) - { - puts(buf); - sscanf(buf, "NB1%d", &nb1); - } - else if (strcmp(buf, "NB2;") == 0) - { - hl_usleep(mysleep * 20); - sprintf(buf, "NB2%d;", nb2); - OUTPUT(buf); - } - else if (strncmp(buf, "NB2", 3) == 0) - { - puts(buf); - sscanf(buf, "NB2%d", &nb2); + else if (strncmp(buf, "NB", 2) == 0) + { // Noise Blanker settings + int idx; + switch (toupper(buf[2])) { + case '1': // Noise Blanker 1 + case '2': // Noise Blanker 2 + idx = buf[2] - '1'; + if (buf[3] == ';') + { // Read + hl_usleep(mysleep * 20); + sprintf(buf, "NB%d%d;", idx + 1, nb[idx]); + OUTPUT(buf); + } + else + { // Set + nb[idx] = buf[3] - '0'; + } + break; + case 'D': // Noise Blanker 2, type B Depth + case 'T': // Noise Blanker 2 Type + case 'W': // Noise Blanker 2, type B Width + break; + default: + cmd_err = 1; + } } else if (strcmp(buf, "RA;") == 0) { @@ -756,13 +762,14 @@ int main(int argc, char *argv[]) { // VFO A to VFO B Copy ([A=B] Operation) /* Akin to the EC command above, this isn't really a "VFO A to VFO B" * copy, but an "Operational VFO to Secondary VFO" copy. It also - * mimics the front panel [A=B] button. + * mimics the front panel [A=B] action. */ kvfop_t ovfo, svfo; ovfo = *vfoLR[0]; svfo = newvfo(*vfoLR[1], ovfo->band); // Get appropriate vfo for new freq svfo->freq = ovfo->freq; svfo->mode = ovfo->mode; + *vfoLR[1] = svfo; } else if (strncmp(buf, "KS;", 3) == 0) { @@ -804,7 +811,7 @@ int main(int argc, char *argv[]) } } else if (strncmp(buf, "RM", 2) == 0) - { // Meter control/readout + { // Meter if (buf[2] == ';') { // Read all enabled meters char tbuf[8]; commit eead7a572ab579b68ef884d37fb870056cfa0e3b Author: George Baltz N3GB <Geo...@gm...> Date: Thu Oct 24 16:20:35 2024 -0400 Correct some split problems and connect VFO ops Fix SP command to match real rig. Still needs work. Add split status to IF response. Add EC and VV commands, and explain that they are not what they're described to be. diff --git a/simulators/simts890.c b/simulators/simts890.c index df8652f0c..e1a2545dc 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -35,7 +35,6 @@ int mysleep = 20; int filternum1 = 7; int filternum2 = 8; int vfo_rx, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; -int split = 0; int keyspd = 20; int sl=3, sh=3; int nr=0; @@ -52,7 +51,8 @@ int mg=0; int ra=0; int rl=0; int is=0; -int sp=0; +int sp=0; // Split OFF/ON +int split_op = 0; // Split frequency setting operation in progress // Clock data int autoset = 1; int tzs[2] = {36, 56}; // 0=primary(EST), 1=auxiliary(UTC) @@ -103,7 +103,7 @@ struct kvfo band_mem[2][NBANDS][5] = { { /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, /* GENE */ { { 135700, 3}, { 472000, 3}, { 1000000, 5}, { 5305500, 2}, { 5403500, 2} } #else // MODEL==E - /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1820000, 3}, { 1820000, 3} }, + /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1810000, 3}, { 1820000, 3} }, /* 80M */ { { 3500000, 1}, { 3550000, 1}, { 3600000, 1}, { 3650000, 1}, { 3700000, 1} }, /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, @@ -124,7 +124,7 @@ struct band_def { int low; int high; }; -struct band_def band_limits[NBANDS] = { +const struct band_def band_limits[NBANDS] = { #if MODEL == K { 1800000, 2000000}, { 3500000, 4000000}, { 7000000, 7300000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, @@ -144,8 +144,8 @@ struct band_def band_limits[NBANDS] = { * 2 = FM * 3 = AM */ -int mode2classtab[16] = { -1, 0, 0, 1, 2, 3, 1, 1, -1, 1, 1, 1, 0, 0, 2, 3}; -int stepvalues[4][10] = { // Step sizes in Hz +const int mode2classtab[16] = { -1, 0, 0, 1, 2, 3, 1, 1, -1, 1, 1, 1, 0, 0, 2, 3}; +const int stepvalues[4][10] = { // Step sizes in Hz /* SSB */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* CW/FSK/PSK */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, /* FM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000}, @@ -156,6 +156,7 @@ int stepsize[4] = { 1000, 500, 10000, 5000}; // Defaults by modeclass /* Function prototypes */ int freq2band(int freq); kvfop_t newvfo(kvfop_t ovfo, int band); +void swapvfos(kvfop_t *vfoset[]); // Extracted from rig.h int hl_usleep(unsigned long usec); // Until it's replaced @@ -252,7 +253,7 @@ int main(int argc, char *argv[]) "%1X" // P9 Operating mode (See OM command) "0" // P10 Function? "0" // P11 Scan status? - "0" // P12 Simplex/Split + "%1d" // P12 Simplex/Split "0" // P13 Tone/CTCSS (not on TS-890S) "00" // P14 Tone/CTCSS freq (not on TS-890S) "0;"; // P15 Always zero @@ -299,7 +300,7 @@ int main(int argc, char *argv[]) char ifbuf[256]; hl_usleep(mysleep * 1000); sprintf(ifbuf, IFformat, (*vfoLR[0])->freq, - (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, (*vfoLR[0])->mode); + (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, (*vfoLR[0])->mode, sp); OUTPUT(ifbuf); } else if (strncmp(buf, "AN", 2) == 0) @@ -547,7 +548,7 @@ int main(int argc, char *argv[]) sscanf(buf, "FT%d", &vfo_tx); if (vfo_tx != vfo_rx) { - split = 1; + sp = 1; } } else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD @@ -659,14 +660,68 @@ int main(int argc, char *argv[]) break; } } + else if (strncmp(buf, "SP", 2) == 0) + { // Split Operation Frequency Setting + if (buf[2] == ';') + { // Read + snprintf(buf + 2, sizeof(buf) -2, "%1d;", split_op); + OUTPUT(buf); + } + else if (buf[3] == ';') + { // Set 1 + /* This section needs a lot of work, and a lot + * of cooperation from other commands. + * AFAICT the split freq can be set by spinning + * the big knob, or by other means. When oper=1 + * is sent, the current freq is used as the split + * value. See page 5-1 of the IM, blinking SPLIT + */ + switch (buf[2]) { + case '0': + // Operation complete + if (split_op) // If a split setup was in progress, + { + sp = 1; // split operation is enabled + } + //TODO: Set split freq VFO + split_op = 0; + break; + case '1': + // Start split frequency setup + split_op = 1; + break; + case '2': + // Cancel op + split_op = 0; + break; + default: + cmd_err = 1; + } + } + else + { // Set 2 + int dir, split, spfreq, band; + kvfop_t ovfo, svfo; + sscanf(buf, "SP%1d%1d%1d", &sp, &dir, &split); + dir = dir == 0 ? +1 : -1; + split = dir * 1000 * split; // Convert kHz to +/- Hz + ovfo = *vfoLR[0]; // Operational VFO + spfreq = ovfo->freq + split; + band = freq2band(spfreq); + svfo = newvfo(*vfoLR[1], band); // Other VFO + svfo->freq = spfreq; + *vfoLR[1] = svfo; + sp = 1; // Turn On Split + } + } else if (strncmp(buf, "TB;", 3) == 0) { // Split - sprintf(buf, "TB%d;", split); + sprintf(buf, "TB%d;", sp); OUTPUT(buf); } else if (strncmp(buf, "TB", 2) == 0) { - sscanf(buf, "TB%d", &split); + sscanf(buf, "TB%d", &sp); } else if (strncmp(buf, "TS", 2) == 0) { // TF-SET @@ -677,6 +732,10 @@ int main(int argc, char *argv[]) } else if (buf[2] >= '0' && buf[2] < '2') { + if (sp && (tfset != buf[2] - '0')) + { // Split is set and we're changing state of TF-SET + swapvfos(vfoLR); // Reverse vfo functions + } tfset = buf[2] - '0'; } else @@ -684,6 +743,27 @@ int main(int argc, char *argv[]) cmd_err = 1; } } + else if (strcmp(buf, "EC;") == 0) + { // VFO A and VFO B Frequency Information Exchange + /* No matter what the title says above, the TS-890S does not + * have a frequency swap command. It does, however, have a VFO + * function exchange - just by swapping the left and right displays. + * This command is the same as the "A/B" button on the front panel. + */ + swapvfos(vfoLR); + } + else if (strcmp(buf, "VV;") == 0) + { // VFO A to VFO B Copy ([A=B] Operation) + /* Akin to the EC command above, this isn't really a "VFO A to VFO B" + * copy, but an "Operational VFO to Secondary VFO" copy. It also + * mimics the front panel [A=B] button. + */ + kvfop_t ovfo, svfo; + ovfo = *vfoLR[0]; + svfo = newvfo(*vfoLR[1], ovfo->band); // Get appropriate vfo for new freq + svfo->freq = ovfo->freq; + svfo->mode = ovfo->mode; + } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); @@ -694,7 +774,7 @@ int main(int argc, char *argv[]) sscanf(buf, "KS%03d", &keyspd); } else if (strncmp(buf, "OM", 2) == 0) - { + { // Operating Mode /* The TS-890S displays two frequencies and modes - left and right, * along with arrows that show which is VFO A and which is VFO B. * In almost all cases, the left VFO is the receive freq. The right @@ -719,7 +799,7 @@ int main(int argc, char *argv[]) * which is always the left VFO unless split is active and * we are transmitting. */ - int idx = split && ((ptt + ptt_mic + ptt_data + ptt_tune) > 0); + int idx = sp && ((ptt + ptt_mic + ptt_data + ptt_tune) > 0); sscanf(&buf[3], "%1X", &(*vfoLR[idx])->mode); } } @@ -870,15 +950,6 @@ int main(int argc, char *argv[]) puts(buf); sscanf(buf,"RL1%d", &rl); } - else if (strcmp(buf, "SP;") == 0) - { - sprintf(buf,"SP%d;", sp); - OUTPUT(buf); - } - else if (strncmp(buf, "SP", 2) == 0) - { - sscanf(buf,"SP%d", &sp); - } else if (strncmp(buf, "CK", 2) == 0) { // All the clock functions switch (buf[2]) { @@ -989,6 +1060,20 @@ int main(int argc, char *argv[]) cmd_err = 1; } } + else if (strncmp(buf, "CD", 2) == 0) + { // CW Communications + switch (buf[2]) { + case '0': // CW Communication Screen Display + case '1': // CW Morse Decoding Threshold Level + case '2': // Decoded CW Morse Character Output + case '3': // CW Communication Screen (Decode Filter) + case '4': // CW Communication Screen (Quick Mode) + case '5': // CW Decode + break; + default: + cmd_err = 1; + } + } else if (strncmp(buf, "CM", 2) == 0) { // CW Message Memory switch (buf[2]) { @@ -1147,3 +1232,17 @@ kvfop_t newvfo(kvfop_t ovfo, int band) return &band_mem[vfonum][band][slot]; } + +/* Reverse the function of vfoA and vfoB + * No status returned + */ +void swapvfos(kvfop_t *vfoset[]) +{ + kvfop_t *temp; + + temp = vfoset[0]; + vfoset[0] = vfoset[1]; + vfoset[1] = temp; + + return; +} commit 671d45f33775851bbcf4bf8bcf951a0be8fee2b2 Author: George Baltz N3GB <Geo...@gm...> Date: Fri Oct 18 15:50:49 2024 -0400 Add DN/UP, FC, and UD commands to simts890.c Yet more ways to apply a delta to a VFO diff --git a/simulators/simts890.c b/simulators/simts890.c index 295de5fe4..df8652f0c 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -590,6 +590,56 @@ int main(int argc, char *argv[]) cmd_err = 1; } } + else if ( (strncmp(buf, "DN", 2) == 0) || (strncmp(buf, "UP", 2) == 0) ) + { // Microphone UP/DOWN Switch Operation + int dir = buf[0] == 'D' ? -1 : +1; + int steps = -1; + kvfop_t ovfo = *vfoLR[0]; // Modify the current operational VFO + + if (buf[2] == ';') + { + steps= 1; + } + else if (buf[4] == ';') + { + steps = atoi(buf + 2); + } + if (steps < 0 || steps > 99) {cmd_err = 1; continue;} + ovfo->freq += dir * steps * stepsize[mode2classtab[ovfo->mode]]; + } + else if (strncmp(buf, "FC", 2) == 0) + { // Change the Frequency (Tuning Control) + static const int fc_steps[6] = { 1, 2, 5, 10, 50, 100}; + int dir = buf[2] == '0' ? +1 : -1; + int stepidx = buf[3] - '0'; + int delta; + kvfop_t ovfo = *vfoLR[0]; + + if (stepidx < 0 || stepidx > 5) {cmd_err = 1; continue;} + delta = dir * fc_steps[stepidx] * stepsize[mode2classtab[ovfo->mode]]; + //TODO: This really needs a sanity check here + ovfo->freq += delta; + } + else if (strncmp(buf, "UD", 2) == 0) + { // VFO Frequency UP/DOWN + int idx = buf[2] - '0'; + int dir = buf[3] == '0' ? +1 : -1; + int steps = -1; + kvfop_t nvfo; + + if (idx < 0 || idx > 1 || tfset != 0) {cmd_err = 1; continue;} + nvfo = *vfoAB[idx]; + if (buf[4] == ';') + { + steps = 1; + } + else if (buf[6] == ';') + { + steps = atoi(buf + 4); + } + if (steps < 0 || steps > 99) {cmd_err = 1; continue; } + nvfo->freq += dir * steps * stepsize[mode2classtab[nvfo->mode]]; + } else if (strcmp(buf, "RX;") == 0) { // Receive Function State ptt = ptt_mic = ptt_data = ptt_tune = 0; commit 3445d94c8d9bff1f57473d275135b46e744da15c Author: George Baltz N3GB <Geo...@gm...> Date: Fri Oct 18 05:04:31 2024 -0400 Implement step sizes for some freq changes Add a few more placeholders Disable #include <hamlib/rig.h>; cleanse namespace Typos and formatting diff --git a/simulators/simts890.c b/simulators/simts890.c index a7f7f3e38..295de5fe4 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -9,6 +9,7 @@ struct ip_mreq }; #endif +#include "config.h" #include <stdio.h> #include <stdlib.h> #include <fcntl.h> @@ -17,7 +18,7 @@ struct ip_mreq #include <errno.h> #include <ctype.h> #include <time.h> -#include <hamlib/rig.h> +//#include <hamlib/rig.h> #define BUFSIZE 256 #define NBANDS 11 @@ -132,14 +133,31 @@ struct band_def band_limits[NBANDS] = { #else { 1810000, 2000000}, { 3500000, 3800000}, { 7000000, 7200000}, {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, - {21000000, 21450000}, {24890000, 24990000}, {28000000, 29000000}, + {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, {50000000, 52000000}, { 30000, 74800000} #endif }; +/* Table for mode<->emission class conversion + * Claas 0 = SSB + * 1 = CW/FSK/PSK + * 2 = FM + * 3 = AM + */ +int mode2classtab[16] = { -1, 0, 0, 1, 2, 3, 1, 1, -1, 1, 1, 1, 0, 0, 2, 3}; +int stepvalues[4][10] = { // Step sizes in Hz + /* SSB */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, + /* CW/FSK/PSK */ { 500, 1000, 2500, 5000, 10000, 0, 0, 0, 0, 0}, + /* FM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000}, + /* AM */ { 5000, 6250, 10000, 12500, 15000, 20000, 25000, 30000, 50000, 100000} +}; +int stepsize[4] = { 1000, 500, 10000, 5000}; // Defaults by modeclass + /* Function prototypes */ int freq2band(int freq); kvfop_t newvfo(kvfop_t ovfo, int band); +// Extracted from rig.h +int hl_usleep(unsigned long usec); // Until it's replaced #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices @@ -414,7 +432,33 @@ int main(int argc, char *argv[]) else { cmd_err = 1; } } - } + } + else if (strncmp(buf + 2, "00301", 5) >= 0 && strncmp(buf + 2, "00304", 5) <= 0) + { // [SSB|CW/FSK/PSK|FM|AM] Mode Frequency Step Size (Multi/Channel Control) + int class = buf[6] - '1'; + int i, tmpstep = -1; + if (buf[7] == ';') + { // Read + for (i = 0; i < 10 && stepvalues[class][i] != 0; i++) + { + if (stepsize[class] == stepvalues[class][i]) + { + tmpstep = i; + break; + } + } + if (tmpstep < 0) {cmd_err = 3; continue;} // Shouldn't happen + snprintf(buf + 7, sizeof(buf) - 7, " %03d;", tmpstep); + OUTPUT(buf); + } + else + { // Set + tmpstep = atoi(buf + 8); + if (tmpstep < 0 || tmpstep > 9 || stepvalues[class][tmpstep] == 0) + {cmd_err = 1; continue;} + stepsize[class] = stepvalues[class][tmpstep]; + } + } } else if (buf[0] == 'F' && (buf[1] == 'A' || buf[1] == 'B')) // FA/FB { // VFO {A|B} Frequency @@ -462,7 +506,7 @@ int main(int argc, char *argv[]) OUTPUT(buf); } else if (strncmp(buf, "SF", 2) == 0) - { + { // Sets and Reads the VFO (Frequency and Mode) int tmpvfo, tmpfreq, tmpmode, newband; kvfop_t ovfo, nvfo; @@ -484,18 +528,6 @@ int main(int argc, char *argv[]) *vfoAB[tmpvfo] = nvfo; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } - else if (strncmp(buf, "FL", 2) == 0) - { - switch (buf[2]) { - case '0': // Select the Receive Filter - case '1': // Roofing Filter - case '2': // IF Filter Shape - case '3': // AF Filter Type - continue; // For now - default: - cmd_err = 1; - } - } else if (strcmp(buf, "FR;") == 0) { snprintf(buf, sizeof(buf), "FR%d;", vfo_rx); @@ -526,13 +558,15 @@ int main(int argc, char *argv[]) if (buf[2] == ';') { // Setting 2 - /* The TS-890S doesn't have a real BAND_UP/BAND_DOWN commnd - * This one just does a simple UP/DOWN. As the manual says, just - * like pushing the UP/DOWN button on the mic - */ - newfreq = ovfo->freq + dir * 1000; // Needs to be tracked by mode - // Checking for band edges needs to go here - ovfo->freq = newfreq; + /* The TS-890S doesn't have a real BAND_UP/BAND_DOWN command + * This one just does a simple UP/DOWN. As the manual says, just + * like pushing the UP/DOWN button on the mic + */ + int class = mode2classtab[ovfo->mode]; + if (class < 0 || class > 3) {cmd_err = 3; continue;} // Shouldn't happen + newfreq = ovfo->freq + (dir * stepsize[class]); + //TODO: Checking for band edges needs to go here + ovfo->freq = newfreq; } else if (buf[3] == ';') { // Read @@ -795,38 +829,6 @@ int main(int argc, char *argv[]) { sscanf(buf,"SP%d", &sp); } - else if (strncmp(buf, "BS", 2) == 0) - { // All the Bandscope commands - switch (toupper(buf[2])) { - case '0': // Scope Display ON/OFF - case '1': // Scope Display Type - case '2': // Bandscpoe Operation Mode - case '3': // Bandscope Span - case '4': // Bandscope Span - case '5': // Bandscope Scope Range (Fixed Mode) - case '6': // Bandscope Dispaly Pause - case '7': // Bandscope Marker - case '8': // Bandscope Attenuator - case '9': // Bandscope Max Hold - case 'A': // Bandscope Averaging - case 'B': // Bandscope Waterfall Display Speed - case 'C': // Bandscope Reference Level - case 'D': // Bandscope Waterfall Display Clear - case 'E': // Bandscope Marker Shift / Marker Center - case 'G': // Audio Scope Attenuator - case 'H': // Audio Scope Span - case 'I': // Oscilloscope Level - case 'J': // Oscilloscpoe Sweep Time - case 'K': // Bandscope Shift Position - case 'L': // Bandscope Receive Circuit State - case 'M': // Bandscope Scope Range Lower/Upper Frequency Limit - case 'N': // Audio Scope Display Pause - case 'O': // Expands Spectrum Analysis Range - break; - default: // Unknown - cmd_err = 1; - } - } else if (strncmp(buf, "CK", 2) == 0) { // All the clock functions switch (buf[2]) { @@ -904,7 +906,39 @@ int main(int argc, char *argv[]) default: printf("Bad clock command - %s\n", buf); } - } + } + else if (strncmp(buf, "BS", 2) == 0) + { // All the Bandscope commands + switch (toupper(buf[2])) { + case '0': // Scope Display ON/OFF + case '1': // Scope Display Type + case '2': // Bandscpoe Operation Mode + case '3': // Bandscope Span + case '4': // Bandscope Span + case '5': // Bandscope Scope Range (Fixed Mode) + case '6': // Bandscope Dispaly Pause + case '7': // Bandscope Marker + case '8': // Bandscope Attenuator + case '9': // Bandscope Max Hold + case 'A': // Bandscope Averaging + case 'B': // Bandscope Waterfall Display Speed + case 'C': // Bandscope Reference Level + case 'D': // Bandscope Waterfall Display Clear + case 'E': // Bandscope Marker Shift / Marker Center + case 'G': // Audio Scope Attenuator + case 'H': // Audio Scope Span + case 'I': // Oscilloscope Level + case 'J': // Oscilloscpoe Sweep Time + case 'K': // Bandscope Shift Position + case 'L': // Bandscope Receive Circuit State + case 'M': // Bandscope Scope Range Lower/Upper Frequency Limit + case 'N': // Audio Scope Display Pause + case 'O': // Expands Spectrum Analysis Range + break; + default: // Unknown + cmd_err = 1; + } + } else if (strncmp(buf, "CM", 2) == 0) { // CW Message Memory switch (buf[2]) { @@ -921,6 +955,57 @@ int main(int argc, char *argv[]) cmd_err = 1; // Unknown command } } + else if (strncmp(buf, "FL", 2) == 0) + { + switch (buf[2]) { + case '0': // Select the Receive Filter + case '1': // Roofing Filter + case '2': // IF Filter Shape + case '3': // AF Filter Type + continue; // For now + default: + cmd_err = 1; + } + } + else if (strncmp(buf, "FM", 2) == 0) + { // Frequency Markers + switch (buf[2]) { + case '0': // Frequency Marker Function + case '1': // Frequency Marker List Regiatration + case '2': // Total Number Registered of Frequency Marker List + case '3': // Frequency Marker List Readout + case '4': // Frequency Marker List Delete + break; + default: + cmd_err = 1; + } + } + else if (strncmp(buf, "IP", 2) == 0) + { // Network Config + switch (buf[2]) { + case '0': // DHCP + case '1': // IP Address (Manual Configuration) + case '2': // MAC Address + break; + default: + cmd_err = 1; + } + } + else if (strncmp(buf, "LA", 2) == 0) + { // Linear Amplifier Configuration + switch (buf[2]) { + case '0': // Target Band of Linear Amplifier Menu + case '1': // Linear Amplifier ON/OFF + case '2': // Linear Amplifier Transmission Control + case '3': // Linear Amplifier Transmission Delay ON/OFF + case '4': // Linear Amplifier Transmission Delay Time + case '5': // Linear Amplifier Relay Control + case '6': // Linear Amplifier External ALC Voltage + break; + default: + cmd_err = 1; + } + } else if (strncmp(buf, "MA", 2) == 0) { // Memory Channel Functions switch (buf[2]) { @@ -937,6 +1022,21 @@ int main(int argc, char *argv[]) cmd_err = 1; } } + else if (strncmp(buf, "PB", 2) == 0) + { // Voice Messages + switch (buf[2]) { + case '0': // Voice Message List Display + case '1': // Voice Message Playback, etc. + case '2': // Voice Message Channel Registration State + case '3': // Voice Message Channel Repeat + case '4': // Voice Message Channel Name + case '5': // Voice Message Recording Sound Source + case '6': // Voice Message Recording Total Remaining Time + break; + default: + cmd_err = 1; + } + } else if (strncmp(buf, "SC", 2) == 0) { // Scan functions switch (buf[2]) { commit d209c655b0bb32706d2e1b96907ada54fa3205eb Author: George Baltz N3GB <Geo...@gm...> Date: Tue Oct 15 19:32:37 2024 -0400 Change FA/FB/SF to use band memories Change name of kvfo_t to denote it's a pointer Add routines to convert freq to band and to get a new band's vfo diff --git a/simulators/simts890.c b/simulators/simts890.c index 8fcf91a6a..a7f7f3e38 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -77,12 +77,13 @@ typedef struct kvfo { int freq; int mode; short band, vfo; // Redundant, but useful for relative movement -} *kvfo_t; +} *kvfop_t; int nummems = 3; // Default - values = 1, 3, 5 int bandslot[2][NBANDS]; // 0-based band memory: ((bandslot[i] + 1) % nummems) (+1 for display) /* Storage and default data for band memories + * vfoA freq and mode initialized here, vfoB and other items set at startup * 1, 3(default), or 5 memories per band can be used. One is always active on * each band. Manually they are selected by multiple band button pushes; CAT * selection is by BD/BU command @@ -115,6 +116,31 @@ struct kvfo band_mem[2][NBANDS][5] = { { #endif } }; +/* Band definitions + * differ by model + */ +struct band_def { + int low; + int high; +}; +struct band_def band_limits[NBANDS] = { +#if MODEL == K + { 1800000, 2000000}, { 3500000, 4000000}, { 7000000, 7300000}, + {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, + {21000000, 21450000}, {24890000, 24990000}, {28000000, 29700000}, + {50000000, 54000000}, { 30000, 60000000} +#else + { 1810000, 2000000}, { 3500000, 3800000}, { 7000000, 7200000}, + {10100000, 10150000}, {14000000, 14350000}, {18068000, 18168000}, + {21000000, 21450000}, {24890000, 24990000}, {28000000, 29000000}, + {50000000, 52000000}, { 30000, 74800000} +#endif +}; + +/* Function prototypes */ +int freq2band(int freq); +kvfop_t newvfo(kvfop_t ovfo, int band); + #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices { @@ -189,8 +215,8 @@ int main(int argc, char *argv[]) char *err_txt[] = { "?;", "E;", "O;" }; struct kvfo *vfoA = &band_mem[0][4][0], *vfoB = &band_mem[1][6][0]; - const kvfo_t *vfoAB[2] = {&vfoA, &vfoB}; // 0=A, 1=B, fixed - kvfo_t *vfoLR[2] = {&vfoA, &vfoB}; // 0=Left, 1=Right, can change + kvfop_t * const vfoAB[2] = {&vfoA, &vfoB}; // 0=A, 1=B, fixed + kvfop_t *vfoLR[2] = {&vfoA, &vfoB}; // 0=Left, 1=Right, can change /* The IF command is not documented for the TS-890S, and is supposed * to be supplanted by SF. However, it is still there for legacy S/W. @@ -400,10 +426,15 @@ int main(int argc, char *argv[]) } else { - int tmpfreq; + int tmpfreq, newband; + kvfop_t ovfo, nvfo; sscanf(buf + 2, "%d", &tmpfreq); - // TODO: Check and decode freq. Check band and set vfo to band mem. - (*vfoAB[idx])->freq = tmpfreq; + newband = freq2band(tmpfreq); + if (newband < 0) {cmd_err = 1; continue; } + ovfo = *vfoAB[idx]; + nvfo = newvfo(ovfo, newband); + nvfo->freq = tmpfreq; + *vfoAB[idx] = nvfo; } } else if (strncmp(buf, "AI;", 3) == 0) @@ -432,7 +463,8 @@ int main(int argc, char *argv[]) } else if (strncmp(buf, "SF", 2) == 0) { - int tmpvfo, tmpfreq, tmpmode; + int tmpvfo, tmpfreq, tmpmode, newband; + kvfop_t ovfo, nvfo; if (sscanf(buf, SFformat, &tmpvfo, &tmpfreq, &tmpmode) != 3 || tmpvfo < 0 || tmpvfo > 1) @@ -443,9 +475,13 @@ int main(int argc, char *argv[]) } //printf("tmpvfo=%d, tmpfreq=%d, tmpmode=%d\n", tmpvfo, tmpfreq, tmpmode); - (*vfoAB[tmpvfo])->mode = tmpmode; - (*vfoAB[tmpvfo])->freq = tmpfreq; - + ovfo = *vfoAB[tmpvfo]; + newband = freq2band(tmpfreq); + if (newband < 0) {cmd_err = 1; continue; } + nvfo = newvfo(ovfo, newband); + nvfo->mode = tmpmode; + nvfo->freq = tmpfreq; + *vfoAB[tmpvfo] = nvfo; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } else if (strncmp(buf, "FL", 2) == 0) @@ -484,9 +520,9 @@ int main(int argc, char *argv[]) } else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD { // Frequency Band Selection(Setting 1)/[UP}/{DOWN] Operating(Setting 2) - int band, cycle, idx, newfreq; + int band, idx, newfreq; int dir = buf[1] == 'D' ? -1 : +1; - kvfo_t ovfo = *vfoLR[0]; // Current operating VFO + kvfop_t ovfo = *vfoLR[0]; // Current operating VFO if (buf[2] == ';') { // Setting 2 @@ -500,20 +536,20 @@ int main(int argc, char *argv[]) } else if (buf[3] == ';') { // Read - idx = buf[2] - '0'; - if (idx < 0 || idx > 1) {cmd_err = 1; continue;} - snprintf(buf + 3, sizeof(buf) - 3, "%d;", bandslot[idx][ovfo->band]); - OUTPUT(buf); + idx = buf[2] - '0'; + if (idx < 0 || idx > 1) {cmd_err = 1; continue;} + snprintf(buf + 3, sizeof(buf) - 3, "%d;", bandslot[idx][ovfo->band] + 1); + OUTPUT(buf); } else if (buf[5] == ';') { // Setting 1 - band = atoi(buf + 3); - if (band < 0 || band >= NBANDS) {cmd_err = 1; continue;} - if (band == ovfo->band) - { // Same band, just cycle the band memory # + band = atoi(buf + 3); + if (band < 0 || band >= NBANDS) {cmd_err = 1; continue;} + if (band == ovfo->band) + { // Same band, cycle the band memory # bandslot[ovfo->vfo][band] = (bandslot[ovfo->vfo][band] + 1) % nummems; } - *(vfoLR[0]) = &band_mem[ovfo->vfo][band][bandslot[ovfo->vfo][band]]; + *vfoLR[0] = newvfo(ovfo, band); } else { @@ -922,3 +958,42 @@ int main(int argc, char *argv[]) return 0; } + +/* Convert freq to TS-890S band # + * + * Input freq in Hz + * + * Returns band # or negative if invalid input + */ +int freq2band(int freq) +{ + int i, retval = -1; // Assume the worst + + for ( i = 0; i < NBANDS; i++ ) + { + if ( freq >= band_limits[i].low && freq <= band_limits[i].high ) + { + retval = i; + break; + } + } + //printf("%dHz is in band # %d\n", freq, retval); + + return retval; +} + +/* Get appropriate vfo for new frequency + * + * Input: current vfo + * new band + * Return: new vfo pointer + */ +kvfop_t newvfo(kvfop_t ovfo, int band) +{ + int vfonum, slot; + + vfonum = ovfo->vfo; + slot = bandslot[vfonum][band]; + + return &band_mem[vfonum][band][slot]; +} commit 8bbf60d5c87f556a2093b7088b5cc14203c292e0 Author: George Baltz N3GB <Geo...@gm...> Date: Fri Oct 11 16:12:50 2024 -0400 More VFOs as objects. Add band memory objects. Use them to implement BD/BU. Default to Model K; E as compile time option Would have been easier as real OOP objects; C syntax is clunky, and the parentheses look weird. Oh well. Still TODO: tie all the other frequency settings into band memories. May need some storage rearrangement to make functions cleaner. diff --git a/simulators/simts890.c b/simulators/simts890.c index f827f14c0..8fcf91a6a 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -20,7 +20,9 @@ struct ip_mreq #include <hamlib/rig.h> #define BUFSIZE 256 - +#define NBANDS 11 +/* Model we're emulating - K=The Americas, E=Europe */ +#define MODEL K /* Define a macro for sending response back to the app * This will allow us to reroute output to a buffering routine * Needed to handle multiple commands in a single message @@ -31,9 +33,7 @@ int mysleep = 20; int filternum1 = 7; int filternum2 = 8; -int datamode = 0; int vfo_rx, vfo_tx, ptt, ptt_data, ptt_mic, ptt_tune; -int operatingband; int split = 0; int keyspd = 20; int sl=3, sh=3; @@ -76,11 +76,44 @@ int tfset = 0; typedef struct kvfo { int freq; int mode; + short band, vfo; // Redundant, but useful for relative movement } *kvfo_t; -struct kvfo temp1 = {14074000, 1}; -struct kvfo temp2 = {14073500, 2}; +int nummems = 3; // Default - values = 1, 3, 5 +int bandslot[2][NBANDS]; // 0-based band memory: ((bandslot[i] + 1) % nummems) (+1 for display) +/* Storage and default data for band memories + * 1, 3(default), or 5 memories per band can be used. One is always active on + * each band. Manually they are selected by multiple band button pushes; CAT + * selection is by BD/BU command + */ +struct kvfo band_mem[2][NBANDS][5] = { { +#if MODEL==K + /* 160M */ { { 1800000, 3}, { 1810000, 3}, { 1820000, 3}, { 1830000, 3}, { 1840000, 3} }, + /* 80M */ { { 3500000, 1}, { 3600000, 1}, { 3700000, 1}, { 3800000, 1}, { 3900000, 1} }, + /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, + /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, + /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, + /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, + /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, + /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, + /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, + /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, + /* GENE */ { { 135700, 3}, { 472000, 3}, { 1000000, 5}, { 5305500, 2}, { 5403500, 2} } +#else // MODEL==E + /* 160M */ { { 1830000, 3}, { 1840000, 3}, { 1850000, 3}, { 1820000, 3}, { 1820000, 3} }, + /* 80M */ { { 3500000, 1}, { 3550000, 1}, { 3600000, 1}, { 3650000, 1}, { 3700000, 1} }, + /* 40M */ { { 7000000, 1}, { 7050000, 1}, { 7100000, 1}, { 7150000, 1}, { 7200000, 1} }, + /* 30M */ { {10100000, 3}, {10110000, 3}, {10120000, 3}, {10130000, 3}, {10140000, 3} }, + /* 20M */ { {14000000, 2}, {14100000, 2}, {14150000, 2}, {14200000, 2}, {14250000, 2} }, + /* 17M */ { {18068000, 2}, {18100000, 2}, {18110000, 2}, {18150000, 2}, {18160000, 2} }, + /* 15M */ { {21000000, 2}, {21100000, 2}, {21150000, 2}, {21200000, 2}, {21300000, 2} }, + /* 12M */ { {24890000, 2}, {24920000, 2}, {24940000, 2}, {24960000, 2}, {24980000, 2} }, + /* 10M */ { {28000000, 2}, {28300000, 2}, {28500000, 2}, {29000000, 4}, {29300000, 4} }, + /* 6M */ { {50000000, 2}, {50125000, 2}, {50200000, 2}, {51000000, 4}, {52000000, 4} }, + /* GENE */ { {70100000, 2}, { 135700, 3}, { 472000, 5}, { 999000, 5}, { 5258500, 2} } +#endif +} }; #if defined(WIN32) || defined(_WIN32) int openPort(char *comport) // doesn't matter for using pts devices @@ -155,9 +188,9 @@ int main(int argc, char *argv[]) int cmd_err = 0; char *err_txt[] = { "?;", "E;", "O;" }; - struct kvfo *vfoA = &temp1, *vfoB = &temp2; - const kvfo_t vfoAB[2] = {vfoA, vfoB}; // 0=A, 1=B, fixed - kvfo_t vfoLR[2] = {vfoA, vfoB}; // 0=Left, 1=Right, can change + struct kvfo *vfoA = &band_mem[0][4][0], *vfoB = &band_mem[1][6][0]; + const kvfo_t *vfoAB[2] = {&vfoA, &vfoB}; // 0=A, 1=B, fixed + kvfo_t *vfoLR[2] = {&vfoA, &vfoB}; // 0=Left, 1=Right, can change /* The IF command is not documented for the TS-890S, and is supposed * to be supplanted by SF. However, it is still there for legacy S/W. @@ -184,6 +217,17 @@ int main(int argc, char *argv[]) "%011d" // P2 Freq(Hz) "%1X;"; // P3 Mode + /* Initialization */ + for (int i = 0; i < NBANDS; i++) + { + for (int j = 0; j < 5; j++) + { + band_mem[1][i][j] = band_mem[0][i][j]; + band_mem[1][i][j].vfo = 1; + band_mem[0][i][j].band = band_mem[1][i][j].band = i; + } + } + while (1) { hl_usleep(10); @@ -201,15 +245,17 @@ int main(int argc, char *argv[]) // printf("Cmd:\"%s\"\n", buf); } - // else { return 0; } + buf[0] = toupper(buf[0]); + buf[1] = toupper(buf[1]); + if (strcmp(buf, "IF;") == 0) { char ifbuf[256]; hl_usleep(mysleep * 1000); - sprintf(ifbuf, IFformat, vfoLR[0]->freq, - (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, vfoLR[0]->mode); + sprintf(ifbuf, IFformat, (*vfoLR[0])->freq, + (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, (*vfoLR[0])->mode); OUTPUT(ifbuf); } else if (strncmp(buf, "AN", 2) == 0) @@ -319,32 +365,46 @@ int main(int argc, char *argv[]) snprintf(buf, sizeof(buf), "ID%03d;", id); OUTPUT(buf); } - else if (strcmp(buf, "EX00011;") == 0) - { - pbuf = "EX00011 001;"; - OUTPUT(pbuf); - } else if (strncmp(buf, "EX", 2) == 0) - { - continue; - } - else if (strcmp(buf, "FA;") == 0) - { - snprintf(buf, sizeof(buf), "FA%011d;", vfoA->freq); - OUTPUT(buf); - } - else if (strcmp(buf, "FB;") == 0) - { - snprintf(buf, sizeof(buf), "FB%011d;", vfoB->freq); - OUTPUT(buf); - } - else if (strncmp(buf, "FA", 2) == 0) - { - sscanf(buf, "FA%d", &vfoA->freq); + { // Menu Setting + if (strcmp(buf + 2, "00011;") == 0) + { // S-Meter Scale + pbuf = "EX00011 001;"; + OUTPUT(pbuf); + } + else if (strncmp(buf + 2, "00311", 5) == 0) + { // Number of Band Memories + if(buf[7] == ';') + { + snprintf(buf, sizeof buf, "EX00311 %03d;", nummems / 2); // Rounds down + OUTPUT(buf); + } + else + { + int temp = -1; + sscanf(buf + 8, "%3d", &temp); + if (temp < 2 && temp >= 0) + { nummems = temp * 2 + 1; } + else + { cmd_err = 1; } + } + } } - else if (strncmp(buf, "FB", 2) == 0) - { - sscanf(buf, "FB%d", &vfoB->freq); + else if (buf[0] == 'F' && (buf[1] == 'A' || buf[1] == 'B')) // FA/FB + { // VFO {A|B} Frequency + int idx = buf[1] - 'A'; + if (buf[2] == ';') + { + snprintf(buf + 2, sizeof(buf) - 2, "%011d;", (*vfoAB[idx])->freq); + OUTPUT(buf); + } + else + { + int tmpfreq; + sscanf(buf + 2, "%d", &tmpfreq); + // TODO: Check and decode freq. Check band and set vfo to band mem. + (*vfoAB[idx])->freq = tmpfreq; + } } else if (strncmp(buf, "AI;", 3) == 0) { @@ -366,7 +426,7 @@ int main(int argc, char *argv[]) continue; } snprintf(buf, sizeof(buf), SFformat, tmpvfo, - vfoAB[tmpvfo]->freq, vfoAB[tmpvfo]->mode); + (*vfoAB[tmpvfo])->freq, (*vfoAB[tmpvfo])->mode); //printf("SF buf=%s\n", buf); OUTPUT(buf); } @@ -383,8 +443,8 @@ int main(int argc, char *argv[]) } //printf("tmpvfo=%d, tmpfreq=%d, tmpmode=%d\n", tmpvfo, tmpfreq, tmpmode); - vfoAB[tmpvfo]->mode = tmpmode; - vfoAB[tmpvfo]->freq = tmpfreq; + (*vfoAB[tmpvfo])->mode = tmpmode; + (*vfoAB[tmpvfo])->freq = tmpfreq; printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } @@ -422,20 +482,50 @@ int main(int argc, char *argv[]) split = 1; } } - else if (strncmp(buf, "BD;", 3) == 0) - { - continue; - } - else if (strncmp(buf, "BU;", 3) == 0) - { - continue; + else if (buf[0] == 'B' && (buf[1] == 'D' || buf[1] == 'U')) // BU/BD + { // Frequency Band Selection(Setting 1)/[UP}/{DOWN] Operating(Setting 2) + int band, cycle, idx, newfreq; + int dir = buf[1] == 'D' ? -1 : +1; + kvfo_t ovfo = *vfoLR[0]; // Current operating VFO + + if (buf[2] == ';') + { // Setting 2 + /* The TS-890S doesn't have a real BAND_UP/BAND_DOWN commnd + * This one just does a simple UP/DOWN. As the manual says, just + * like pushing the UP/DOWN button on the mic + */ + newfreq = ovfo->freq + dir * 1000; // Needs to be tracked by mode + // Checking for band edges needs to go here + ovfo->freq = newfreq; + } + else if (buf[3] == ';') + { // Read + idx = buf[2] - '0'; + if (idx < 0 || idx > 1) {cmd_err = 1; continue;} + snprintf(buf + 3, sizeof(buf) - 3, "%d;", bandslot[idx][ovfo->band]); + OUTPUT(buf); + } + else if (buf[5] == ';') + { // Setting 1 + band = atoi(buf + 3); + if (band < 0 || band >= NBANDS) {cmd_err = 1; continue;} + if (band == ovfo->band) + { // Same band, just cycle the band memory # + bandslot[ovfo->vfo][band] = (bandslot[ovfo->vfo][band] + 1) % nummems; + } + *(vfoLR[0]) = &band_mem[ovfo->vfo][band][bandslot[ovfo->vfo][band]]; + } + else + { + cmd_err = 1; + } } else if (strcmp(buf, "RX;") == 0) - { + { // Receive Function State ptt = ptt_mic = ptt_data = ptt_tune = 0; } else if (strncmp(buf, "TX", 2) == 0) - { + { // Transmission Mode ptt = ptt_mic = ptt_data = ptt_tune = 0; switch (buf[2]) @@ -450,7 +540,7 @@ int main(int argc, char *argv[]) } } else if (strncmp(buf, "TB;", 3) == 0) - { + { // Split sprintf(buf, "TB%d;", split); OUTPUT(buf); } @@ -458,6 +548,22 @@ int main(int argc, char *argv[]) { sscanf(buf, "TB%d", &split); } + else if (strncmp(buf, "TS", 2) == 0) + { // TF-SET + if (buf[2] == ';') + { + snprintf(buf, sizeof buf, "TS%d;", tfset); + OUTPUT(buf); + } + else if (buf[2] >= '0' && buf[2] < '2') + { + tfset = buf[2] - '0'; + } + else + { + cmd_err = 1; + } + } else if (strncmp(buf, "KS;", 3) == 0) { sprintf(buf, "KS%03d;", keyspd); @@ -483,15 +589,19 @@ int main(int argc, char *argv[]) } else { - sprintf(buf, "OM%d%X;", tmpvfo, vfoLR[tmpvfo]->mode); + sprintf(buf, "OM%d%X;", tmpvfo, (*vfoLR[tmpvfo])->mode); OUTPUT(buf); } - continue; } + else + { /* Setting - Only sets the active function(RX/TX), - * which is always the left VFO. + * which is always the left VFO unless split is active and + * we are transmitting. */ - sscanf(&buf[3], "%1X", &vfoLR[0]->mode); + int idx = split && ((ptt + ptt_mic + ptt_data + ptt_tune) > 0); + sscanf(&buf[3], "%1X", &(*vfoLR[idx])->mode); + } } else if (strncmp(buf, "RM", 2) == 0) { // Meter control/readout @@ -793,32 +903,16 @@ int main(int argc, char *argv[]) } else if (strncmp(buf, "SC", 2) == 0) { // Scan functions - switch (buf[2]) { - case '0': // Scan - case '1': // Scan Speed - case '2': // Tone Scan/CTCSS Scan - case '3': // Program Scan/VFO Scan Selection - break; - default: - cmd_err = 1; + switch (buf[2]) { + case '0': // Scan + case '1': // Scan Speed + case '2': // Tone Scan/CTCSS Scan + case '3': // Program Scan/VFO Scan Selection + break; + default: + cmd_err = 1; } } - else if (strncmp(buf, "TS", 2) == 0) - { // TF-SET - if (buf[2] == ';') - { - snprintf(buf, sizeof buf, "TS%d;", tfset); - OUTPUT(buf); - continue; - } - int tmpset = buf[2] - '0'; - if (tmpset < 0 || tmpset > 1) - { - cmd_err = 1; - continue; - } - tfset = tmpset; - } else if (strlen(buf) > 0) { fprintf(stderr, "Unknown command: %s\n", buf); commit 7aa739a97d5b5f3803a0940ac74f6955d77b26ed Author: George Baltz N3GB <Geo...@gm...> Date: Tue Oct 8 11:11:03 2024 -0400 Get rid of ghost commands. They ain't coming back. diff --git a/simulators/simts890.c b/simulators/simts890.c index 1ba3769db..f827f14c0 100644 --- a/simulators/simts890.c +++ b/simulators/simts890.c @@ -212,19 +212,6 @@ int main(int argc, char *argv[]) (ptt + ptt_mic + ptt_data + ptt_tune) > 0 ? 1 : 0, vfoLR[0]->mode); OUTPUT(ifbuf); } -#if 0 - else if (strncmp(buf, "RM2", 3) == 0) - { - pbuf = "RM20020;"; - OUTPUT(pbuf); - } - else if (strcmp(buf, "RM5;") == 0) - { - hl_usleep(mysleep * 1000); - pbuf = "RM5100000;"; - OUTPUT(pbuf); - } -#endif else if (strncmp(buf, "AN", 2) == 0) { // Antenna connection handling hl_usleep(mysleep * 1000); @@ -325,19 +312,6 @@ int main(int argc, char *argv[]) { sscanf(buf,"PC%d", &pc); } -#if 0 - else if (strcmp(buf, "FW1;") == 0) - { - //usleep(mysleep * 1000); - pbuf = "FW10;"; - OUTPUT(pbuf); - hl_usleep(20 * 1000); - } - else if (strncmp(buf, "FW", 2) == 0) - { - continue; - } -#endif else if (strcmp(buf, "ID;") == 0) { hl_usleep(mysleep * 1000); @@ -345,18 +319,6 @@ int main(int argc, char *argv[]) snprintf(buf, sizeof(buf), "ID%03d;", id); OUTPUT(buf); } - -#if 0 - else if (strncmp(buf, "AI", 2) == 0) - { - if (strcmp(buf, "AI;")) - { - hl_usleep(mysleep * 1000); - n = fprintf(fp, "%s", "AI0;"); - } - } - -#endif else if (strcmp(buf, "EX00011;") == 0) { pbuf = "EX00011 001;"; @@ -426,18 +388,6 @@ int main(int argc, char *argv[]) printf("modeA=%X, modeB=%X\n", vfoA->mode, vfoB->mode); } -#if 0 - else if (strncmp(buf, "MD;", 3) == 0) - { - snprintf(buf, sizeof(buf), "MD%d;", - vfoA->mode); // not worried about modeB yet for simulator - OUTPUT(buf); - } - else if (strncmp(buf, "MD", 2) == 0) - { - sscanf(buf, "MD%d", &vfoA->mode); // not worried about modeB yet for simulator - } -#endif else if (strncmp(buf, "FL", 2) == 0) { switch (buf[2]) { @@ -472,17 +422,6 @@ int main(int argc, char *argv[]) split = 1; } } -#if 0 - else if (strncmp(buf, "DA;", 3) == 0) - { - snprintf(buf, sizeof(buf), "DA%d;", datamode); - OUTPUT(buf); - } - else if (strncmp(buf, "DA", 2) == 0) - { - sscanf(buf, "DA%d", &datamode); - } -#endif else if (strncmp(buf, "BD;", 3) == 0) { continue; @@ -510,18 +449,6 @@ int main(int argc, char *argv[]) break; } } -#if 0 - else if (strncmp(buf, "CB;", 3) == 0) - { - printf("No CB command!\n"); - sprintf(buf, "CB%d;", operatingband); - OUTPUT(buf); - } - else if (strncmp(buf, "CB", 2) == 0) - { - sscanf(buf, "CB... [truncated message content] |