simpleSA/SigLo.ino

335 lines
9.8 KiB
Arduino
Raw Permalink Normal View History

2020-08-16 02:03:43 +08:00
/*
* ########################################################################
*
* 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 );
2020-08-21 19:33:06 +08:00
img.setAttribute ( PSRAM_ENABLE, false ); // Don't use the PSRAM on the WROVERs
img.createSprite ( 320, 55 ); // used for frequency display
2020-08-16 02:03:43 +08:00
img.loadFont(SA_FONT_LARGE);
SetRX ( 1 ); // LO and RX both in receive until turned on by UI
2020-08-21 19:33:06 +08:00
xmit.SetOffset ( 0 ); // make sure frequency offset registers are zero
rcvr.SetOffset ( 0 );
2020-08-16 02:03:43 +08:00
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 );
2020-08-16 02:03:43 +08:00
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
2020-09-30 06:16:59 +08:00
#ifdef USE_WIFI
if ( numberOfWebsocketClients > 0 )
pushSigGenSettings ();
2020-09-30 06:16:59 +08:00
#endif
2020-08-16 02:03:43 +08:00
}
/* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
* Low frequency range signal generator
* '''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''''
*/
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;
2020-08-16 02:03:43 +08:00
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
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;
}
2020-08-16 02:03:43 +08:00
// 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) );
2020-09-30 06:16:59 +08:00
changedSetting=true;
2020-08-16 02:03:43 +08:00
break;
case 7: // Decrement buttons
case 8:
case 9:
case 10:
case 11:
case 12:
case 13:
decrementFreq( pow(10, 15-b) );
2020-09-30 06:16:59 +08:00
changedSetting=true;
2020-08-16 02:03:43 +08:00
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");
}
2020-09-30 06:16:59 +08:00
changedSetting = true;
}
break;
} // on of state change switch
2020-08-16 02:03:43 +08:00
} // end of keys loop
// Check if slider touched
if ( sliderPressed( pressed, t_x, t_y) )
{
p = sliderPercent( t_x ); // position of slider in %
float pwr = p * (sliderRange)/100.0 + sigGenSetting.Calibration - sliderRange;
2020-08-16 02:03:43 +08:00
drawSlider ( SLIDER_X, SLIDER_Y, p, pwr, "dBm" );
sigGenSetting.Power = pwr;
2020-09-30 06:16:59 +08:00
changedSetting = true;
} else {
p = ( sigGenSetting.Power - (sigGenSetting.Calibration - sliderRange) ) * 100.0 / sliderRange;
drawSlider ( SLIDER_X, SLIDER_Y, p, sigGenSetting.Power, "dBm" );
2020-08-16 02:03:43 +08:00
}
// 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);
2020-09-30 06:16:59 +08:00
SetRX(3); // both LO and RX in tx mode
2020-08-16 02:03:43 +08:00
}
2020-09-30 06:16:59 +08:00
changedSetting = true;
2020-08-16 02:03:43 +08:00
}
oldFreq = sigGenSetting.Frequency;
oldIF = setting.IF_Freq;
oldSigGenOutputOn = sigGenOutputOn;
2020-09-30 06:16:59 +08:00
2020-08-16 02:03:43 +08:00
}
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;
}
}