Wolf-LITE/STM32/Core/Src/cw.c

214 wiersze
6.1 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 "swr_analyzer.h"
volatile bool CW_key_serial = false;
volatile bool CW_old_key_serial = false;
volatile bool CW_key_dot_hard = false;
volatile bool CW_key_dash_hard = false;
volatile uint_fast16_t CW_Key_Timeout_est = 0;
volatile uint_fast8_t KEYER_symbol_status = 0; // status (signal or period) of the automatic key symbol
static uint32_t KEYER_symbol_start_time = 0; // start time of the automatic key character
static float32_t current_cw_power = 0.0f; // current amplitude (for rise/fall)
static bool iambic_first_button_pressed = false; //start symbol | false - dot, true - dash
static bool iambic_last_symbol = false; //last Iambic symbol | false - dot, true - dash
static bool iambic_sequence_started = false;
void CW_key_change(void)
{
if (TRX_Tune)
return;
if (CurrentVFO()->Mode != TRX_MODE_CW_L && CurrentVFO()->Mode != TRX_MODE_CW_U)
return;
bool TRX_new_key_dot_hard = !HAL_GPIO_ReadPin(KEY_IN_DOT_GPIO_Port, KEY_IN_DOT_Pin);
//if(TRX.CW_Invert)
//TRX_new_key_dot_hard = !HAL_GPIO_ReadPin(KEY_IN_DASH_GPIO_Port, KEY_IN_DASH_Pin);
if (CW_key_dot_hard != TRX_new_key_dot_hard)
{
CW_key_dot_hard = TRX_new_key_dot_hard;
if (CW_key_dot_hard == true && (KEYER_symbol_status == 0 || !TRX.CW_KEYER))
{
CW_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
bool TRX_new_key_dash_hard = !HAL_GPIO_ReadPin(KEY_IN_DASH_GPIO_Port, KEY_IN_DASH_Pin);
//if(TRX.CW_Invert)
//TRX_new_key_dash_hard = !HAL_GPIO_ReadPin(KEY_IN_DOT_GPIO_Port, KEY_IN_DOT_Pin);
if (CW_key_dash_hard != TRX_new_key_dash_hard)
{
CW_key_dash_hard = TRX_new_key_dash_hard;
if (CW_key_dash_hard == true && (KEYER_symbol_status == 0 || !TRX.CW_KEYER))
{
CW_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
if (CW_key_serial != CW_old_key_serial)
{
CW_old_key_serial = CW_key_serial;
if (CW_key_serial == true)
CW_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
static float32_t CW_generateRiseSignal(float32_t power)
{
if (current_cw_power < power)
current_cw_power += power * 0.007f;
if (current_cw_power > power)
current_cw_power = power;
return current_cw_power;
}
static float32_t CW_generateFallSignal(float32_t power)
{
if (current_cw_power > 0.0f)
current_cw_power -= power * 0.007f;
if (current_cw_power < 0.0f)
current_cw_power = 0.0f;
return current_cw_power;
}
float32_t CW_GenerateSignal(float32_t power)
{
//Do no signal before start TX delay
//if ((HAL_GetTick() - TRX_TX_StartTime) < CALIBRATE.TX_StartDelay)
//return 0.0f;
//Keyer disabled
if (!TRX.CW_KEYER)
{
if (!CW_key_serial && !TRX_ptt_hard && !CW_key_dot_hard && !CW_key_dash_hard)
return CW_generateFallSignal(power);
return CW_generateRiseSignal(power);
}
//USB CW (Serial)
if(CW_key_serial)
return CW_generateRiseSignal(power);
//Keyer
const float32_t CW_DotToDashRate = 3.0f;
uint32_t dot_length_ms = 1200 / TRX.CW_KEYER_WPM;
uint32_t dash_length_ms = (float32_t)dot_length_ms * CW_DotToDashRate;
uint32_t sim_space_length_ms = dot_length_ms;
uint32_t curTime = HAL_GetTick();
//Iambic keyer start mode
if(CW_key_dot_hard && !CW_key_dash_hard)
iambic_first_button_pressed = false;
if(!CW_key_dot_hard && CW_key_dash_hard)
iambic_first_button_pressed = true;
if(CW_key_dot_hard && CW_key_dash_hard)
iambic_sequence_started = true;
//DOT .
if (KEYER_symbol_status == 0 && CW_key_dot_hard)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 1;
}
if (KEYER_symbol_status == 1 && (KEYER_symbol_start_time + dot_length_ms) > curTime)
{
CW_Key_Timeout_est = TRX.CW_Key_timeout;
return CW_generateRiseSignal(power);
}
if (KEYER_symbol_status == 1 && (KEYER_symbol_start_time + dot_length_ms) < curTime)
{
iambic_last_symbol = false;
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 3;
}
//DASH -
if (KEYER_symbol_status == 0 && CW_key_dash_hard)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 2;
}
if (KEYER_symbol_status == 2 && (KEYER_symbol_start_time + dash_length_ms) > curTime)
{
CW_Key_Timeout_est = TRX.CW_Key_timeout;
return CW_generateRiseSignal(power);
}
if (KEYER_symbol_status == 2 && (KEYER_symbol_start_time + dash_length_ms) < curTime)
{
iambic_last_symbol = true;
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 3;
}
//SPACE
if (KEYER_symbol_status == 3 && (KEYER_symbol_start_time + sim_space_length_ms) > curTime)
{
CW_Key_Timeout_est = TRX.CW_Key_timeout;
return CW_generateFallSignal(power);
}
if (KEYER_symbol_status == 3 && (KEYER_symbol_start_time + sim_space_length_ms) < curTime)
{
//if(!TRX.CW_Iambic) //classic keyer
KEYER_symbol_status = 0;
/*else //iambic keyer
{
//start iambic sequence
if(iambic_sequence_started)
{
if(!iambic_last_symbol) // iambic dot . , next dash -
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 2;
if(iambic_first_button_pressed && (!CW_key_dot_hard || !CW_key_dash_hard)) //iambic dash-dot sequence compleated
{
//println("-.e");
iambic_sequence_started = false;
KEYER_symbol_status = 0;
}
}
else // iambic dash - , next dot .
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 1;
if(!iambic_first_button_pressed && (!CW_key_dot_hard || !CW_key_dash_hard)) //iambic dot-dash sequence compleated
{
//println(".-e");
KEYER_symbol_status = 0;
iambic_sequence_started = false;
}
}
}
else //no sequence, classic mode
KEYER_symbol_status = 0;
}*/
}
return CW_generateFallSignal(power);
}