diff --git a/Bandscope.ino b/Bandscope.ino
index 3054841..2f952dc 100644
--- a/Bandscope.ino
+++ b/Bandscope.ino
@@ -237,14 +237,8 @@ static uint16_t chunkIndex;
if ( numberOfWebsocketClients > 0 ) // Start off the json document for the scan
{
- jsonDocument.clear ();
chunkIndex = 0;
-
- jsonDocument["PreAmp"] = setting.PreampGain;
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = 0;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
+ initChunkSweepDoc (autoSweepStep);
Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
@@ -395,12 +389,8 @@ static uint16_t chunkIndex;
if ( ( chunkIndex >= wiFiPoints ) || !jsonDocInitialised ) // Start new jSon document
{
chunkIndex = 0;
- jsonDocument.clear();
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = autoSweepStep;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
- Points = jsonDocument.createNestedArray ("Points" ); // Add Points array
+ initChunkSweepDoc (autoSweepStep);
+ Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
}
diff --git a/IFsweep.ino b/IFsweep.ino
index f91d843..c8e003e 100644
--- a/IFsweep.ino
+++ b/IFsweep.ino
@@ -120,6 +120,7 @@ static uint16_t chunkIndex;
} // initSweep || changedSetting
autoSweepStep = 0; // Set the step counter to zero
+ sweepStep = 0;
autoSweepFreq = startFreq_IF; // Set the start frequency.
nextPointFreq = autoSweepFreq + autoSweepFreqStep;
@@ -142,24 +143,16 @@ static uint16_t chunkIndex;
if ( numberOfWebsocketClients > 0 ) // Start off the json document for the scan
{
- jsonDocument.clear ();
chunkIndex = 0;
-
- jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = 0;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
+ initChunkSweepDoc (sweepStep);
Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
-
else
jsonDocInitialised = false;
#endif // #ifdef USE_WIFI
- sweepStep = 0;
startFreq = startFreq_IF + sigFreq_IF; // Start freq for the LO
stopFreq = stopFreq_IF + sigFreq_IF; // Stop freq for the LO
@@ -315,12 +308,8 @@ static uint16_t chunkIndex;
if ( ( chunkIndex >= wiFiPoints ) || !jsonDocInitialised ) // Start new jSon document
{
chunkIndex = 0;
- jsonDocument.clear();
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = sweepStep;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
- Points = jsonDocument.createNestedArray ("Points" ); // Add Points array
+ initChunkSweepDoc (sweepStep);
+ Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
}
diff --git a/RXsweep.ino b/RXsweep.ino
index 0116113..608639e 100644
--- a/RXsweep.ino
+++ b/RXsweep.ino
@@ -126,6 +126,7 @@ static uint16_t chunkIndex;
} // initSweep || changedSetting
autoSweepStep = 0; // Set the step counter to zero
+ sweepStep = 0;
autoSweepFreq = startFreq_RX; // Set the start frequency.
nextPointFreq = autoSweepFreq + autoSweepFreqStep;
@@ -148,24 +149,16 @@ static uint16_t chunkIndex;
if ( numberOfWebsocketClients > 0 ) // Start off the json document for the scan
{
- jsonDocument.clear ();
chunkIndex = 0;
-
- jsonDocument["PreAmp"] = setting.PreampGain;
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = 0;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
+ initChunkSweepDoc (sweepStep);
Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
-
else
jsonDocInitialised = false;
#endif // #ifdef USE_WIFI
- sweepStep = 0;
startFreq = startFreq_RX; // Start freq for the RX
stopFreq = stopFreq_RX; // Stop freq for the RX
@@ -322,12 +315,8 @@ static uint16_t chunkIndex;
if ( ( chunkIndex >= wiFiPoints ) || !jsonDocInitialised ) // Start new jSon document
{
chunkIndex = 0;
- jsonDocument.clear();
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = sweepStep;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
- Points = jsonDocument.createNestedArray ("Points" ); // Add Points array
+ initChunkSweepDoc (sweepStep);
+ Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
}
diff --git a/SigLo.ino b/SigLo.ino
index d1a5f99..fbfaa7e 100644
--- a/SigLo.ino
+++ b/SigLo.ino
@@ -107,6 +107,11 @@ void initSigLow()
oldFreq = 0; // Force write of frequency on first loop
+#ifdef USE_WIFI
+ if ( numberOfWebsocketClients > 0 )
+ pushSigGenSettings ();
+#endif
+
}
@@ -119,6 +124,10 @@ void initSigLow()
void doSigGenLow ()
{
static uint32_t oldIF; // to store the current IF
+ static uint16_t oldSigGenOutputOn;
+ float p; // temporary variable for slider percent
+ static uint16_t sliderRange = ATTENUATOR_RANGE + RX_SI4432_MAX_DRIVE * 3;
+
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
@@ -127,6 +136,29 @@ void doSigGenLow ()
showUpDownButtons = 1;
#endif
+ if (changedSetting) {
+ // calculate required drive and attenuator settings
+ // keep drive as high as possible so nasties are attenuated
+ uint16_t sgRXDrive = RX_SI4432_MAX_DRIVE;
+ uint16_t attenuation = sigGenSetting.Calibration - sigGenSetting.Power;
+ if (attenuation > ATTENUATOR_RANGE )
+ {
+ int16_t diff = attenuation - ATTENUATOR_RANGE;
+ sgRXDrive = RX_SI4432_MAX_DRIVE - (int16_t)( (diff-1)/3 ) - 1 ;
+ attenuation = ATTENUATOR_RANGE - 2 + (diff-1)%3;
+ }
+ SetSGRxDrive(sgRXDrive);
+ att.SetAtten(attenuation);
+ Serial.printf("sigGenLow - rxDrive set to %i, attenuation set to %i, cal is %i\n", sgRXDrive, attenuation, sigGenSetting.Calibration);
+
+ #ifdef USE_WIFI
+ if ( numberOfWebsocketClients > 0 )
+ pushSigGenSettings ();
+ #endif
+
+ changedSetting = false;
+ }
+
// Get current touch state and coordinates
boolean pressed = tft.getTouch(&t_x, &t_y); // Just uses standard TFT_eSPI function as not bothered about speed
@@ -154,6 +186,7 @@ void doSigGenLow ()
case 5:
case 6:
incrementFreq( pow(10, 8-b) );
+ changedSetting=true;
break;
case 7: // Decrement buttons
@@ -164,6 +197,7 @@ void doSigGenLow ()
case 12:
case 13:
decrementFreq( pow(10, 15-b) );
+ changedSetting=true;
break;
case 14: // Return to SAlo mode
@@ -172,21 +206,6 @@ void doSigGenLow ()
case 15: // toggle the output on/off
sigGenOutputOn = !sigGenOutputOn;
- if (sigGenOutputOn) {
- SetRX(3); // both LO and RX in transmit. Output levels have been set in the init function
- key[b].drawButton(true, sig_keys[b].activeText);
- tft.setCursor(sig_keys[b].x + 30, sig_keys[b].y);
- tft.fillRect(sig_keys[b].x + 30, sig_keys[b].y, sig_keys[b].x + 60, sig_keys[b].y + 10, SIG_BACKGROUND_COLOR);
- tft.setTextColor(TFT_GREEN, SIG_BACKGROUND_COLOR );
- tft.print(" ON");
- } else {
- SetRX(1); // Both in receive
- key[b].drawButton(false, sig_keys[b].text);
- tft.setCursor(sig_keys[b].x + 30, sig_keys[b].y);
- tft.fillRect(sig_keys[b].x + 30, sig_keys[b].y, sig_keys[b].x + 60, sig_keys[b].y + 10, SIG_BACKGROUND_COLOR);
- tft.setTextColor(TFT_WHITE, SIG_BACKGROUND_COLOR );
- tft.print("OFF");
- }
break;
case 16: // launch menu
@@ -224,6 +243,33 @@ void doSigGenLow ()
return;
}
}
+
+ // check if state changed - can change from command or from wifi
+ switch (b) {
+ case 15: // On/Off button
+ if (oldSigGenOutputOn != sigGenOutputOn)
+ {
+ if (sigGenOutputOn) {
+ SetRX(3); // both LO and RX in transmit. Output levels have been set in the init function
+ key[b].drawButton(true, sig_keys[b].activeText);
+ tft.setCursor(sig_keys[b].x + 30, sig_keys[b].y);
+ tft.fillRect(sig_keys[b].x + 30, sig_keys[b].y, sig_keys[b].x + 60, sig_keys[b].y + 10, SIG_BACKGROUND_COLOR);
+ tft.setTextColor(TFT_GREEN, SIG_BACKGROUND_COLOR );
+ tft.print(" ON");
+ } else {
+ SetRX(1); // Both in receive
+ key[b].drawButton(false, sig_keys[b].text);
+ tft.setCursor(sig_keys[b].x + 30, sig_keys[b].y);
+ tft.fillRect(sig_keys[b].x + 30, sig_keys[b].y, sig_keys[b].x + 60, sig_keys[b].y + 10, SIG_BACKGROUND_COLOR);
+ tft.setTextColor(TFT_WHITE, SIG_BACKGROUND_COLOR );
+ tft.print("OFF");
+ }
+ changedSetting = true;
+ }
+ break;
+
+ } // on of state change switch
+
} // end of keys loop
@@ -232,12 +278,15 @@ void doSigGenLow ()
// Check if slider touched
if ( sliderPressed( pressed, t_x, t_y) )
{
- float p = sliderPercent( t_x ); // position of slider in %
- float pwr = p * (ATTENUATOR_RANGE)/100.0 + sigGenSetting.Calibration - ATTENUATOR_RANGE;
+ p = sliderPercent( t_x ); // position of slider in %
+ float pwr = p * (sliderRange)/100.0 + sigGenSetting.Calibration - sliderRange;
drawSlider ( SLIDER_X, SLIDER_Y, p, pwr, "dBm" );
- att.SetAtten ( ( 100.0 - p ) / 100.0 * ATTENUATOR_RANGE ); // set attenuator to give required output
sigGenSetting.Power = pwr;
+ changedSetting = true;
+ } else {
+ p = ( sigGenSetting.Power - (sigGenSetting.Calibration - sliderRange) ) * 100.0 / sliderRange;
+ drawSlider ( SLIDER_X, SLIDER_Y, p, sigGenSetting.Power, "dBm" );
}
@@ -266,12 +315,15 @@ void doSigGenLow ()
if (sigGenOutputOn)
{
delayMicroseconds(300);
- SetRX(3);
+ SetRX(3); // both LO and RX in tx mode
}
+ changedSetting = true;
}
oldFreq = sigGenSetting.Frequency;
oldIF = setting.IF_Freq;
+ oldSigGenOutputOn = sigGenOutputOn;
+
}
diff --git a/SweepLo.ino b/SweepLo.ino
index 722a72e..b319a19 100644
--- a/SweepLo.ino
+++ b/SweepLo.ino
@@ -73,6 +73,7 @@ static bool resetAverage; // Flag to indicate a setting has changed and avera
static bool jsonDocInitialised = false;
static uint16_t chunkIndex;
static uint32_t offsetIF; // IF frequency offset by half the bandwidth to position in the centre of the filter
+static uint32_t tgIF; // Track gen IF - SA IF plus any offset if both SI4432 defined
@@ -181,10 +182,20 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
tg_lo.RxMode();
#endif
+#if defined(SI_TG_IF_CS) && defined(SI_TG_LO_CS)
+ if (tgLO_OK && tgIF_OK && (trackGenSetting.Mode == 2) ) // tracking gen as signal generator
+ {
+ tg_if.SetFrequency ( setting.IF_Freq + trackGenSetting.Offset );
+ tg_lo.SetFrequency ( setting.IF_Freq + trackGenSetting.Offset + trackGenSetting.Frequency );
+ tg_lo.TxMode ( trackGenSetting.LO_Drive ); // Set tracking generator LO on
+ tg_if.TxMode ( trackGenSetting.IF_Drive ); // Set tracking generator IF on
+ }
+#endif
} // initSweep || changedSetting
autoSweepStep = 0; // Set the step counter to zero
+ sweepStep = 0;
autoSweepFreq = setting.ScanStart; // Set the start frequency.
nextPointFreq = autoSweepFreq + autoSweepFreqStep;
@@ -207,6 +218,12 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
tempIF = offsetIF;
}
+ // track gen IF follows LO if only one SI4432, otherwise its offset by an amount to reduce blow by
+ if (tgLO_OK)
+ tgIF = tempIF + trackGenSetting.Offset;
+ else
+ tgIF = tempIF;
+
spurToggle = !spurToggle;
@@ -225,7 +242,7 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
#ifdef SI_TG_IF_CS
if (tgIF_OK && (trackGenSetting.Mode == 1) )
- tg_if.SetFrequency ( tempIF + trackGenSetting.Offset ); // Set tracking generator IF for the sweep
+ tg_if.SetFrequency ( tgIF ); // Set tracking generator IF for the sweep
#endif
}
@@ -233,13 +250,11 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
#ifdef SI_TG_LO_CS
if (tgLO_OK && (trackGenSetting.Mode == 1) )
- tg_lo.SetFrequency ( tempIF + autoSweepFreq + trackGenSetting.Offset ); // Set tracking generator LO
+ tg_lo.SetFrequency ( tgIF + autoSweepFreq ); // Set tracking generator LO
#endif
setFreqMicros = micros(); // Store the time the frequency was changed
-// if (trackGenSetting.Mode == 1) // debug
-// Serial.printf("tglo start %i at %i\n", tg_lo.GetFrequency(), setFreqMicros);
/*
* Actual frequency in the SI4432 is rounded and is limited by the possible resolution
@@ -253,22 +268,15 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
{
jsonDocument.clear ();
chunkIndex = 0;
-
- jsonDocument["PreAmp"] = setting.PreampGain; // Fixed gain
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = 0;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
+ initChunkSweepDoc (sweepStep);
Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
-
else
jsonDocInitialised = false;
#endif // #ifdef USE_WIFI
- sweepStep = 0;
startFreq = setting.ScanStart + tempIF; // Start freq for the LO
stopFreq = setting.ScanStop + tempIF; // Stop freq for the LO
@@ -438,7 +446,11 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
{
Serial.println("webSocketTimeout");
Serial.println(wsBuffer);
- numberOfWebsocketClients = 0;
+ websocketFailCount++;
+ if (websocketFailCount > 2)
+ numberOfWebsocketClients = 0;
+ } else {
+ websocketFailCount = 0; // reset if OK
}
// Serial.print("j");
}
@@ -450,12 +462,8 @@ static uint32_t offsetIF; // IF frequency offset by half the bandwidth to pos
if ( ( chunkIndex >= wiFiPoints ) || !jsonDocInitialised ) // Start new jSon document
{
chunkIndex = 0;
- jsonDocument.clear();
- jsonDocument["mType"] = "chunkSweep";
- jsonDocument["StartIndex"] = sweepStep;
- jsonDocument["sweepPoints"] = sweepPoints;
- jsonDocument["sweepTime"] = (uint32_t)(sweepMicros/1000);
- Points = jsonDocument.createNestedArray ("Points" ); // Add Points array
+ initChunkSweepDoc (sweepStep);
+ Points = jsonDocument.createNestedArray ( "Points" ); // Add Points array
jsonDocInitialised = true;
}
}
diff --git a/cmd.cpp b/cmd.cpp
index 291f414..c652e60 100644
--- a/cmd.cpp
+++ b/cmd.cpp
@@ -106,6 +106,7 @@ extern uint32_t colourTest;
extern Marker marker[MARKER_COUNT]; // Array of marker objects
+extern uint16_t sigGenOutputOn; // signal generator state - 0 = off, 1 = on
/*
* Functions still in the main program file. Maybe some need to move here?
@@ -183,6 +184,13 @@ extern uint8_t dBmToRSSI ( double dBm );
{ "RXSWEEP", MSG_RX_SWEEP }, // Set RX Sweep Mode
{ "RXSIGNAL", MSG_RXSIGNAL }, // IF sweep signal frequency
{ "EXTGAIN", MSG_EXTGAIN }, // External gain or attenuation
+ { "SGON", MSG_SGON }, // turn on signal generator output
+ { "SGOFF", MSG_SGOFF }, // turn off signal generator output
+ { "SGFREQ", MSG_SGFREQ }, // Set Signal Generator Frequency
+ { "TRACKON", MSG_TGON }, // turn on tracking generator output
+ { "TRACKOFF", MSG_TGOFF }, // turn off tracking generator output
+ { "TRACKSIG", MSG_TGSIG }, // turn off tracking generator output
+ { "TGFREQ", MSG_TGFREQ }, // Set Track gen freq for sig gen mode
{ "", MSG_NONE } // Unrecognized command
};
@@ -196,7 +204,7 @@ int msgCount = ELEMENTS ( msgTable);
void ShowMenu ()
{
- Serial.printf ( "\nTiny Spectrum Analyzer Version %s - User Commands:\n\n", PROGRAM_VERSION );
+ Serial.printf ( "\nsimpleSA Spectrum Analyzer %s - User Commands:\n\n", PROGRAM_VERSION );
Serial.println ( "Sweep Settings:\n" );
Serial.print ( " START.........Sweep start frequency, currently: " );
@@ -248,25 +256,53 @@ void ShowMenu ()
Serial.printf ( " WFMIN.........Set the minimum RSSI level for waterfall colouring: %i\n", setting.WaterfallMin );
Serial.printf ( " WFGAIN........Set the gain for waterfall colouring: %d\n", setting.WaterfallGain );
- Serial.println ( "\nOther Commands:\n" );
- Serial.print ( " DRIVE.........Local oscillator drive level [0 to 7]; currently: " );
- Serial.println ( setting.Drive );
+ Serial.println ( "\nSignal Generator Commands:\n" );
+
+ Serial.println ( " SGON..........Turn on signal generator output" );
+ Serial.print ( " SGOFF.........Turn off signal generator output; currently " );
+ Serial.println ( sigGenOutputOn );
+
+ Serial.print ( " SGFREQ........Signal Generator frequency, currently: " );
+ Serial.println ( FormatFrequency ( sigGenSetting.Frequency ));
Serial.print ( " SGLODRIVE.....Local oscillator drive level in signal generator mode [0 to 7]; currently: " );
Serial.println ( sigGenSetting.LO_Drive );
- Serial.print ( " SGRXDRIVE.....Local oscillator drive level in signal generator mode [0 to 7]; currently: " );
+ Serial.print ( " SGRXDRIVE.....RX SI4432 oscillator drive level in signal generator mode [0 to ");
+ Serial.print ( RX_SI4432_MAX_DRIVE );
+ Serial.print ( "]; currently: " );
Serial.println ( sigGenSetting.RX_Drive );
+#ifdef SI_TG_IF_CS
+ Serial.println ( "\nTracking Generator Commands:\n" );
+
+ Serial.println ( " TRACKON.......Turn on tracking generator output" );
+#ifdef SI_TG_LO_CS
+ Serial.println ( " TRACKSIG......Turn on tracking generator signal generator output" );
+#endif
+ Serial.print ( " TRACKOFF......Turn off tracking generator output; currently " );
+ Serial.println ( trackGenSetting.Mode );
+
+#ifdef SI_TG_LO_CS
Serial.print ( " TGLODRIVE.....Local oscillator drive level in tracking generator mode [0 to 7]; currently: " );
Serial.println ( trackGenSetting.LO_Drive );
-
+#endif
Serial.print ( " TGIFDRIVE.....Local oscillator drive level in tracking generator mode [0 to 7]; currently: " );
Serial.println ( trackGenSetting.IF_Drive );
-
+#ifdef SI_TG_LO_CS
Serial.print ( " TGOFFSET......Tracking generator offset from SA IF; currently: " );
Serial.println ( trackGenSetting.Offset );
+ Serial.print ( " TGFREQ........Tracking generator signal generator frequency; currently: " );
+ Serial.println ( trackGenSetting.Frequency );
+#endif
+#endif
+
+
+ Serial.println ( "\nOther Commands:\n" );
+
+ Serial.print ( " DRIVE.........Local oscillator drive level [0 to 7]; currently: " );
+ Serial.println ( setting.Drive );
Serial.println ( " SAVE .........Save the current scan configuration [0 to 4]" );
@@ -759,6 +795,29 @@ uint8_t reg69; // Ditto
return true;
+/*
+ * Signal Generator On/Off commands
+ *
+ */
+ case MSG_SGON:
+ SetSGState(1);
+ return true;
+
+ case MSG_SGOFF:
+ SetSGState(0);
+ return true;
+
+ case MSG_SGFREQ:
+ if ( dataLen != 0 ) // Frequency specified?
+ {
+ freq1 = ParseFrequency ( dataBuff ); // Yes, get new frequency
+ SetSGFreq (freq1);
+ }
+ Serial.printf ( "Signal Generator frequency: %i\n", FormatFrequency ( freq1 ));
+ return true;
+
+
+
/*
* The "SGLODRIVE" command sets the local oscillator "drive" level in signal generator mode.
@@ -769,7 +828,7 @@ uint8_t reg69; // Ditto
tempValue = atoi ( dataBuff ); // Yes, convert to a number
if (( tempValue < MIN_DRIVE ) || ( tempValue > MAX_DRIVE ))
- Serial.printf ( "Invalid drive specification: %d\n", tempValue );
+ Serial.printf ( "Invalid LO drive: %d\n", tempValue );
else // Set the transmitter drive level
SetSGLoDrive ( tempValue ); // "SetSGLoDrive" saves the settings
}
@@ -781,17 +840,17 @@ uint8_t reg69; // Ditto
return true;
/*
- * The "SGLODRIVE" command sets the receiver (IF) oscillator "drive" level in signal generator mode.
+ * The "SGRXDRIVE" command sets the receiver (IF) oscillator "drive" level in signal generator mode.
*/
case MSG_SG_RX_DRIVE:
if ( dataLen != 0 ) // Drive level specified?
{
tempValue = atoi ( dataBuff ); // Yes, convert to a number
- if (( tempValue < MIN_DRIVE ) || ( tempValue > MAX_DRIVE ))
- Serial.printf ( "Invalid drive specification: %d\n", tempValue );
+ if (( tempValue < MIN_DRIVE ) || ( tempValue > RX_SI4432_MAX_DRIVE ))
+ Serial.printf ( "Invalid RX drive: %d - (%d-%d)\n", tempValue, MIN_DRIVE, RX_SI4432_MAX_DRIVE );
else // Set the transmitter drive level
- SetSGRxDrive ( tempValue ); // "SetTGRxDrive" saves the settings
+ SetSGRxDrive ( tempValue ); // "SetSGRxDrive" saves the settings
}
Serial.printf ( "SigGen RX Drive: %d (+%udBm)\n", sigGenSetting.RX_Drive, driveLevel[sigGenSetting.RX_Drive] );
@@ -800,8 +859,26 @@ uint8_t reg69; // Ditto
return true;
+/*
+ * Tracking Generator On/Off commands
+ *
+ */
+ case MSG_TGON:
+ SetTracking(1);
+ return true;
+
+ case MSG_TGOFF:
+ SetTracking(0);
+ return true;
+
#ifdef SI_TG_LO_CS
+
+ case MSG_TGSIG:
+ SetTracking(2);
+ return true;
+
+
/*
* The "TGLODRIVE" command sets the local oscillator "drive" level in tracking generator mode.
* (only valid if two SI4432 used for the tracking generator)
@@ -1578,6 +1655,14 @@ uint8_t reg69; // Ditto
Serial.printf ( "Tracking Generator IF offset: %i\n", trackGenSetting.Offset ); // sort out signed version of format frequency!!!!!!!!!!!!!!!!!!!
return true;
+ case MSG_TGFREQ:
+ if ( dataLen != 0 ) // Frequency specified?
+ {
+ freq1 = ParseFrequency ( dataBuff ); // Yes, get new frequency
+ SetTGFreq (freq1);
+ }
+ Serial.printf ( "Tracking Signal Generator frequency: %i\n", FormatFrequency ( trackGenSetting.Frequency ));
+ return true;
/*
@@ -2295,6 +2380,7 @@ void RequestSetPowerLevel ( float o )
/*
* "SetPowerLevel"
+ * Adjusts displayed power to match the actual input signal power - calibration function
*/
void SetPowerLevel ( double o )
@@ -2433,6 +2519,32 @@ int oldLevel = setting.Drive;
}
+/* Set SGFreq sets the signal generator Frequency
+ * Signal generator frequency may change frequently, so don't save the setting
+ * Settings are saved when leaving the mode
+ * parameter is in Hz
+ */
+bool SetSGFreq (uint32_t f)
+{
+ if ( ( f >= MIN_SIGLO_FREQ ) && ( f <= MAX_SIGLO_FREQ ) )
+ {
+ sigGenSetting.Frequency = f;
+ return true;
+ }
+ else
+ return false;
+}
+
+
+/*
+ * Sig gen state is not saved - always want to start in off state
+ */
+
+void SetSGState (uint16_t s)
+{
+ sigGenOutputOn = s;
+}
+
/*
* "SetSGLoDrive" sets the transmitter max output level in signal generator mode.
*
@@ -2479,13 +2591,16 @@ int oldLevel = sigGenSetting.LO_Drive;
* 1 => +2dBm 5 => +14dBm
* 2 => +5dBm 6 => +17dBm
* 3 => +8dBm 7 => +20dBm
+ * Note the power limits of the B3555 SAW filter is 10dBm
+ * RX_SI4432_MAX_DRIVE is set in my_SA.h to suit the attenuator pad and losses
+ * in your build.
*/
void SetSGRxDrive ( uint8_t level )
{
int oldLevel = sigGenSetting.RX_Drive;
- if (( level < 0 ) || ( level > 7 ))
+ if (( level < 0 ) || ( level > RX_SI4432_MAX_DRIVE ))
return;
else
@@ -2503,6 +2618,20 @@ int oldLevel = sigGenSetting.RX_Drive;
}
+void SetSGPower ( int16_t dBm )
+{
+ // Add algorithm to set attenuator and IF drive level
+ // initially limit to just set attenuator
+
+ if ( dBm > sigGenSetting.Calibration )
+ dBm = sigGenSetting.Calibration;
+ if ( dBm < (sigGenSetting.Calibration - ATTENUATOR_RANGE - RX_SI4432_MAX_DRIVE * 3) )
+ dBm = sigGenSetting.Calibration - ATTENUATOR_RANGE;
+
+ sigGenSetting.Power = dBm;
+ changedSetting = true;
+}
+
#ifdef SI_TG_LO_CS
/*
* "SetTGLoDrive" sets the transmitter max output level for the tracking generator.
@@ -2618,6 +2747,28 @@ int32_t GetTGOffset ( )
return trackGenSetting.Offset;
}
+/*
+ * Set the Track Gen frequency - M0WID addition
+ */
+
+bool SetTGFreq ( int32_t freq )
+{
+int32_t oldFreq = trackGenSetting.Frequency;
+
+ if (( freq < MIN_SIGLO_FREQ ) || ( freq > MAX_SIGLO_FREQ )) // If out of limits
+ return false; // Don't change it
+
+ trackGenSetting.Frequency = freq;
+
+ if ( oldFreq != trackGenSetting.Frequency )
+ {
+ changedSetting = true;
+ WriteTrackGenSettings ();
+ }
+
+ return true; // Frequency was good
+}
+
/*
* "SetSweepStart" and "GetSweepStart" were added in Version 2.3. They used to be in
diff --git a/cmd.h b/cmd.h
index b09f970..7ee44f3 100644
--- a/cmd.h
+++ b/cmd.h
@@ -78,6 +78,13 @@
#define MSG_RX_SWEEP 49 // Set the RX Sweep Mode
#define MSG_RXSIGNAL 50 // Set frequency of injected signal for IF Sweep
#define MSG_EXTGAIN 51 // Set external gain or attenuation
+#define MSG_SGON 52 // Turn Signal Generator output on
+#define MSG_SGOFF 53 // Turn Signal Generator output off
+#define MSG_SGFREQ 54 // Set Signal Generator Frequency
+#define MSG_TGON 55 // Turn Tracking Generator output on
+#define MSG_TGOFF 56 // Turn Tracking Generator output off
+#define MSG_TGFREQ 57 // Set Track Gen frequency for sig gen mode
+#define MSG_TGSIG 58 // Set Track Gen sig gen mode
#define MSG_COLOURTEST 99 // test of waterfall colours - remove this when done!
@@ -139,13 +146,17 @@ void SetGenerate ( int8_t g ); // Puts the unit into or out of signal generat
bool SetIFFrequency ( int32_t f ); // Sets the IF frequency
void SetLoDrive ( uint8_t level ); // Sets LO Si4432 output level
+void SetSGState (uint16_t s);
+bool SetSGFreq ( uint32_t freq); // set signal generator frequency - returns false if invalid
void SetSGLoDrive ( uint8_t level );
void SetSGRxDrive ( uint8_t level );
+void SetSGPower ( int16_t dBm ); // Set signal generator attenuator and drive levels
void SetTracking ( int8_t m ); // set tracking generator mode
void SetTGLoDrive ( uint8_t level ); // set tracking generator drive
void SetTGIfDrive ( uint8_t level );
bool SetTGOffset ( int32_t offset); // set tracking generator offset - returns false if invalid
+bool SetTGFreq ( int32_t freq); // set tracking generator freq for sig gen mode - returns false if invalid
int32_t GetTGOffset (void );
void SetTGPower ( int16_t dBm ); // Set TG attenuator and drive levels
diff --git a/data/about.html b/data/about.html
index 64bbb17..9b87ab5 100644
--- a/data/about.html
+++ b/data/about.html
@@ -1,7 +1,7 @@
- [TinySA]
+ [simpleSA]
@@ -46,18 +46,18 @@
About
- The TinySA has been developed by Erik PD0EK.
- This version has been adapted to run on the ESP32 DevKit module by Dave M0WID and John WA2FZW.
+ This simpleSA running on an ESP32 has been adapted by Dave M0WID and John WA2FZW.
+ It was based on an early prototype design of the TinySA by Erik PD0EK.
Information can be found at https://groups.io/g/HBTE