Wolf-LITE/STM32/Core/Src/trx_manager.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();
}