307 lines
8.8 KiB
C++
307 lines
8.8 KiB
C++
|
|
/*
|
|
* ########################################################################
|
|
*
|
|
* Initialise variables and SI4432 for sig gen mode
|
|
*
|
|
* ########################################################################
|
|
*/
|
|
void initSigLow()
|
|
{
|
|
|
|
// Use the TFT_eSPI buttons for now.
|
|
// This could be changed to use something similar to the main menu
|
|
|
|
tft.fillScreen(SIG_BACKGROUND_COLOR);
|
|
|
|
//img.unloadFont(); // Free up memory from any previous incarnation of img
|
|
img.deleteSprite();
|
|
img.setColorDepth ( 16 );
|
|
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
|
img.createSprite ( 320, 55 ); // used for frequency display
|
|
img.loadFont(SA_FONT_LARGE);
|
|
|
|
SetRX ( 1 ); // LO and RX both in receive until turned on by UI
|
|
|
|
xmit.SetOffset ( 0 ); // make sure frequency offset registers are zero
|
|
rcvr.SetOffset ( 0 );
|
|
|
|
#ifdef SI_TG_IF_CS
|
|
if (tgIF_OK) {
|
|
tg_if.RxMode ( ); // turn off the IF oscillator in tracking generator
|
|
}
|
|
#endif
|
|
|
|
#ifdef SI_TG_LO_CS
|
|
if (tgLO_OK) {
|
|
tg_lo.RxMode ( ); // turn off the Local Oscillator in tracking generator
|
|
}
|
|
#endif
|
|
|
|
int showUpDownButtons = 0;
|
|
#ifdef SHOW_FREQ_UP_DOWN_BUTTONS
|
|
showUpDownButtons = 1;
|
|
#endif
|
|
|
|
xmit.SetDrive ( sigGenSetting.LO_Drive ); // Set Local Oscillator power level
|
|
rcvr.SetDrive ( sigGenSetting.RX_Drive ); // Set receiver SI4432 power level
|
|
|
|
tinySA_mode = SIG_GEN_LOW_RANGE;
|
|
setting.Mode = tinySA_mode;
|
|
|
|
tft.unloadFont();
|
|
tft.setCursor ( xOrigin + 50, SCREEN_HEIGHT - CHAR_HEIGHT );
|
|
tft.setTextSize(1);
|
|
tft.setTextColor ( YELLOW );
|
|
tft.printf ( "Mode:%s", modeText[setting.Mode] );
|
|
tft.setTextColor ( WHITE );
|
|
|
|
tft.loadFont(KEY_FONT);
|
|
|
|
// draw the buttons
|
|
for (int i = 0; i < SIG_KEY_COUNT; i++)
|
|
{
|
|
if ( showUpDownButtons || ( i > 13 ))
|
|
{
|
|
key[i].initButton(&tft,
|
|
// x, y, w, h, outline, fill, text
|
|
sig_keys[i].x,
|
|
sig_keys[i].y,
|
|
sig_keys[i].width,
|
|
sig_keys[i].height,
|
|
DARKGREY, // outline colour
|
|
sig_keys[i].color, // fill
|
|
TFT_BLACK, // Text colour
|
|
"", // 10 Byte Label
|
|
2); // font size multiplier (not used when font loaded)
|
|
|
|
// setLabelDatum(uint16_t x_delta, uint16_t y_delta, uint8_t datum)
|
|
key[i].setLabelDatum(1, 1, MC_DATUM);
|
|
|
|
// Draw button and specify label string
|
|
// Specifying label string here will allow more than the default 10 byte label
|
|
key[i].drawButton(false, sig_keys[i].text);
|
|
}
|
|
}
|
|
|
|
// draw the slider to control output level
|
|
// we re-purpose the sSprite for this
|
|
|
|
sSprite.deleteSprite();
|
|
sSprite.setColorDepth ( 16 );
|
|
sSprite.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
|
|
sSprite.createSprite ( SLIDER_WIDTH + 2 * SLIDER_KNOB_RADIUS + 60, 2 * SLIDER_KNOB_RADIUS ); // used for slider and value
|
|
sSprite.setTextColor(TFT_ORANGE);
|
|
sSprite.loadFont(KEY_FONT);
|
|
|
|
// Slider range will be something like -60 to -10dBm for low frequency range
|
|
// (to be changed once I have worked out what the real values should be)
|
|
// Parameter passed in are x, y and slider knob position in %
|
|
|
|
float sPercent = (float)(sigGenSetting.Power - sigGenSetting.Calibration + ATTENUATOR_RANGE) * 100.0
|
|
/ (float)(ATTENUATOR_RANGE);
|
|
|
|
drawSlider(SLIDER_X, SLIDER_Y, sPercent, sigGenSetting.Power, "dBm");
|
|
|
|
att.SetAtten ( sigGenSetting.Calibration - sigGenSetting.Power ); // set attenuator to give required output
|
|
|
|
oldFreq = 0; // Force write of frequency on first loop
|
|
|
|
}
|
|
|
|
|
|
|
|
/* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
|
* Low frequency range signal generator
|
|
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
|
|
*/
|
|
|
|
void doSigGenLow ()
|
|
{
|
|
static uint32_t oldIF; // to store the current IF
|
|
static uint16_t oldSigGenOutputOn;
|
|
|
|
uint16_t t_x = 0, t_y = 0; // To store the touch coordinates
|
|
|
|
int showUpDownButtons = 0;
|
|
#ifdef SHOW_FREQ_UP_DOWN_BUTTONS
|
|
showUpDownButtons = 1;
|
|
#endif
|
|
|
|
|
|
// 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
|
|
|
|
// Adjust press state of each key appropriately
|
|
for (uint8_t b = 0; b < SIG_KEY_COUNT; b++) {
|
|
if (pressed && key[b].contains(t_x, t_y))
|
|
key[b].press(true); // tell the button it is pressed
|
|
else
|
|
key[b].press(false); // tell the button it is NOT pressed
|
|
}
|
|
|
|
// Check if any key has changed state
|
|
for (uint8_t b = 0; b < SIG_KEY_COUNT; b++)
|
|
{
|
|
if ( showUpDownButtons || ( b > 13 ))
|
|
{
|
|
if ( key[b].justPressed() ) {
|
|
switch (b) {
|
|
case 0: // Increment buttons
|
|
case 1:
|
|
case 2:
|
|
case 3:
|
|
case 4:
|
|
case 5:
|
|
case 6:
|
|
incrementFreq( pow(10, 8-b) );
|
|
break;
|
|
|
|
case 7: // Decrement buttons
|
|
case 8:
|
|
case 9:
|
|
case 10:
|
|
case 11:
|
|
case 12:
|
|
case 13:
|
|
decrementFreq( pow(10, 15-b) );
|
|
break;
|
|
|
|
case 14: // Return to SAlo mode
|
|
key[b].drawButton(true, sig_keys[b].activeText);
|
|
break;
|
|
|
|
case 15: // toggle the output on/off
|
|
sigGenOutputOn = !sigGenOutputOn;
|
|
break;
|
|
|
|
case 16: // launch menu
|
|
key[b].drawButton(true, sig_keys[b].activeText);
|
|
break;
|
|
|
|
default:
|
|
Serial.printf("Button %i press not handled", b );
|
|
break;
|
|
}
|
|
}
|
|
}
|
|
|
|
|
|
if (key[b].isPressed()) { // button held
|
|
return;
|
|
}
|
|
|
|
|
|
// // If button was just released
|
|
if (key[b].justReleased())
|
|
{
|
|
switch (b) {
|
|
case 14: // Return to SAlo mode
|
|
WriteSigGenSettings ();
|
|
initSweepLow();
|
|
break;
|
|
|
|
case 16: // launch signal generator menu
|
|
StartSigGenMenu ( );
|
|
return;
|
|
|
|
case 17: // launch frequency keypad
|
|
StartSigGenFreq ( );
|
|
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");
|
|
}
|
|
}
|
|
break;
|
|
|
|
} // on of state change switch
|
|
|
|
|
|
} // end of keys loop
|
|
|
|
|
|
|
|
// 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;
|
|
|
|
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;
|
|
}
|
|
|
|
|
|
|
|
// draw frequency. Uses a sprite to avoid flicker
|
|
img.fillSprite(SIG_BACKGROUND_COLOR);
|
|
img.setCursor(5,5);
|
|
img.setTextColor(TFT_ORANGE);
|
|
img.printf("%s",DisplayFrequency ( sigGenSetting.Frequency ) );
|
|
img.pushSprite(0,80);
|
|
|
|
|
|
/*
|
|
* set RX to IF_Frequency and LO to IF plus required frequency
|
|
*
|
|
* but only if value has changed to avoid the SI4432 running its state change sequencer
|
|
* The mixer will produce IF + LO and IF - LO
|
|
* The Low pass filter will filter out the higher frequency and LO leakage
|
|
* The IF SAW filter will smooth out the waveform produced by the SI4432
|
|
*/
|
|
if ( (oldFreq != sigGenSetting.Frequency) || (oldIF != setting.IF_Freq) )
|
|
{
|
|
rcvr.SetFrequency ( setting.IF_Freq );
|
|
xmit.SetFrequency ( setting.IF_Freq + sigGenSetting.Frequency );
|
|
Serial.println("set frequency");
|
|
if (sigGenOutputOn)
|
|
{
|
|
delayMicroseconds(300);
|
|
SetRX(3);
|
|
}
|
|
}
|
|
|
|
oldFreq = sigGenSetting.Frequency;
|
|
oldIF = setting.IF_Freq;
|
|
oldSigGenOutputOn = sigGenOutputOn;
|
|
}
|
|
|
|
|
|
void incrementFreq(uint32_t amount) {
|
|
sigGenSetting.Frequency += amount;
|
|
if (sigGenSetting.Frequency > MAX_SIGLO_FREQ)
|
|
sigGenSetting.Frequency = MAX_SIGLO_FREQ;
|
|
}
|
|
|
|
void decrementFreq(uint32_t amount) {
|
|
|
|
if (sigGenSetting.Frequency > amount) {
|
|
sigGenSetting.Frequency -= amount;
|
|
if (sigGenSetting.Frequency < MIN_SIGLO_FREQ)
|
|
sigGenSetting.Frequency = MIN_SIGLO_FREQ;
|
|
} else {
|
|
sigGenSetting.Frequency = MIN_SIGLO_FREQ;
|
|
}
|
|
}
|