kopia lustrzana https://github.com/UU5JPP/Wolf-LITE
359 wiersze
11 KiB
C
359 wiersze
11 KiB
C
#include "stm32f4xx_hal.h"
|
|
#include "main.h"
|
|
#include "trx_manager.h"
|
|
#include "functions.h"
|
|
#include "lcd.h"
|
|
#include "fpga.h"
|
|
#include "settings.h"
|
|
#include "wm8731.h"
|
|
#include "fpga.h"
|
|
#include "bands.h"
|
|
#include "agc.h"
|
|
#include "audio_filters.h"
|
|
#include "usbd_audio_if.h"
|
|
#include "front_unit.h"
|
|
#include "rf_unit.h"
|
|
#include "system_menu.h"
|
|
#include "cw.h"
|
|
|
|
volatile bool TRX_ptt_hard = false;
|
|
volatile bool TRX_ptt_soft = false;
|
|
volatile bool TRX_old_ptt_soft = false;
|
|
volatile bool TRX_RX_IQ_swap = false;
|
|
volatile bool TRX_TX_IQ_swap = false;
|
|
volatile bool TRX_Tune = false;
|
|
volatile bool TRX_Inited = false;
|
|
volatile int_fast16_t TRX_RX_dBm = -100;
|
|
volatile bool TRX_ADC_OTR = false;
|
|
volatile bool TRX_DAC_OTR = false;
|
|
volatile int16_t TRX_ADC_MINAMPLITUDE = 0;
|
|
volatile int16_t TRX_ADC_MAXAMPLITUDE = 0;
|
|
volatile uint32_t TRX_SNTP_Synced = 0; // time of the last time synchronization
|
|
volatile int_fast16_t TRX_SHIFT = 0;
|
|
volatile float32_t TRX_MAX_TX_Amplitude = MAX_TX_AMPLITUDE;
|
|
volatile float32_t TRX_PWR_Forward = 0;
|
|
volatile float32_t TRX_PWR_Backward = 0;
|
|
volatile float32_t TRX_SWR = 0;
|
|
volatile float32_t TRX_ALC = 0;
|
|
static uint_fast8_t autogain_wait_reaction = 0; // timer for waiting for a reaction from changing the ATT / PRE modes
|
|
volatile uint8_t TRX_AutoGain_Stage = 0; // stage of working out the amplification corrector
|
|
static uint32_t KEYER_symbol_start_time = 0; // start time of the automatic key character
|
|
volatile float32_t TRX_IQ_phase_error = 0.0f;
|
|
volatile bool TRX_NeedGoToBootloader = false;
|
|
volatile bool TRX_Temporary_Stop_BandMap = false;
|
|
volatile bool TRX_Mute = false;
|
|
volatile bool TRX_IF_Gain = false;
|
|
volatile uint32_t TRX_Temporary_Mute_StartTime = 0;
|
|
uint32_t TRX_freq_phrase = 0;
|
|
uint32_t TRX_freq_phrase_tx = 0;
|
|
|
|
float32_t TRX_InVoltage = 12.0f;
|
|
float32_t TRX_SW1_Voltage = 0.0f;
|
|
float32_t TRX_SW2_Voltage = 0.0f;
|
|
float32_t TRX_CPU_temperature = 0.0f;
|
|
float32_t TRX_CPU_VRef = 0.0f;
|
|
float32_t TRX_CPU_VBat = 0.0f;
|
|
|
|
static void TRX_Start_RX(void);
|
|
static void TRX_Start_TX(void);
|
|
static void TRX_Start_TXRX(void);
|
|
|
|
bool TRX_on_TX(void)
|
|
{
|
|
if (TRX_ptt_hard || TRX_ptt_soft || TRX_Tune || CurrentVFO()->Mode == TRX_MODE_LOOPBACK || CW_Key_Timeout_est > 0)
|
|
return true;
|
|
return false;
|
|
}
|
|
|
|
void TRX_Init()
|
|
{
|
|
TRX_Start_TXRX();
|
|
WM8731_TXRX_mode();
|
|
WM8731_start_i2s_and_dma();
|
|
uint_fast8_t saved_mode = CurrentVFO()->Mode;
|
|
TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO());
|
|
TRX_setMode(saved_mode, CurrentVFO());
|
|
HAL_ADCEx_InjectedStart(&hadc1);
|
|
HAL_ADCEx_InjectedStart(&hadc2);
|
|
HAL_ADCEx_InjectedStart(&hadc3);
|
|
}
|
|
|
|
void TRX_Restart_Mode()
|
|
{
|
|
ADCDAC_OVR_StatusLatency = 0;
|
|
uint_fast8_t mode = CurrentVFO()->Mode;
|
|
//CLAR
|
|
if (TRX.CLAR)
|
|
{
|
|
TRX.current_vfo = !TRX.current_vfo;
|
|
TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO());
|
|
TRX_setMode(CurrentVFO()->Mode, CurrentVFO());
|
|
LCD_UpdateQuery.FreqInfo = true;
|
|
LCD_UpdateQuery.TopButtons = true;
|
|
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
|
|
}
|
|
FFT_Reset();
|
|
}
|
|
|
|
static void TRX_Start_RX()
|
|
{
|
|
sendToDebug_str("RX MODE\r\n");
|
|
WM8731_CleanBuffer();
|
|
Processor_NeedRXBuffer = false;
|
|
WM8731_Buffer_underrun = false;
|
|
WM8731_DMA_state = true;
|
|
|
|
//clean TX buffer
|
|
memset((void *)&FPGA_Audio_SendBuffer_Q[0], 0x00, sizeof(FPGA_Audio_SendBuffer_Q));
|
|
memset((void *)&FPGA_Audio_SendBuffer_I[0], 0x00, sizeof(FPGA_Audio_SendBuffer_I));
|
|
}
|
|
|
|
static void TRX_Start_TX()
|
|
{
|
|
sendToDebug_str("TX MODE\r\n");
|
|
WM8731_CleanBuffer();
|
|
HAL_Delay(10); // delay before the RF signal is applied, so that the relay has time to trigger
|
|
}
|
|
|
|
static void TRX_Start_TXRX()
|
|
{
|
|
sendToDebug_str("TXRX MODE\r\n");
|
|
WM8731_CleanBuffer();
|
|
}
|
|
|
|
void TRX_ptt_change(void)
|
|
{
|
|
if (TRX_Tune)
|
|
return;
|
|
bool TRX_new_ptt_hard = !HAL_GPIO_ReadPin(PTT_IN_GPIO_Port, PTT_IN_Pin);
|
|
if (TRX_ptt_hard != TRX_new_ptt_hard)
|
|
{
|
|
TRX_ptt_hard = TRX_new_ptt_hard;
|
|
TRX_ptt_soft = false;
|
|
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
|
|
FPGA_NeedSendParams = true;
|
|
TRX_Restart_Mode();
|
|
}
|
|
if (TRX_ptt_soft != TRX_old_ptt_soft)
|
|
{
|
|
TRX_old_ptt_soft = TRX_ptt_soft;
|
|
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
|
|
FPGA_NeedSendParams = true;
|
|
TRX_Restart_Mode();
|
|
}
|
|
}
|
|
|
|
void TRX_setFrequency(uint32_t _freq, VFO *vfo)
|
|
{
|
|
if (_freq < 1)
|
|
return;
|
|
if (_freq >= MAX_RX_FREQ_HZ)
|
|
_freq = MAX_RX_FREQ_HZ;
|
|
|
|
vfo->Freq = _freq;
|
|
|
|
//get band
|
|
int_fast8_t bandFromFreq = getBandFromFreq(_freq, true);
|
|
if (bandFromFreq >= 0)
|
|
{
|
|
TRX.BANDS_SAVED_SETTINGS[bandFromFreq].Freq = _freq;
|
|
}
|
|
if (TRX.BandMapEnabled && !TRX_Temporary_Stop_BandMap)
|
|
{
|
|
uint_fast8_t mode_from_bandmap = getModeFromFreq(vfo->Freq);
|
|
if (vfo->Mode != mode_from_bandmap)
|
|
{
|
|
TRX_setMode(mode_from_bandmap, vfo);
|
|
TRX.BANDS_SAVED_SETTINGS[bandFromFreq].Mode = mode_from_bandmap;
|
|
LCD_UpdateQuery.TopButtons = true;
|
|
}
|
|
}
|
|
|
|
//get fpga freq phrase
|
|
int8_t band = getBandFromFreq(CurrentVFO()->Freq, true);
|
|
VFO *current_vfo = CurrentVFO();
|
|
VFO *secondary_vfo = SecondaryVFO();
|
|
TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT);
|
|
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq);
|
|
// switch (band)
|
|
// {
|
|
// case 1:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_160);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_160);
|
|
// break;
|
|
// case 2:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_80);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_80);
|
|
// break;
|
|
// case 4:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_40);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_40);
|
|
// break;
|
|
// case 5:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_30);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_30);
|
|
// break;
|
|
// case 6:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_20);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_20);
|
|
// break;
|
|
// case 7:
|
|
// case 8:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_15);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_15);
|
|
// break;
|
|
// case 9:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_12);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_12);
|
|
// break;
|
|
// case 10:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_sibi);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_sibi);
|
|
// break;
|
|
// case 11:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_10);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_10);
|
|
// break;
|
|
// case 12:
|
|
// TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur_52);
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + CALIBRATE.freq_correctur_52);
|
|
// break;
|
|
// }
|
|
|
|
if (!TRX_on_TX())
|
|
{
|
|
int8_t mode = (int8_t)CurrentVFO()->Mode;
|
|
switch (mode)
|
|
{
|
|
case TRX_MODE_CW_L:
|
|
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq - TRX.CW_GENERATOR_SHIFT_HZ);
|
|
break;
|
|
case TRX_MODE_CW_U:
|
|
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX.CW_GENERATOR_SHIFT_HZ);
|
|
break;
|
|
// default:
|
|
// TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq);
|
|
// break;
|
|
}
|
|
}
|
|
|
|
//
|
|
TRX_MAX_TX_Amplitude = getMaxTXAmplitudeOnFreq(vfo->Freq);
|
|
FPGA_NeedSendParams = true;
|
|
}
|
|
|
|
void TRX_setMode(uint_fast8_t _mode, VFO *vfo)
|
|
{
|
|
if (vfo->Mode == TRX_MODE_LOOPBACK || _mode == TRX_MODE_LOOPBACK)
|
|
LCD_UpdateQuery.StatusInfoGUI = true;
|
|
vfo->Mode = _mode;
|
|
if (vfo->Mode == TRX_MODE_LOOPBACK)
|
|
TRX_Start_TXRX();
|
|
|
|
switch (_mode)
|
|
{
|
|
case TRX_MODE_AM:
|
|
vfo->RX_LPF_Filter_Width = TRX.RX_AM_LPF_Filter;
|
|
vfo->TX_LPF_Filter_Width = TRX.TX_AM_LPF_Filter;
|
|
vfo->HPF_Filter_Width = 0;
|
|
break;
|
|
case TRX_MODE_LSB:
|
|
case TRX_MODE_USB:
|
|
case TRX_MODE_DIGI_L:
|
|
case TRX_MODE_DIGI_U:
|
|
vfo->RX_LPF_Filter_Width = TRX.RX_SSB_LPF_Filter;
|
|
vfo->TX_LPF_Filter_Width = TRX.TX_SSB_LPF_Filter;
|
|
vfo->HPF_Filter_Width = TRX.SSB_HPF_Filter;
|
|
break;
|
|
case TRX_MODE_CW_L:
|
|
case TRX_MODE_CW_U:
|
|
vfo->RX_LPF_Filter_Width = TRX.CW_LPF_Filter;
|
|
vfo->TX_LPF_Filter_Width = TRX.CW_LPF_Filter;
|
|
vfo->HPF_Filter_Width = TRX.CW_HPF_Filter;
|
|
LCD_UpdateQuery.StatusInfoGUI = true;
|
|
break;
|
|
case TRX_MODE_NFM:
|
|
vfo->RX_LPF_Filter_Width = TRX.RX_FM_LPF_Filter;
|
|
vfo->TX_LPF_Filter_Width = TRX.TX_FM_LPF_Filter;
|
|
vfo->HPF_Filter_Width = 0;
|
|
break;
|
|
case TRX_MODE_WFM:
|
|
vfo->RX_LPF_Filter_Width = 0;
|
|
vfo->TX_LPF_Filter_Width = 0;
|
|
vfo->HPF_Filter_Width = 0;
|
|
break;
|
|
}
|
|
NeedReinitAudioFilters = true;
|
|
NeedSaveSettings = true;
|
|
LCD_UpdateQuery.StatusInfoBar = true;
|
|
LCD_UpdateQuery.StatusInfoGUI = true;
|
|
}
|
|
|
|
void TRX_DoAutoGain(void)
|
|
{
|
|
uint8_t skip_cycles = 0;
|
|
if (skip_cycles > 0)
|
|
{
|
|
skip_cycles--;
|
|
return;
|
|
}
|
|
|
|
//Process AutoGain feature
|
|
if (TRX.AutoGain && !TRX_on_TX())
|
|
{
|
|
if (!TRX.ATT)
|
|
{
|
|
TRX.ATT = true;
|
|
LCD_UpdateQuery.TopButtons = true;
|
|
}
|
|
|
|
int32_t max_amplitude = abs(TRX_ADC_MAXAMPLITUDE);
|
|
if (abs(TRX_ADC_MINAMPLITUDE) > max_amplitude)
|
|
max_amplitude = abs(TRX_ADC_MINAMPLITUDE);
|
|
//sendToDebug_int32(max_amplitude,false);
|
|
float32_t new_att_val = TRX.ATT_DB;
|
|
if (max_amplitude > (AUTOGAINER_TAGET + AUTOGAINER_HYSTERESIS) && new_att_val < 31.5f)
|
|
new_att_val += 0.5f;
|
|
else if (max_amplitude < (AUTOGAINER_TAGET - AUTOGAINER_HYSTERESIS) && new_att_val > 1.0f)
|
|
new_att_val -= 0.5f;
|
|
|
|
if (new_att_val == 0.0f && max_amplitude < (AUTOGAINER_TAGET - AUTOGAINER_HYSTERESIS) && !TRX.ADC_Driver)
|
|
{
|
|
TRX.ADC_Driver = true;
|
|
LCD_UpdateQuery.TopButtons = true;
|
|
skip_cycles = 5;
|
|
}
|
|
|
|
if (new_att_val != TRX.ATT_DB)
|
|
{
|
|
TRX.ATT_DB = new_att_val;
|
|
LCD_UpdateQuery.TopButtons = true;
|
|
//save settings
|
|
int8_t band = getBandFromFreq(CurrentVFO()->Freq, true);
|
|
TRX.BANDS_SAVED_SETTINGS[band].ATT_DB = TRX.ATT_DB;
|
|
TRX.BANDS_SAVED_SETTINGS[band].ADC_Driver = TRX.ADC_Driver;
|
|
}
|
|
// sendToDebug_int32(new_att_val,false);
|
|
}
|
|
}
|
|
|
|
void TRX_DBMCalculate(void)
|
|
{
|
|
if(Processor_RX_Power_value == 0)
|
|
return;
|
|
|
|
float32_t adc_volts = Processor_RX_Power_value * (ADC_RANGE / 2.0f);
|
|
if(adc_volts > 0.0f)
|
|
{
|
|
TRX_RX_dBm = (int16_t)(10.0f * log10f_fast((adc_volts * adc_volts / ADC_INPUT_IMPEDANCE) / 0.001f));
|
|
TRX_RX_dBm += CALIBRATE.smeter_calibration;
|
|
}
|
|
Processor_RX_Power_value = 0;
|
|
}
|
|
|
|
void TRX_TemporaryMute(void)
|
|
{
|
|
WM8731_Mute();
|
|
TRX_Temporary_Mute_StartTime = HAL_GetTick();
|
|
}
|