From 941560ae27be28d0f1dd008b00dfcaa8d1c72245 Mon Sep 17 00:00:00 2001 From: =?UTF-8?q?=D0=90=D0=BD=D1=82=D0=BE=D0=BD?= <43981173+UU5JPP@users.noreply.github.com> Date: Sat, 26 Jun 2021 13:55:56 +0300 Subject: [PATCH] test --- STM32/Core/Src/1front_unit.c | 1261 +++++++++++++++++ STM32/Core/Src/agc.c | 191 ++- STM32/Core/Src/agc.h | 3 +- STM32/Core/Src/audio_filters.c | 10 + STM32/Core/Src/audio_filters.h | 2 + STM32/Core/Src/audio_processor.c | 2 +- STM32/Core/Src/color_themes.h | 2 +- STM32/Core/Src/fft.c | 34 +- STM32/Core/Src/fft.h | 4 +- STM32/Core/Src/front_unit.c | 85 +- STM32/Core/Src/functions.c | 17 + STM32/Core/Src/functions.h | 3 + STM32/Core/Src/lcd.c | 1 + STM32/Core/Src/main.c | 42 +- STM32/Core/Src/rf_unit.c | 4 +- STM32/Core/Src/screen_layout.h | 2 +- STM32/Core/Src/settings.c | 20 +- STM32/Core/Src/settings.h | 25 +- STM32/Core/Src/system_menu.c | 14 + STM32/Core/Src/trx_manager.c | 159 +-- STM32/Core/Src/usbd_ua3reo.c | 21 +- STM32/Core/USBDevice/usbd_desc.c | 2 +- STM32/DEBUG.bat | 2 +- STM32/MDK-ARM/RTE/_WOLF-Lite/RTE_Components.h | 42 +- STM32/MDK-ARM/WOLF-Lite.uvprojx | 2 +- STM32/MDK-ARM/startup_stm32f407xx.s | 2 +- Stuff/CIC_Filters/61.440/rx_fir_filter.coe | 1 + Stuff/CIC_Filters/61.440/tx_fir_filter.coe | 1 + 28 files changed, 1665 insertions(+), 289 deletions(-) create mode 100644 STM32/Core/Src/1front_unit.c create mode 100644 Stuff/CIC_Filters/61.440/rx_fir_filter.coe create mode 100644 Stuff/CIC_Filters/61.440/tx_fir_filter.coe diff --git a/STM32/Core/Src/1front_unit.c b/STM32/Core/Src/1front_unit.c new file mode 100644 index 0000000..08af98c --- /dev/null +++ b/STM32/Core/Src/1front_unit.c @@ -0,0 +1,1261 @@ +#include "stm32f4xx_hal.h" +#include "main.h" +#include "front_unit.h" +#include "lcd.h" +#include "trx_manager.h" +#include "settings.h" +#include "system_menu.h" +#include "functions.h" +#include "audio_filters.h" +#include "auto_notch.h" +#include "agc.h" + +static void FRONTPANEL_ENCODER_Rotated(float32_t direction); +static void FRONTPANEL_ENCODER2_Rotated(int8_t direction); +static uint16_t FRONTPANEL_ReadMCP3008_Value(uint8_t channel, GPIO_TypeDef *CS_PORT, uint16_t CS_PIN); +static void FRONTPANEL_ENCODER2_Rotated(int8_t direction); + + +static void FRONTPANEL_BUTTONHANDLER_BAND_P(void); +static void FRONTPANEL_BUTTONHANDLER_BAND_N(void); +static void FRONTPANEL_BUTTONHANDLER_SQUELCH(void); +static void FRONTPANEL_BUTTONHANDLER_WPM(void); +static void FRONTPANEL_BUTTONHANDLER_KEYER(void); +static void FRONTPANEL_BUTTONHANDLER_SHIFT(void); +static void FRONTPANEL_BUTTONHANDLER_CLAR(void); +static void FRONTPANEL_BUTTONHANDLER_STEP(void); +static void FRONTPANEL_BUTTONHANDLER_BANDMAP(void); +static void FRONTPANEL_BUTTONHANDLER_HIDDEN_ENABLE(void); +static void FRONTPANEL_BUTTONHANDLER_ATTHOLD(void); +static void FRONTPANEL_BUTTONHANDLER_AGC(void); +static void FRONTPANEL_BUTTONHANDLER_AGC_SPEED(void); +static void FRONTPANEL_BUTTONHANDLER_NOTCH(void); +static void FRONTPANEL_BUTTONHANDLER_FAST(void); +static void FRONTPANEL_BUTTONHANDLER_MUTE(void); +static void FRONTPANEL_BUTTONHANDLER_AsB(void); +static void FRONTPANEL_BUTTONHANDLER_ArB(void); +static void FRONTPANEL_BUTTONHANDLER_TUNE(void); +static void FRONTPANEL_BUTTONHANDLER_BW(void); +static void FRONTPANEL_BUTTONHANDLER_HPF(void); +static void FRONTPANEL_BUTTONHANDLER_MENU(void); +static void FRONTPANEL_BUTTONHANDLER_LOCK(void); +static void FRONTPANEL_BUTTONHANDLER_PWR_P(void); +static void FRONTPANEL_BUTTONHANDLER_PWR_N(void); +static void FRONTPANEL_BUTTONHANDLER_ZOOM_P(void); +static void FRONTPANEL_ENC2SW_click_handler(uint32_t parameter); +static void FRONTPANEL_ENC2SW_hold_handler(uint32_t parameter); + +static bool FRONTPanel_MCP3008_1_Enabled = true; + +static int32_t ENCODER_slowler = 0; +static uint32_t ENCODER_AValDeb = 0; +static uint32_t ENCODER2_AValDeb = 0; + +static bool enc2_func_mode = false; //false - fast-step, true - func mode (WPM, etc...) + +static PERIPH_FrontPanel_Button PERIPH_FrontPanel_Static_Buttons[] = { + {.port = 1, .channel = 0, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 1, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 2, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 3, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 4, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 7, .name = "MODE", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6 + {.port = 1, .channel = 7, .name = "BAND", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB1 + {.port = 1, .channel = 6, .name = "MENU", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MENU, .holdHandler = FRONTPANEL_BUTTONHANDLER_MENU}, //SB1 +}; + +static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SCROLLBUTTONS_GROUPS_COUNT][5] = { + { + {.port = 1, .channel = 5, .name = "PRE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PRE, .holdHandler = FRONTPANEL_BUTTONHANDLER_PRE}, //SB2 + {.port = 1, .channel = 5, .name = "ATT", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ATT, .holdHandler = FRONTPANEL_BUTTONHANDLER_ATTHOLD}, //SB3 + {.port = 1, .channel = 5, .name = "BW", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW, .holdHandler = FRONTPANEL_BUTTONHANDLER_HPF}, //SB4 + {.port = 1, .channel = 6, .name = "A/B", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AsB, .holdHandler = FRONTPANEL_BUTTONHANDLER_ArB}, //SB5 + {.port = 1, .channel = 6, .name = "POWER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2 + }, + { + {.port = 1, .channel = 5, .name = "AGC", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AGC, .holdHandler = FRONTPANEL_BUTTONHANDLER_AGC_SPEED}, //SB2 + {.port = 1, .channel = 5, .name = "TUNE", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_TUNE, .holdHandler = FRONTPANEL_BUTTONHANDLER_TUNE}, //SB3 + {.port = 1, .channel = 5, .name = "NOTCH", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_NOTCH, .holdHandler = FRONTPANEL_BUTTONHANDLER_NOTCH}, //SB4 + {.port = 1, .channel = 6, .name = "FAST", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_FAST, .holdHandler = FRONTPANEL_BUTTONHANDLER_FAST}, //SB5 + {.port = 1, .channel = 6, .name = "CLAR", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_CLAR, .holdHandler = FRONTPANEL_BUTTONHANDLER_CLAR}, //SB3 + }, + { + {.port = 1, .channel = 5, .name = "VOLUME", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_VOLUME, .holdHandler = FRONTPANEL_BUTTONHANDLER_VOLUME}, //SB2 + {.port = 1, .channel = 5, .name = "BANDMAP", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP, .holdHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP}, //SB3 + {.port = 1, .channel = 5, .name = "MUTE", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MUTE, .holdHandler = FRONTPANEL_BUTTONHANDLER_MUTE}, //SB4 + {.port = 1, .channel = 6, .name = "LOCK", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_LOCK, .holdHandler = FRONTPANEL_BUTTONHANDLER_LOCK}, //SB5 + {.port = 1, .channel = 6, .name = "WPM", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_WPM, .holdHandler = FRONTPANEL_BUTTONHANDLER_WPM}, //SB4 + }, + { + {.port = 1, .channel = 5, .name = "BAND-", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB2 + {.port = 1, .channel = 5, .name = "BAND+", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_P}, //SB3 + {.port = 1, .channel = 5, .name = "MODE-", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_N}, //SB4 + {.port = 1, .channel = 6, .name = "MODE+", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB5 + {.port = 1, .channel = 6, .name = "KEYER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_KEYER, .holdHandler = FRONTPANEL_BUTTONHANDLER_KEYER}, //SB5 + }, + { + {.port = 1, .channel = 5, .name = "BW-", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_BW_N}, //SB2 + {.port = 1, .channel = 5, .name = "BW+", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BW_P}, //SB3 + {.port = 1, .channel = 5, .name = "PWR-", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_N}, //SB4 + {.port = 1, .channel = 6, .name = "PWR+", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_P}, //SB5 + {.port = 1, .channel = 6, .name = "ZOOM", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P}, //SB2 + }, + { + {.port = 1, .channel = 5, .name = "MODE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6 + {.port = 1, .channel = 5, .name = "BAND", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB1 + {.port = 1, .channel = 5, .name = "PRE", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PRE, .holdHandler = FRONTPANEL_BUTTONHANDLER_PRE}, //SB2 + {.port = 1, .channel = 6, .name = "A/B", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AsB, .holdHandler = FRONTPANEL_BUTTONHANDLER_ArB}, //SB5 + {.port = 1, .channel = 6, .name = "POWER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2 + }, +}; + +PERIPH_FrontPanel_Button* PERIPH_FrontPanel_BottomScroll_Buttons_Active = PERIPH_FrontPanel_BottomScroll_Buttons[0]; +int8_t PERIPH_FrontPanel_BottomScroll_index = 0; + +void FRONTPANEL_ENCODER_checkRotate(void) +{ + static uint32_t ENCstartMeasureTime = 0; + static int16_t ENCticksInInterval = 0; + static float32_t ENCAcceleration = 0; + static uint8_t ENClastClkVal = 0; + static bool ENCfirst = true; + uint8_t ENCODER_DTVal = HAL_GPIO_ReadPin(ENC_DT_GPIO_Port, ENC_DT_Pin); + uint8_t ENCODER_CLKVal = HAL_GPIO_ReadPin(ENC_CLK_GPIO_Port, ENC_CLK_Pin); + + if (ENCfirst) + { + ENClastClkVal = ENCODER_CLKVal; + ENCfirst = false; + } + if ((HAL_GetTick() - ENCODER_AValDeb) < CALIBRATE.ENCODER_DEBOUNCE) + return; + + if (ENClastClkVal != ENCODER_CLKVal) + { + if (!CALIBRATE.ENCODER_ON_FALLING || ENCODER_CLKVal == 0) + { + if (ENCODER_DTVal != ENCODER_CLKVal) + { // If pin A changed first - clockwise rotation + ENCODER_slowler--; + if (ENCODER_slowler <= -CALIBRATE.ENCODER_SLOW_RATE) + { + //acceleration + ENCticksInInterval++; + if((HAL_GetTick() - ENCstartMeasureTime) > ENCODER_ACCELERATION) + { + ENCstartMeasureTime = HAL_GetTick(); + ENCAcceleration = (10.0f + ENCticksInInterval - 1.0f) / 10.0f; + ENCticksInInterval = 0; + } + //do rotate + FRONTPANEL_ENCODER_Rotated(CALIBRATE.ENCODER_INVERT ? ENCAcceleration : -ENCAcceleration); + ENCODER_slowler = 0; + } + } + else + { // otherwise B changed its state first - counterclockwise rotation + ENCODER_slowler++; + if (ENCODER_slowler >= CALIBRATE.ENCODER_SLOW_RATE) + { + //acceleration + ENCticksInInterval++; + if((HAL_GetTick() - ENCstartMeasureTime) > ENCODER_ACCELERATION) + { + ENCstartMeasureTime = HAL_GetTick(); + ENCAcceleration = (10.0f + ENCticksInInterval - 1.0f) / 10.0f; + ENCticksInInterval = 0; + } + //do rotate + FRONTPANEL_ENCODER_Rotated(CALIBRATE.ENCODER_INVERT ? -ENCAcceleration : ENCAcceleration); + ENCODER_slowler = 0; + } + } + } + ENCODER_AValDeb = HAL_GetTick(); + ENClastClkVal = ENCODER_CLKVal; + } +} + +void FRONTPANEL_ENCODER2_checkRotate(void) +{ + static int8_t enc2_slowler = 0; + #define enc2_slowler_val 2 + uint8_t ENCODER2_DTVal = HAL_GPIO_ReadPin(ENC2_DT_GPIO_Port, ENC2_DT_Pin); + uint8_t ENCODER2_CLKVal = HAL_GPIO_ReadPin(ENC2_CLK_GPIO_Port, ENC2_CLK_Pin); + + if ((HAL_GetTick() - ENCODER2_AValDeb) < CALIBRATE.ENCODER2_DEBOUNCE) + return; + + if (!CALIBRATE.ENCODER_ON_FALLING || ENCODER2_CLKVal == 0) + { + if (ENCODER2_DTVal != ENCODER2_CLKVal) + { + // If pin A changed first - clockwise rotation + enc2_slowler--; + if(enc2_slowler <= -enc2_slowler_val) + { + FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? 1 : -1); + enc2_slowler = 0; + } + } + else + { + // otherwise B changed its state first - counterclockwise rotation + enc2_slowler++; + if(enc2_slowler >= enc2_slowler_val) + { + FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? -1 : 1); + enc2_slowler = 0; + } + } + } + ENCODER2_AValDeb = HAL_GetTick(); +} + +static void FRONTPANEL_ENCODER_Rotated(float32_t direction) // rotated encoder, handler here, direction -1 - left, 1 - right +{ + if (TRX.Locked) + return; + if (LCD_systemMenuOpened) + { + eventRotateSystemMenu((int8_t)direction); + return; + } + if(fabsf(direction) <= ENCODER_MIN_RATE_ACCELERATION) + direction = (direction < 0.0f)? -1.0f : 1.0f; + + VFO *vfo = CurrentVFO(); + uint32_t newfreq = 0; + if (TRX.Fast) + { + newfreq = (uint32_t)((int32_t)vfo->Freq + (int32_t)((float32_t)TRX.FRQ_FAST_STEP * direction)); + if ((vfo->Freq % TRX.FRQ_FAST_STEP) > 0 && fabsf(direction) <= 1.0f) + newfreq = vfo->Freq / TRX.FRQ_FAST_STEP * TRX.FRQ_FAST_STEP; + } + else + { + newfreq = (uint32_t)((int32_t)vfo->Freq + (int32_t)((float32_t)TRX.FRQ_STEP * direction)); + if ((vfo->Freq % TRX.FRQ_STEP) > 0 && fabsf(direction) <= 1.0f) + newfreq = vfo->Freq / TRX.FRQ_STEP * TRX.FRQ_STEP; + } + TRX_setFrequency(newfreq, vfo); + LCD_UpdateQuery.FreqInfo = true; + NeedSaveSettings = true; +} + +static void FRONTPANEL_ENCODER2_Rotated(int8_t direction) // rotated encoder, handler here, direction -1 - left, 1 - right +{ + if (TRX.Locked) + return; + + if (LCD_systemMenuOpened) + { + eventSecRotateSystemMenu(direction); + return; + } + else + { + if (!enc2_func_mode) //function buttons scroll + { + PERIPH_FrontPanel_BottomScroll_index += direction; + if(PERIPH_FrontPanel_BottomScroll_index < 0) + PERIPH_FrontPanel_BottomScroll_index = BOTTOM_SCROLLBUTTONS_GROUPS_COUNT - 1; + if(PERIPH_FrontPanel_BottomScroll_index >= BOTTOM_SCROLLBUTTONS_GROUPS_COUNT) + PERIPH_FrontPanel_BottomScroll_index = 0; + PERIPH_FrontPanel_BottomScroll_Buttons_Active = PERIPH_FrontPanel_BottomScroll_Buttons[PERIPH_FrontPanel_BottomScroll_index]; + LCD_UpdateQuery.TopButtons = true; + } + else //set volume + { + int16_t newvolume = (int16_t)TRX.Volume + direction * 10; + newvolume /= 10; + newvolume *= 10; + if(newvolume > 100) + newvolume = 100; + if(newvolume < 0) + newvolume = 0; + TRX.Volume = newvolume; + char str[32] = {0}; + sprintf(str, "VOL: %d%%",TRX.Volume); + LCD_showTooltip(str); + } + } +} + +void FRONTPANEL_check_ENC2SW(void) +{ + static uint32_t menu_enc2_click_starttime = 0; + static bool ENC2SW_Last = true; + static bool ENC2SW_clicked = false; + static bool ENC2SW_hold_start = false; + static bool ENC2SW_holded = false; + ENC2SW_clicked = false; + ENC2SW_holded = false; + + if (TRX.Locked) + return; + + bool ENC2SW_AND_TOUCH_Now = HAL_GPIO_ReadPin(ENC2_SW_GPIO_Port, ENC2_SW_Pin); + //check hold and click + if (ENC2SW_Last != ENC2SW_AND_TOUCH_Now) + { + ENC2SW_Last = ENC2SW_AND_TOUCH_Now; + if (!ENC2SW_AND_TOUCH_Now) + { + menu_enc2_click_starttime = HAL_GetTick(); + ENC2SW_hold_start = true; + } + } + if (!ENC2SW_AND_TOUCH_Now && ENC2SW_hold_start) + { + if ((HAL_GetTick() - menu_enc2_click_starttime) > KEY_HOLD_TIME) + { + ENC2SW_holded = true; + ENC2SW_hold_start = false; + } + } + if (ENC2SW_AND_TOUCH_Now && ENC2SW_hold_start) + { + if ((HAL_GetTick() - menu_enc2_click_starttime) > 1) + { + ENC2SW_clicked = true; + ENC2SW_hold_start = false; + } + } + + //ENC2 Button hold + if (ENC2SW_holded) + { + FRONTPANEL_ENC2SW_hold_handler(0); + } + + //ENC2 Button click + if (ENC2SW_clicked) + { + menu_enc2_click_starttime = HAL_GetTick(); + FRONTPANEL_ENC2SW_click_handler(0); + } +} + +static void FRONTPANEL_ENC2SW_click_handler(uint32_t parameter) +{ + //ENC2 CLICK + if (!LCD_systemMenuOpened) + { + enc2_func_mode = !enc2_func_mode; //enc2 rotary mode + + if (!enc2_func_mode) + LCD_showTooltip("FUNC ROTATE"); + else + LCD_showTooltip("SET VOLUME"); + } + else + { + if (LCD_systemMenuOpened) + { + //navigate in menu + SYSMENU_eventSecEncoderClickSystemMenu(); + } + } +} + +static void FRONTPANEL_ENC2SW_hold_handler(uint32_t parameter) +{ + FRONTPANEL_BUTTONHANDLER_MENU(); +} + +void FRONTPANEL_Init(void) +{ + uint16_t test_value = FRONTPANEL_ReadMCP3008_Value(0, AD1_CS_GPIO_Port, AD1_CS_Pin); + if (test_value == 65535) + { + FRONTPanel_MCP3008_1_Enabled = false; + sendToDebug_strln("[ERR] Frontpanel MCP3008 - 1 not found, disabling... (FPGA SPI/I2S CLOCK ERROR?)"); + LCD_showError("MCP3008 - 1 init error (FPGA I2S CLK?)", true); + } + FRONTPANEL_Process(); +} + +void FRONTPANEL_Process(void) +{ + if (SPI_process) + return; + SPI_process = true; + + FRONTPANEL_check_ENC2SW(); + uint16_t buttons_count = sizeof(PERIPH_FrontPanel_Static_Buttons) / sizeof(PERIPH_FrontPanel_Button); + uint16_t mcp3008_value = 0; + bool process_static_buttons = true; + + //process buttons + PERIPH_FrontPanel_Button* PERIPH_FrontPanel_Buttons = PERIPH_FrontPanel_Static_Buttons; + for (int16_t b = 0; b < buttons_count; b++) + { + //check disabled ports + if (PERIPH_FrontPanel_Buttons[b].port == 1 && !FRONTPanel_MCP3008_1_Enabled) + continue; + + //get state from ADC MCP3008 (10bit - 1024values) + if (PERIPH_FrontPanel_Buttons[b].port == 1) + mcp3008_value = FRONTPANEL_ReadMCP3008_Value(PERIPH_FrontPanel_Buttons[b].channel, AD1_CS_GPIO_Port, AD1_CS_Pin); + + /*sendToDebug_str("port: "); + sendToDebug_uint8(PERIPH_FrontPanel_Buttons[b].port, true); + sendToDebug_str("channel: "); + sendToDebug_uint8(PERIPH_FrontPanel_Buttons[b].channel, true); + sendToDebug_str("value: "); + sendToDebug_uint16(mcp3008_value, false); + sendToDebug_flush();*/ + + //set state + if (mcp3008_value >= PERIPH_FrontPanel_Buttons[b].tres_min && mcp3008_value < PERIPH_FrontPanel_Buttons[b].tres_max) + PERIPH_FrontPanel_Buttons[b].state = true; + else + PERIPH_FrontPanel_Buttons[b].state = false; + + //check state + if ((PERIPH_FrontPanel_Buttons[b].prev_state != PERIPH_FrontPanel_Buttons[b].state) && PERIPH_FrontPanel_Buttons[b].state) + { + PERIPH_FrontPanel_Buttons[b].start_hold_time = HAL_GetTick(); + PERIPH_FrontPanel_Buttons[b].afterhold = false; + } + + //check hold state + if ((PERIPH_FrontPanel_Buttons[b].prev_state == PERIPH_FrontPanel_Buttons[b].state) && PERIPH_FrontPanel_Buttons[b].state && ((HAL_GetTick() - PERIPH_FrontPanel_Buttons[b].start_hold_time) > KEY_HOLD_TIME) && !PERIPH_FrontPanel_Buttons[b].afterhold) + { + PERIPH_FrontPanel_Buttons[b].afterhold = true; + if (!TRX.Locked || (PERIPH_FrontPanel_Buttons[b].clickHandler == FRONTPANEL_BUTTONHANDLER_LOCK)) //LOCK BUTTON + if (!LCD_systemMenuOpened || PERIPH_FrontPanel_Buttons[b].work_in_menu) + if (PERIPH_FrontPanel_Buttons[b].holdHandler != NULL) + { + WM8731_Beep(); + PERIPH_FrontPanel_Buttons[b].holdHandler(); + } + } + + //check click state + if ((PERIPH_FrontPanel_Buttons[b].prev_state != PERIPH_FrontPanel_Buttons[b].state) && !PERIPH_FrontPanel_Buttons[b].state && ((HAL_GetTick() - PERIPH_FrontPanel_Buttons[b].start_hold_time) < KEY_HOLD_TIME) && !PERIPH_FrontPanel_Buttons[b].afterhold && !TRX.Locked) + { + if (!LCD_systemMenuOpened || PERIPH_FrontPanel_Buttons[b].work_in_menu) + if (PERIPH_FrontPanel_Buttons[b].clickHandler != NULL) + { + WM8731_Beep(); + PERIPH_FrontPanel_Buttons[b].clickHandler(); + } + } + + //save prev state + PERIPH_FrontPanel_Buttons[b].prev_state = PERIPH_FrontPanel_Buttons[b].state; + + if(process_static_buttons && b == (buttons_count - 1)) + { + //repeat with dynamic buttons + process_static_buttons = false; + buttons_count = sizeof(PERIPH_FrontPanel_BottomScroll_Buttons[0]) / sizeof(PERIPH_FrontPanel_Button); + PERIPH_FrontPanel_Buttons = PERIPH_FrontPanel_BottomScroll_Buttons_Active; + b = -1; + } + } + SPI_process = false; +} +//---------------------------------------------------------------------------- +static void FRONTPANEL_BUTTONHANDLER_ZOOM_P(void) +{ + if (TRX.FFT_Zoom == 1) + TRX.FFT_Zoom = 2; + else if (TRX.FFT_Zoom == 2) + TRX.FFT_Zoom = 4; + else if (TRX.FFT_Zoom == 4) + TRX.FFT_Zoom = 8; + else if (TRX.FFT_Zoom == 8) + TRX.FFT_Zoom = 1; + FFT_Init(); + //LCD_redraw(false); +} + +//---------------------------------------------------------------------------- + +void FRONTPANEL_BUTTONHANDLER_AsB(void) // A/B +{ + TRX_TemporaryMute(); + TRX.current_vfo = !TRX.current_vfo; + TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO()); + TRX_setMode(CurrentVFO()->Mode, CurrentVFO()); + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.FreqInfo = true; + LCD_UpdateQuery.StatusInfoGUI = true; + NeedSaveSettings = true; + NeedReinitAudioFilters = true; + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_TUNE(void) +{ + TRX_Tune = !TRX_Tune; + TRX_ptt_hard = TRX_Tune; + LCD_UpdateQuery.StatusInfoGUIRedraw = true; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; + TRX_Restart_Mode(); +} + +void FRONTPANEL_BUTTONHANDLER_PRE(void) +{ + TRX.ADC_Driver = !TRX.ADC_Driver; + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + TRX.BANDS_SAVED_SETTINGS[band].ADC_Driver = TRX.ADC_Driver; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_ATT(void) +{ + TRX.ATT = !TRX.ATT; + + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + { + TRX.BANDS_SAVED_SETTINGS[band].ATT = TRX.ATT; + TRX.BANDS_SAVED_SETTINGS[band].ATT_DB = TRX.ATT_DB; + } + + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_ATTHOLD(void) +{ + TRX.ATT_DB += TRX.ATT_STEP; + if (TRX.ATT_DB > 31.0f) + TRX.ATT_DB = TRX.ATT_STEP; + + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + { + TRX.BANDS_SAVED_SETTINGS[band].ATT = TRX.ATT; + TRX.BANDS_SAVED_SETTINGS[band].ATT_DB = TRX.ATT_DB; + } + + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_FAST(void) +{ + TRX.Fast = !TRX.Fast; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_MODE_P(void) +{ + //enable claibration hidden menu! + if (LCD_systemMenuOpened) + { + sysmenu_hiddenmenu_enabled = true; + LCD_redraw(false); + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.StatusInfoBar = true; + NeedSaveSettings = true; + return; + } + + int8_t mode = (int8_t)CurrentVFO()->Mode; + if (mode == TRX_MODE_LSB) + mode = TRX_MODE_USB; + else if (mode == TRX_MODE_USB) + mode = TRX_MODE_LSB; + else if (mode == TRX_MODE_CW_L) + mode = TRX_MODE_CW_U; + else if (mode == TRX_MODE_CW_U) + mode = TRX_MODE_CW_L; + else if (mode == TRX_MODE_NFM) + mode = TRX_MODE_WFM; + else if (mode == TRX_MODE_WFM) + mode = TRX_MODE_NFM; + else if (mode == TRX_MODE_DIGI_L) + mode = TRX_MODE_DIGI_U; + else if (mode == TRX_MODE_DIGI_U) + mode = TRX_MODE_DIGI_L; + else if (mode == TRX_MODE_AM) + mode = TRX_MODE_IQ; + else if (mode == TRX_MODE_IQ) + { + mode = TRX_MODE_LOOPBACK; + LCD_UpdateQuery.StatusInfoGUIRedraw = true; + } + else if (mode == TRX_MODE_LOOPBACK) + { + mode = TRX_MODE_AM; + LCD_UpdateQuery.StatusInfoGUIRedraw = true; + } + + TRX_setMode((uint8_t)mode, CurrentVFO()); + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + TRX.BANDS_SAVED_SETTINGS[band].Mode = (uint8_t)mode; + TRX_Temporary_Stop_BandMap = true; +} + +void FRONTPANEL_BUTTONHANDLER_MODE_N(void) +{ + int8_t mode = (int8_t)CurrentVFO()->Mode; + if(mode == TRX_MODE_LOOPBACK) + LCD_UpdateQuery.StatusInfoGUIRedraw = true; + if (mode == TRX_MODE_LSB) + mode = TRX_MODE_CW_L; + else if (mode == TRX_MODE_USB) + mode = TRX_MODE_CW_U; + else if (mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U) + mode = TRX_MODE_DIGI_U; + else if (mode == TRX_MODE_DIGI_L || mode == TRX_MODE_DIGI_U) + mode = TRX_MODE_NFM; + else if (mode == TRX_MODE_NFM || mode == TRX_MODE_WFM) + mode = TRX_MODE_AM; + else + { + if (CurrentVFO()->Freq < 10000000) + mode = TRX_MODE_LSB; + else + mode = TRX_MODE_USB; + } + + TRX_setMode((uint8_t)mode, CurrentVFO()); + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + TRX.BANDS_SAVED_SETTINGS[band].Mode = (uint8_t)mode; + TRX_Temporary_Stop_BandMap = true; +} + +static void FRONTPANEL_BUTTONHANDLER_BAND_P(void) +{ + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + band++; + if (band >= BANDS_COUNT) + band = 0; + while (!BANDS[band].selectable) + { + band++; + if (band >= BANDS_COUNT) + band = 0; + } + + TRX_setFrequency(TRX.BANDS_SAVED_SETTINGS[band].Freq, CurrentVFO()); + TRX_setMode(TRX.BANDS_SAVED_SETTINGS[band].Mode, CurrentVFO()); + TRX.ATT = TRX.BANDS_SAVED_SETTINGS[band].ATT; + TRX.ATT_DB = TRX.BANDS_SAVED_SETTINGS[band].ATT_DB; + TRX.ADC_Driver = TRX.BANDS_SAVED_SETTINGS[band].ADC_Driver; + TRX.FM_SQL_threshold = TRX.BANDS_SAVED_SETTINGS[band].FM_SQL_threshold; + TRX_AutoGain_Stage = TRX.BANDS_SAVED_SETTINGS[band].AutoGain_Stage; + CurrentVFO()->AGC = TRX.BANDS_SAVED_SETTINGS[band].AGC; + TRX_Temporary_Stop_BandMap = false; + + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.FreqInfo = true; +} + +static void FRONTPANEL_BUTTONHANDLER_BAND_N(void) +{ + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + band--; + if (band < 0) + band = BANDS_COUNT - 1; + while (!BANDS[band].selectable) + { + band--; + if (band < 0) + band = BANDS_COUNT - 1; + } + + TRX_setFrequency(TRX.BANDS_SAVED_SETTINGS[band].Freq, CurrentVFO()); + TRX_setMode(TRX.BANDS_SAVED_SETTINGS[band].Mode, CurrentVFO()); + TRX.ATT = TRX.BANDS_SAVED_SETTINGS[band].ATT; + TRX.ATT_DB = TRX.BANDS_SAVED_SETTINGS[band].ATT_DB; + TRX.ADC_Driver = TRX.BANDS_SAVED_SETTINGS[band].ADC_Driver; + TRX.FM_SQL_threshold = TRX.BANDS_SAVED_SETTINGS[band].FM_SQL_threshold; + TRX_AutoGain_Stage = TRX.BANDS_SAVED_SETTINGS[band].AutoGain_Stage; + CurrentVFO()->AGC = TRX.BANDS_SAVED_SETTINGS[band].AGC; + TRX_Temporary_Stop_BandMap = false; + + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.FreqInfo = true; +} + +void FRONTPANEL_BUTTONHANDLER_RF_POWER(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_TRX_RFPOWER_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_AGC(void) +{ + CurrentVFO()->AGC = !CurrentVFO()->AGC; + int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); + if (band > 0) + TRX.BANDS_SAVED_SETTINGS[band].AGC = CurrentVFO()->AGC; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_AGC_SPEED(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_AUDIO_AGC_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +static void FRONTPANEL_BUTTONHANDLER_SQUELCH(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_AUDIO_SQUELCH_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +static void FRONTPANEL_BUTTONHANDLER_WPM(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_CW_WPM_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +static void FRONTPANEL_BUTTONHANDLER_KEYER(void) +{ + TRX.CW_KEYER = !TRX.CW_KEYER; + if(TRX.CW_KEYER) + LCD_showTooltip("KEYER ON"); + else + LCD_showTooltip("KEYER OFF"); +} + +static void FRONTPANEL_BUTTONHANDLER_STEP(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_TRX_STEP_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_BW(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + if (CurrentVFO()->Mode == TRX_MODE_CW_L || CurrentVFO()->Mode == TRX_MODE_CW_U) + SYSMENU_AUDIO_BW_CW_HOTKEY(); + else if (CurrentVFO()->Mode == TRX_MODE_NFM || CurrentVFO()->Mode == TRX_MODE_WFM) + SYSMENU_AUDIO_BW_FM_HOTKEY(); + else if (CurrentVFO()->Mode == TRX_MODE_AM) + SYSMENU_AUDIO_BW_AM_HOTKEY(); + else + SYSMENU_AUDIO_BW_SSB_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_VOLUME(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + SYSMENU_AUDIO_VOLUME_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_HPF(void) +{ + if (!LCD_systemMenuOpened) + { + LCD_systemMenuOpened = true; + if (CurrentVFO()->Mode == TRX_MODE_CW_L || CurrentVFO()->Mode == TRX_MODE_CW_U) + SYSMENU_AUDIO_HPF_CW_HOTKEY(); + else + SYSMENU_AUDIO_HPF_SSB_HOTKEY(); + } + else + { + eventCloseAllSystemMenu(); + } + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_ArB(void) //A=B +{ + if (TRX.current_vfo) + memcpy(&TRX.VFO_A, &TRX.VFO_B, sizeof TRX.VFO_B); + else + memcpy(&TRX.VFO_B, &TRX.VFO_A, sizeof TRX.VFO_B); + + LCD_showTooltip("VFO COPIED"); + + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.FreqInfo = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_NOTCH(void) +{ + TRX_TemporaryMute(); + + if (CurrentVFO()->NotchFC > CurrentVFO()->RX_LPF_Filter_Width) + { + CurrentVFO()->NotchFC = CurrentVFO()->RX_LPF_Filter_Width; + } + + if (!CurrentVFO()->AutoNotchFilter) + { + InitAutoNotchReduction(); + CurrentVFO()->AutoNotchFilter = true; + } + else + CurrentVFO()->AutoNotchFilter = false; + + LCD_UpdateQuery.StatusInfoGUI = true; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_NOTCH_MANUAL(void) +{ + if (CurrentVFO()->NotchFC > CurrentVFO()->RX_LPF_Filter_Width) + CurrentVFO()->NotchFC = CurrentVFO()->RX_LPF_Filter_Width; + CurrentVFO()->AutoNotchFilter = false; + + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.StatusInfoGUI = true; + NeedSaveSettings = true; +} + +static void FRONTPANEL_BUTTONHANDLER_SHIFT(void) +{ + TRX.ShiftEnabled = !TRX.ShiftEnabled; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +static void FRONTPANEL_BUTTONHANDLER_CLAR(void) +{ + TRX.CLAR = !TRX.CLAR; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_LOCK(void) +{ + if (!LCD_systemMenuOpened) + TRX.Locked = !TRX.Locked; + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.StatusInfoBar = true; + NeedSaveSettings = true; +} + +static void FRONTPANEL_BUTTONHANDLER_HIDDEN_ENABLE(void) +{ + if (LCD_systemMenuOpened) + { + sysmenu_hiddenmenu_enabled = true; + LCD_redraw(false); + } + LCD_UpdateQuery.TopButtons = true; + LCD_UpdateQuery.StatusInfoBar = true; + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_MENU(void) +{ + if (!LCD_systemMenuOpened) + LCD_systemMenuOpened = true; + else + eventCloseSystemMenu(); + LCD_redraw(false); +} + +void FRONTPANEL_BUTTONHANDLER_MUTE(void) +{ + TRX_Mute = !TRX_Mute; + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +static void FRONTPANEL_BUTTONHANDLER_BANDMAP(void) +{ + TRX.BandMapEnabled = !TRX.BandMapEnabled; + + if(TRX.BandMapEnabled) + LCD_showTooltip("BANDMAP ON"); + else + LCD_showTooltip("BANDMAP OFF"); + + LCD_UpdateQuery.TopButtons = true; + NeedSaveSettings = true; +} + +static uint16_t FRONTPANEL_ReadMCP3008_Value(uint8_t channel, GPIO_TypeDef *CS_PORT, uint16_t CS_PIN) +{ + uint8_t outData[3] = {0}; + uint8_t inData[3] = {0}; + uint16_t mcp3008_value = 0; + + outData[0] = 0x18 | channel; + bool res = SPI_Transmit(outData, inData, 3, CS_PORT, CS_PIN, false, SPI_FRONT_UNIT_PRESCALER); + if (res == false) + return 65535; + mcp3008_value = (uint16_t)(0 | ((inData[1] & 0x3F) << 4) | (inData[2] & 0xF0 >> 4)); + + //sendToDebug_uint16(mcp3008_value, false); + return mcp3008_value; +} + +static void FRONTPANEL_BUTTONHANDLER_PWR_P(void) +{ + int16_t newval = (int16_t)TRX.RF_Power + 10; + newval /= 10; + newval *= 10; + if(newval > 100) + newval = 100; + TRX.RF_Power = newval; + char str[32] = {0}; + sprintf(str, "PWR: %d%%",TRX.RF_Power); + LCD_showTooltip(str); + NeedSaveSettings = true; +} + +static void FRONTPANEL_BUTTONHANDLER_PWR_N(void) +{ + int16_t newval = (int16_t)TRX.RF_Power - 10; + newval /= 10; + newval *= 10; + if(newval < 0) + newval = 0; + TRX.RF_Power = newval; + char str[32] = {0}; + sprintf(str, "PWR: %d%%",TRX.RF_Power); + LCD_showTooltip(str); + NeedSaveSettings = true; +} + +void FRONTPANEL_BUTTONHANDLER_BW_P(void) +{ + char str[32] = {0}; + switch (CurrentVFO()->Mode) + { + case TRX_MODE_LSB: + case TRX_MODE_USB: + case TRX_MODE_DIGI_L: + case TRX_MODE_DIGI_U: + case TRX_MODE_IQ: + case TRX_MODE_LOOPBACK: + case TRX_MODE_NO_TX: + if (TRX.RX_SSB_LPF_Filter == 0) + TRX.RX_SSB_LPF_Filter = 1400; + if (TRX.RX_SSB_LPF_Filter == 1400) + TRX.RX_SSB_LPF_Filter = 1600; + else if (TRX.RX_SSB_LPF_Filter == 1600) + TRX.RX_SSB_LPF_Filter = 1800; + else if (TRX.RX_SSB_LPF_Filter == 1800) + TRX.RX_SSB_LPF_Filter = 2100; + else if (TRX.RX_SSB_LPF_Filter == 2100) + TRX.RX_SSB_LPF_Filter = 2300; + else if (TRX.RX_SSB_LPF_Filter == 2300) + TRX.RX_SSB_LPF_Filter = 2500; + else if (TRX.RX_SSB_LPF_Filter == 2500) + TRX.RX_SSB_LPF_Filter = 2700; + else if (TRX.RX_SSB_LPF_Filter == 2700) + TRX.RX_SSB_LPF_Filter = 2900; + else if (TRX.RX_SSB_LPF_Filter == 2900) + TRX.RX_SSB_LPF_Filter = 3000; + else if (TRX.RX_SSB_LPF_Filter == 3000) + TRX.RX_SSB_LPF_Filter = 3200; + else if (TRX.RX_SSB_LPF_Filter == 3200) + TRX.RX_SSB_LPF_Filter = 3400; + sprintf(str, "BW: %d",TRX.RX_SSB_LPF_Filter); + break; + + case TRX_MODE_CW_L: + case TRX_MODE_CW_U: + if (TRX.CW_LPF_Filter == 100) + TRX.CW_LPF_Filter = 150; + else if (TRX.CW_LPF_Filter == 150) + TRX.CW_LPF_Filter = 200; + else if (TRX.CW_LPF_Filter == 200) + TRX.CW_LPF_Filter = 250; + else if (TRX.CW_LPF_Filter == 250) + TRX.CW_LPF_Filter = 300; + else if (TRX.CW_LPF_Filter == 300) + TRX.CW_LPF_Filter = 350; + else if (TRX.CW_LPF_Filter == 350) + TRX.CW_LPF_Filter = 400; + else if (TRX.CW_LPF_Filter == 400) + TRX.CW_LPF_Filter = 450; + else if (TRX.CW_LPF_Filter == 450) + TRX.CW_LPF_Filter = 500; + else if (TRX.CW_LPF_Filter == 500) + TRX.CW_LPF_Filter = 550; + else if (TRX.CW_LPF_Filter == 550) + TRX.CW_LPF_Filter = 600; + else if (TRX.CW_LPF_Filter == 600) + TRX.CW_LPF_Filter = 650; + else if (TRX.CW_LPF_Filter == 650) + TRX.CW_LPF_Filter = 700; + else if (TRX.CW_LPF_Filter == 700) + TRX.CW_LPF_Filter = 750; + else if (TRX.CW_LPF_Filter == 750) + TRX.CW_LPF_Filter = 800; + else if (TRX.CW_LPF_Filter == 800) + TRX.CW_LPF_Filter = 850; + else if (TRX.CW_LPF_Filter == 850) + TRX.CW_LPF_Filter = 900; + else if (TRX.CW_LPF_Filter == 900) + TRX.CW_LPF_Filter = 950; + else if (TRX.CW_LPF_Filter == 950) + TRX.CW_LPF_Filter = 1000; + sprintf(str, "BW: %d",TRX.CW_LPF_Filter); + break; + + case TRX_MODE_NFM: + case TRX_MODE_WFM: + if (TRX.RX_FM_LPF_Filter == 5000) + TRX.RX_FM_LPF_Filter = 6000; + else if (TRX.RX_FM_LPF_Filter == 6000) + TRX.RX_FM_LPF_Filter = 7000; + else if (TRX.RX_FM_LPF_Filter == 7000) + TRX.RX_FM_LPF_Filter = 8000; + else if (TRX.RX_FM_LPF_Filter == 8000) + TRX.RX_FM_LPF_Filter = 9000; + else if (TRX.RX_FM_LPF_Filter == 9000) + TRX.RX_FM_LPF_Filter = 10000; + else if (TRX.RX_FM_LPF_Filter == 10000) + TRX.RX_FM_LPF_Filter = 15000; + else if (TRX.RX_FM_LPF_Filter == 15000) + TRX.RX_FM_LPF_Filter = 20000; + sprintf(str, "BW: %d",TRX.RX_FM_LPF_Filter); + break; + + case TRX_MODE_AM: + if (TRX.RX_AM_LPF_Filter == 2100) + TRX.RX_AM_LPF_Filter = 2300; + else if (TRX.RX_AM_LPF_Filter == 2300) + TRX.RX_AM_LPF_Filter = 2500; + else if (TRX.RX_AM_LPF_Filter == 2500) + TRX.RX_AM_LPF_Filter = 2700; + else if (TRX.RX_AM_LPF_Filter == 2700) + TRX.RX_AM_LPF_Filter = 2900; + else if (TRX.RX_AM_LPF_Filter == 2900) + TRX.RX_AM_LPF_Filter = 3000; + else if (TRX.RX_AM_LPF_Filter == 3000) + TRX.RX_AM_LPF_Filter = 3200; + else if (TRX.RX_AM_LPF_Filter == 3200) + TRX.RX_AM_LPF_Filter = 3400; + else if (TRX.RX_AM_LPF_Filter == 3400) + TRX.RX_AM_LPF_Filter = 3600; + else if (TRX.RX_AM_LPF_Filter == 3600) + TRX.RX_AM_LPF_Filter = 3800; + else if (TRX.RX_AM_LPF_Filter == 3800) + TRX.RX_AM_LPF_Filter = 4000; + else if (TRX.RX_AM_LPF_Filter == 4000) + TRX.RX_AM_LPF_Filter = 4500; + else if (TRX.RX_AM_LPF_Filter == 4500) + TRX.RX_AM_LPF_Filter = 5000; + else if (TRX.RX_AM_LPF_Filter == 5000) + TRX.RX_AM_LPF_Filter = 6000; + else if (TRX.RX_AM_LPF_Filter == 6000) + TRX.RX_AM_LPF_Filter = 7000; + else if (TRX.RX_AM_LPF_Filter == 7000) + TRX.RX_AM_LPF_Filter = 8000; + else if (TRX.RX_AM_LPF_Filter == 8000) + TRX.RX_AM_LPF_Filter = 9000; + else if (TRX.RX_AM_LPF_Filter == 9000) + TRX.RX_AM_LPF_Filter = 10000; + sprintf(str, "BW: %d",TRX.RX_AM_LPF_Filter); + break; + } + + TRX_setMode(SecondaryVFO()->Mode, SecondaryVFO()); + TRX_setMode(CurrentVFO()->Mode, CurrentVFO()); + LCD_showTooltip(str); + NeedSaveSettings = true; +} + + void FRONTPANEL_BUTTONHANDLER_BW_N(void) +{ + char str[32] = {0}; + switch (CurrentVFO()->Mode) + { + case TRX_MODE_LSB: + case TRX_MODE_USB: + case TRX_MODE_DIGI_L: + case TRX_MODE_DIGI_U: + case TRX_MODE_IQ: + case TRX_MODE_LOOPBACK: + case TRX_MODE_NO_TX: + if (TRX.RX_SSB_LPF_Filter == 1600) + TRX.RX_SSB_LPF_Filter = 1400; + else if (TRX.RX_SSB_LPF_Filter == 1800) + TRX.RX_SSB_LPF_Filter = 1600; + else if (TRX.RX_SSB_LPF_Filter == 2100) + TRX.RX_SSB_LPF_Filter = 1800; + else if (TRX.RX_SSB_LPF_Filter == 2300) + TRX.RX_SSB_LPF_Filter = 2100; + else if (TRX.RX_SSB_LPF_Filter == 2500) + TRX.RX_SSB_LPF_Filter = 2300; + else if (TRX.RX_SSB_LPF_Filter == 2700) + TRX.RX_SSB_LPF_Filter = 2500; + else if (TRX.RX_SSB_LPF_Filter == 2900) + TRX.RX_SSB_LPF_Filter = 2700; + else if (TRX.RX_SSB_LPF_Filter == 3000) + TRX.RX_SSB_LPF_Filter = 2900; + else if (TRX.RX_SSB_LPF_Filter == 3200) + TRX.RX_SSB_LPF_Filter = 3000; + else if (TRX.RX_SSB_LPF_Filter == 3400) + TRX.RX_SSB_LPF_Filter = 3200; + sprintf(str, "BW: %d",TRX.RX_SSB_LPF_Filter); + break; + + case TRX_MODE_CW_L: + case TRX_MODE_CW_U: + if (TRX.CW_LPF_Filter == 1000) + TRX.CW_LPF_Filter = 950; + else if (TRX.CW_LPF_Filter == 950) + TRX.CW_LPF_Filter = 900; + else if (TRX.CW_LPF_Filter == 900) + TRX.CW_LPF_Filter = 850; + else if (TRX.CW_LPF_Filter == 850) + TRX.CW_LPF_Filter = 800; + else if (TRX.CW_LPF_Filter == 800) + TRX.CW_LPF_Filter = 750; + else if (TRX.CW_LPF_Filter == 750) + TRX.CW_LPF_Filter = 700; + else if (TRX.CW_LPF_Filter == 700) + TRX.CW_LPF_Filter = 650; + else if (TRX.CW_LPF_Filter == 650) + TRX.CW_LPF_Filter = 600; + else if (TRX.CW_LPF_Filter == 600) + TRX.CW_LPF_Filter = 550; + else if (TRX.CW_LPF_Filter == 550) + TRX.CW_LPF_Filter = 500; + else if (TRX.CW_LPF_Filter == 500) + TRX.CW_LPF_Filter = 450; + else if (TRX.CW_LPF_Filter == 450) + TRX.CW_LPF_Filter = 400; + else if (TRX.CW_LPF_Filter == 400) + TRX.CW_LPF_Filter = 350; + else if (TRX.CW_LPF_Filter == 350) + TRX.CW_LPF_Filter = 300; + else if (TRX.CW_LPF_Filter == 300) + TRX.CW_LPF_Filter = 250; + else if (TRX.CW_LPF_Filter == 250) + TRX.CW_LPF_Filter = 200; + else if (TRX.CW_LPF_Filter == 200) + TRX.CW_LPF_Filter = 150; + else if (TRX.CW_LPF_Filter == 150) + TRX.CW_LPF_Filter = 100; + sprintf(str, "BW: %d",TRX.CW_LPF_Filter); + break; + + case TRX_MODE_NFM: + case TRX_MODE_WFM: + if (TRX.RX_FM_LPF_Filter == 6000) + TRX.RX_FM_LPF_Filter = 5000; + else if (TRX.RX_FM_LPF_Filter == 7000) + TRX.RX_FM_LPF_Filter = 6000; + else if (TRX.RX_FM_LPF_Filter == 8000) + TRX.RX_FM_LPF_Filter = 7000; + else if (TRX.RX_FM_LPF_Filter == 9000) + TRX.RX_FM_LPF_Filter = 8000; + else if (TRX.RX_FM_LPF_Filter == 10000) + TRX.RX_FM_LPF_Filter = 9000; + else if (TRX.RX_FM_LPF_Filter == 15000) + TRX.RX_FM_LPF_Filter = 10000; + else if (TRX.RX_FM_LPF_Filter == 20000) + TRX.RX_FM_LPF_Filter = 15000; + sprintf(str, "BW: %d",TRX.RX_FM_LPF_Filter); + break; + + case TRX_MODE_AM: + if (TRX.RX_AM_LPF_Filter == 2300) + TRX.RX_AM_LPF_Filter = 2100; + else if (TRX.RX_AM_LPF_Filter == 2500) + TRX.RX_AM_LPF_Filter = 2300; + else if (TRX.RX_AM_LPF_Filter == 2700) + TRX.RX_AM_LPF_Filter = 2500; + else if (TRX.RX_AM_LPF_Filter == 2900) + TRX.RX_AM_LPF_Filter = 2700; + else if (TRX.RX_AM_LPF_Filter == 3000) + TRX.RX_AM_LPF_Filter = 2900; + else if (TRX.RX_AM_LPF_Filter == 3200) + TRX.RX_AM_LPF_Filter = 3000; + else if (TRX.RX_AM_LPF_Filter == 3400) + TRX.RX_AM_LPF_Filter = 3200; + else if (TRX.RX_AM_LPF_Filter == 3600) + TRX.RX_AM_LPF_Filter = 3400; + else if (TRX.RX_AM_LPF_Filter == 3800) + TRX.RX_AM_LPF_Filter = 3400; + else if (TRX.RX_AM_LPF_Filter == 4000) + TRX.RX_AM_LPF_Filter = 3800; + else if (TRX.RX_AM_LPF_Filter == 4500) + TRX.RX_AM_LPF_Filter = 3800; + else if (TRX.RX_AM_LPF_Filter == 5000) + TRX.RX_AM_LPF_Filter = 4500; + else if (TRX.RX_AM_LPF_Filter == 6000) + TRX.RX_AM_LPF_Filter = 5000; + else if (TRX.RX_AM_LPF_Filter == 7000) + TRX.RX_AM_LPF_Filter = 6000; + else if (TRX.RX_AM_LPF_Filter == 8000) + TRX.RX_AM_LPF_Filter = 7000; + else if (TRX.RX_AM_LPF_Filter == 9000) + TRX.RX_AM_LPF_Filter = 8000; + else if (TRX.RX_AM_LPF_Filter == 10000) + TRX.RX_AM_LPF_Filter = 9000; + sprintf(str, "BW: %d",TRX.RX_AM_LPF_Filter); + break; + } + + TRX_setMode(SecondaryVFO()->Mode, SecondaryVFO()); + TRX_setMode(CurrentVFO()->Mode, CurrentVFO()); + LCD_showTooltip(str); + NeedSaveSettings = true; +} diff --git a/STM32/Core/Src/agc.c b/STM32/Core/Src/agc.c index 0a1feac..6cd4144 100644 --- a/STM32/Core/Src/agc.c +++ b/STM32/Core/Src/agc.c @@ -5,21 +5,20 @@ //Private variables static float32_t AGC_RX_need_gain_db = 0.0f; +static float32_t AGC_TX_need_gain_db = 0.0f; static float32_t AGC_RX_need_gain_db_old = 0.0f; +static float32_t AGC_TX_need_gain_db_old = 0.0f; +static float32_t AGC_RX_agcBuffer_kw[AUDIO_BUFFER_HALF_SIZE] = {0}; IRAM2 static float32_t AGC_RX_ringbuffer[AGC_RINGBUFFER_TAPS_SIZE * AUDIO_BUFFER_HALF_SIZE] = {0}; +static float32_t AGC_TX_ringbuffer_i[AGC_RINGBUFFER_TAPS_SIZE * AUDIO_BUFFER_HALF_SIZE] = {0}; //Run AGC on data block void DoRxAGC(float32_t *agcBuffer, uint_fast16_t blockSize, uint_fast8_t mode) { - //RX1 or RX2 - float32_t *AGC_need_gain_db = &AGC_RX_need_gain_db; - float32_t *AGC_need_gain_db_old = &AGC_RX_need_gain_db_old; - float32_t *agc_ringbuffer = (float32_t*)&AGC_RX_ringbuffer; - //higher speed in settings - higher speed of AGC processing float32_t RX_AGC_STEPSIZE_UP = 0.0f; float32_t RX_AGC_STEPSIZE_DOWN = 0.0f; - if(mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U) + if (mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U) { RX_AGC_STEPSIZE_UP = 200.0f / (float32_t)TRX.RX_AGC_CW_speed; RX_AGC_STEPSIZE_DOWN = 20.0f / (float32_t)TRX.RX_AGC_CW_speed; @@ -30,38 +29,42 @@ void DoRxAGC(float32_t *agcBuffer, uint_fast16_t blockSize, uint_fast8_t mode) RX_AGC_STEPSIZE_DOWN = 20.0f / (float32_t)TRX.RX_AGC_SSB_speed; } + //do k-weighting (for LKFS) + arm_biquad_cascade_df2T_f32(&AGC_RX_KW_HSHELF_FILTER, agcBuffer, AGC_RX_agcBuffer_kw, blockSize); + arm_biquad_cascade_df2T_f32(&AGC_RX_KW_HPASS_FILTER, agcBuffer, AGC_RX_agcBuffer_kw, blockSize); + //do ring buffer static uint32_t ring_position = 0; //save new data to ring buffer - memcpy(&agc_ringbuffer[ring_position * blockSize], agcBuffer, sizeof(float32_t) * blockSize); + memcpy(&AGC_RX_ringbuffer[ring_position * blockSize], agcBuffer, sizeof(float32_t) * blockSize); //move ring buffer index - ring_position++; - if(ring_position >= AGC_RINGBUFFER_TAPS_SIZE) + ring_position++; + if (ring_position >= AGC_RINGBUFFER_TAPS_SIZE) ring_position = 0; //get old data to process - memcpy(agcBuffer, &agc_ringbuffer[ring_position * blockSize], sizeof(float32_t) * blockSize); - + memcpy(agcBuffer, &AGC_RX_ringbuffer[ring_position * blockSize], sizeof(float32_t) * blockSize); + //calculate the magnitude in dBFS float32_t AGC_RX_magnitude = 0; - arm_rms_f32(agcBuffer, blockSize, &AGC_RX_magnitude); + arm_rms_f32(AGC_RX_agcBuffer_kw, blockSize, &AGC_RX_magnitude); if (AGC_RX_magnitude == 0.0f) AGC_RX_magnitude = 0.001f; float32_t full_scale_rate = AGC_RX_magnitude / FLOAT_FULL_SCALE_POW; float32_t AGC_RX_dbFS = rate2dbV(full_scale_rate); //move the gain one step - if(!WM8731_Muting) + if (!WM8731_Muting) { - float32_t diff = ((float32_t)TRX.AGC_GAIN_TARGET - (AGC_RX_dbFS + *AGC_need_gain_db)); + float32_t diff = ((float32_t)TRX.AGC_GAIN_TARGET - (AGC_RX_dbFS + AGC_RX_need_gain_db)); if (diff > 0) - *AGC_need_gain_db += diff / RX_AGC_STEPSIZE_UP; + AGC_RX_need_gain_db += diff / RX_AGC_STEPSIZE_UP; else - *AGC_need_gain_db += diff / RX_AGC_STEPSIZE_DOWN; + AGC_RX_need_gain_db += diff / RX_AGC_STEPSIZE_DOWN; //overload (clipping), sharply reduce the gain - if ((AGC_RX_dbFS + *AGC_need_gain_db) > ((float32_t)TRX.AGC_GAIN_TARGET + AGC_CLIPPING)) + if ((AGC_RX_dbFS + AGC_RX_need_gain_db) > ((float32_t)TRX.AGC_GAIN_TARGET + AGC_CLIPPING)) { - *AGC_need_gain_db = (float32_t)TRX.AGC_GAIN_TARGET - AGC_RX_dbFS; + AGC_RX_need_gain_db = (float32_t)TRX.AGC_GAIN_TARGET - AGC_RX_dbFS; //sendToDebug_float32(diff,false); } } @@ -72,16 +75,142 @@ void DoRxAGC(float32_t *agcBuffer, uint_fast16_t blockSize, uint_fast8_t mode) //AGC off, not adjustable if (!CurrentVFO()->AGC) - *AGC_need_gain_db = 1.0f; - + AGC_RX_need_gain_db = 1.0f; + //Muting if need - if(WM8731_Muting) + if (WM8731_Muting) + AGC_RX_need_gain_db = -200.0f; + + //gain limitation + if (AGC_RX_need_gain_db > AGC_MAX_GAIN) + AGC_RX_need_gain_db = AGC_MAX_GAIN; + + //apply gain + //sendToDebug_float32(AGC_RX_need_gain_db, false); + if (fabsf(AGC_RX_need_gain_db_old - AGC_RX_need_gain_db) > 0.0f) //gain changed + { + float32_t gainApplyStep = 0; + if (AGC_RX_need_gain_db_old > AGC_RX_need_gain_db) + gainApplyStep = -(AGC_RX_need_gain_db_old - AGC_RX_need_gain_db) / (float32_t)blockSize; + if (AGC_RX_need_gain_db_old < AGC_RX_need_gain_db) + gainApplyStep = (AGC_RX_need_gain_db - AGC_RX_need_gain_db_old) / (float32_t)blockSize; + float32_t val_prev = 0.0f; + bool zero_cross = false; + for (uint_fast16_t i = 0; i < blockSize; i++) + { + if (val_prev < 0.0f && agcBuffer[i] > 0.0f) + zero_cross = true; + else if (val_prev > 0.0f && agcBuffer[i] < 0.0f) + zero_cross = true; + if (zero_cross) + AGC_RX_need_gain_db_old += gainApplyStep; + + agcBuffer[i] = agcBuffer[i] * db2rateV(AGC_RX_need_gain_db_old); + val_prev = agcBuffer[i]; + } + } + else //gain did not change, apply gain across all samples + { + arm_scale_f32(agcBuffer, db2rateV(AGC_RX_need_gain_db), agcBuffer, blockSize); + } +} + +//Run TX AGC on data block +void DoTxAGC(float32_t *agcBuffer_i, uint_fast16_t blockSize, float32_t target, uint_fast8_t mode) +{ + float32_t *AGC_need_gain_db = &AGC_TX_need_gain_db; + float32_t *AGC_need_gain_db_old = &AGC_TX_need_gain_db_old; + float32_t *agc_ringbuffer_i = (float32_t *)&AGC_TX_ringbuffer_i; + + //higher speed in settings - higher speed of AGC processing + float32_t TX_AGC_STEPSIZE_UP = 0.0f; + float32_t TX_AGC_STEPSIZE_DOWN = 0.0f; + switch(mode) + { + case TRX_MODE_LSB: + case TRX_MODE_USB: + case TRX_MODE_LOOPBACK: + default: + TX_AGC_STEPSIZE_UP = 200.0f / 3.0f; //TX_Compressor_speed_SSB + TX_AGC_STEPSIZE_DOWN = 20.0f / 3.0f; //TX_Compressor_speed_SSB + break; + + case TRX_MODE_NFM: + case TRX_MODE_WFM: + case TRX_MODE_AM: + TX_AGC_STEPSIZE_UP = 200.0f / 3.0f; //TX_Compressor_speed_AMFM + TX_AGC_STEPSIZE_DOWN = 20.0f / 3.0f; //TX_Compressor_speed_AMFM + break; + } + + //do ring buffer + static uint32_t ring_position = 0; + //save new data to ring buffer + memcpy(&agc_ringbuffer_i[ring_position * blockSize], agcBuffer_i, sizeof(float32_t) * blockSize); + //move ring buffer index + ring_position++; + if (ring_position >= AGC_RINGBUFFER_TAPS_SIZE) + ring_position = 0; + //get old data to process + memcpy(agcBuffer_i, &agc_ringbuffer_i[ring_position * blockSize], sizeof(float32_t) * blockSize); + + //calculate the magnitude + float32_t AGC_TX_I_magnitude = 0; + float32_t ampl_max_i = 0.0f; + float32_t ampl_min_i = 0.0f; + uint32_t tmp_index; + arm_max_no_idx_f32(agcBuffer_i, blockSize, &l_max_i); + arm_min_f32(agcBuffer_i, blockSize, &l_min_i, &tmp_index); + if (ampl_max_i > -ampl_min_i) + AGC_TX_I_magnitude = ampl_max_i; + else + AGC_TX_I_magnitude = -ampl_min_i; + + if (AGC_TX_I_magnitude == 0.0f) + AGC_TX_I_magnitude = 0.001f; + float32_t AGC_TX_dbFS = rate2dbV(AGC_TX_I_magnitude); + + //move the gain one step + float32_t diff = (target - (AGC_TX_dbFS + *AGC_need_gain_db)); + if (diff > 0) + *AGC_need_gain_db += diff / TX_AGC_STEPSIZE_UP; + else + *AGC_need_gain_db += diff / TX_AGC_STEPSIZE_DOWN; + + //overload (clipping), sharply reduce the gain + if ((AGC_TX_dbFS + *AGC_need_gain_db) > target) + { + *AGC_need_gain_db = target - AGC_TX_dbFS; + //sendToDebug_float32(diff,false); + } + + //noise threshold, below it - do not amplify + /*if (AGC_RX_dbFS < AGC_NOISE_GATE) + *AGC_need_gain_db = 1.0f;*/ + + //Muting if need + if (target == 0.0f) *AGC_need_gain_db = -200.0f; //gain limitation - if (*AGC_need_gain_db > AGC_MAX_GAIN) - *AGC_need_gain_db = AGC_MAX_GAIN; - + switch(mode) + { + case TRX_MODE_LSB: + case TRX_MODE_USB: + case TRX_MODE_LOOPBACK: + default: + if (*AGC_need_gain_db > 10.0f) //TX_Compressor_maxgain_SSB + *AGC_need_gain_db = 10.0f; //TX_Compressor_maxgain_SSB + break; + + case TRX_MODE_NFM: + case TRX_MODE_WFM: + case TRX_MODE_AM: + if (*AGC_need_gain_db > 10.0f) //TX_Compressor_maxgain_AMFM + *AGC_need_gain_db = 10.0f; //TX_Compressor_maxgain_AMFM + break; + } + //apply gain if (fabsf(*AGC_need_gain_db_old - *AGC_need_gain_db) > 0.0f) //gain changed { @@ -94,20 +223,20 @@ void DoRxAGC(float32_t *agcBuffer, uint_fast16_t blockSize, uint_fast8_t mode) bool zero_cross = false; for (uint_fast16_t i = 0; i < blockSize; i++) { - if(val_prev < 0.0f && agcBuffer[i] > 0.0f) + if (val_prev < 0.0f && agcBuffer_i[i] > 0.0f) zero_cross = true; - else if(val_prev > 0.0f && agcBuffer[i] < 0.0f) + else if (val_prev > 0.0f && agcBuffer_i[i] < 0.0f) zero_cross = true; - if(zero_cross) + if (zero_cross) *AGC_need_gain_db_old += gainApplyStep; - - agcBuffer[i] = agcBuffer[i] * db2rateV(*AGC_need_gain_db_old); - val_prev = agcBuffer[i]; + + agcBuffer_i[i] = agcBuffer_i[i] * db2rateV(*AGC_need_gain_db_old); + val_prev = agcBuffer_i[i]; } } else //gain did not change, apply gain across all samples { - arm_scale_f32(agcBuffer, db2rateV(*AGC_need_gain_db), agcBuffer, blockSize); + arm_scale_f32(agcBuffer_i, db2rateV(*AGC_need_gain_db), agcBuffer_i, blockSize); } } diff --git a/STM32/Core/Src/agc.h b/STM32/Core/Src/agc.h index 7e2cf9a..40a5251 100644 --- a/STM32/Core/Src/agc.h +++ b/STM32/Core/Src/agc.h @@ -8,7 +8,8 @@ #define AGC_RINGBUFFER_TAPS_SIZE 3 //Public methods -extern void DoRxAGC(float32_t *agcbuffer, uint_fast16_t blockSize, uint_fast8_t mode); // start AGC on a data block +extern void DoRxAGC(float32_t *agcbuffer, uint_fast16_t blockSize, uint_fast8_t mode); // start RX AGC on a data block +extern void DoTxAGC(float32_t *agcbuffer_i, uint_fast16_t blockSize, float32_t target, uint_fast8_t mode); // start TX AGC on a data block extern void ResetAGC(void); #endif diff --git a/STM32/Core/Src/audio_filters.c b/STM32/Core/Src/audio_filters.c index db53aec..906d294 100644 --- a/STM32/Core/Src/audio_filters.c +++ b/STM32/Core/Src/audio_filters.c @@ -35,6 +35,10 @@ static float32_t EQ_MIC_HIG_FILTER_State[2 * EQ_STAGES] = {0}; static float32_t EQ_MIC_LOW_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0}; static float32_t EQ_MIC_MID_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0}; static float32_t EQ_MIC_HIG_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0}; +static float32_t AGC_RX_KW_HSHELF_FILTER_State[2 * EQ_STAGES] = {0}; +static float32_t AGC_RX_KW_HPASS_FILTER_State[2 * EQ_STAGES] = {0}; +static float32_t AGC_RX_KW_HSHELF_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0}; +static float32_t AGC_RX_KW_HPASS_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0}; static DC_filter_state_type DC_Filter_State[8] = {0}; // states of the DC corrector @@ -491,6 +495,8 @@ arm_biquad_cascade_df2T_instance_f32 EQ_RX_HIG_FILTER = {EQ_STAGES, EQ_RX_HIG_FI arm_biquad_cascade_df2T_instance_f32 EQ_MIC_LOW_FILTER = {EQ_STAGES, EQ_MIC_LOW_FILTER_State, EQ_MIC_LOW_FILTER_Coeffs}; arm_biquad_cascade_df2T_instance_f32 EQ_MIC_MID_FILTER = {EQ_STAGES, EQ_MIC_MID_FILTER_State, EQ_MIC_MID_FILTER_Coeffs}; arm_biquad_cascade_df2T_instance_f32 EQ_MIC_HIG_FILTER = {EQ_STAGES, EQ_MIC_HIG_FILTER_State, EQ_MIC_HIG_FILTER_Coeffs}; +arm_biquad_cascade_df2T_instance_f32 AGC_RX_KW_HSHELF_FILTER = {EQ_STAGES, AGC_RX_KW_HSHELF_FILTER_State, AGC_RX_KW_HSHELF_FILTER_Coeffs}; +arm_biquad_cascade_df2T_instance_f32 AGC_RX_KW_HPASS_FILTER = {EQ_STAGES, AGC_RX_KW_HPASS_FILTER_State, AGC_RX_KW_HPASS_FILTER_Coeffs}; volatile bool NeedReinitNotch = false; // need to re-initialize the manual Notch filter volatile bool NeedReinitAudioFilters = false; // need to re-initialize Audio filters volatile bool NeedReinitAudioFiltersClean = false; //also clean state @@ -509,6 +515,10 @@ void InitAudioFilters(void) arm_fir_init_f32(&FIR_TX_Hilbert_I, IQ_HILBERT_TAPS, (float32_t *)&FIR_HILB_I_coeffs, (float32_t *)&Fir_Tx_Hilbert_State_I[0], AUDIO_BUFFER_HALF_SIZE); arm_fir_init_f32(&FIR_TX_Hilbert_Q, IQ_HILBERT_TAPS, (float32_t *)&FIR_HILB_Q_coeffs, (float32_t *)&Fir_Tx_Hilbert_State_Q[0], AUDIO_BUFFER_HALF_SIZE); + //AGC K-Weight LKFS BS.1770 + calcBiquad(BIQUAD_highShelf, 1500, TRX_SAMPLERATE, 1.0f / sqrtf(2), 4.0f, AGC_RX_KW_HSHELF_FILTER_Coeffs); + calcBiquad(BIQUAD_highpass, 38, TRX_SAMPLERATE, 0.5f, 0.0f, AGC_RX_KW_HPASS_FILTER_Coeffs); + //Other InitAutoNotchReduction(); ReinitAudioFilters(); diff --git a/STM32/Core/Src/audio_filters.h b/STM32/Core/Src/audio_filters.h index d3c2320..063c5be 100644 --- a/STM32/Core/Src/audio_filters.h +++ b/STM32/Core/Src/audio_filters.h @@ -101,6 +101,8 @@ extern arm_biquad_cascade_df2T_instance_f32 EQ_RX_HIG_FILTER; extern arm_biquad_cascade_df2T_instance_f32 EQ_MIC_LOW_FILTER; extern arm_biquad_cascade_df2T_instance_f32 EQ_MIC_MID_FILTER; extern arm_biquad_cascade_df2T_instance_f32 EQ_MIC_HIG_FILTER; +extern arm_biquad_cascade_df2T_instance_f32 AGC_RX_KW_HSHELF_FILTER; +extern arm_biquad_cascade_df2T_instance_f32 AGC_RX_KW_HPASS_FILTER; extern volatile bool NeedReinitAudioFilters; // need to reinitialize the Audio filters //Public methods diff --git a/STM32/Core/Src/audio_processor.c b/STM32/Core/Src/audio_processor.c index a497820..18fc1a7 100644 --- a/STM32/Core/Src/audio_processor.c +++ b/STM32/Core/Src/audio_processor.c @@ -199,7 +199,7 @@ void processRxAudio(void) if (current_vfo->Mode == TRX_MODE_IQ) arm_float_to_q31(&FPGA_Audio_Buffer_RX_Q_tmp[i], &Processor_AudioBuffer_current[i * 2 + 1], 1); //right channel else - arm_float_to_q31(&FPGA_Audio_Buffer_RX_I_tmp[i], &Processor_AudioBuffer_current[i * 2 + 1], 1); //right channel + Processor_AudioBuffer_current[i * 2 + 1] = Processor_AudioBuffer_current[i * 2]; //right channel } if (Processor_AudioBuffer_ReadyBuffer == 0) Processor_AudioBuffer_ReadyBuffer = 1; diff --git a/STM32/Core/Src/color_themes.h b/STM32/Core/Src/color_themes.h index 6e951de..f7d2dbf 100644 --- a/STM32/Core/Src/color_themes.h +++ b/STM32/Core/Src/color_themes.h @@ -67,7 +67,7 @@ static const STRUCT_COLOR_THEME COLOR_THEMES[2] = { .FOREGROUND = COLOR_WHITE, .BUTTON_TEXT = rgb888torgb565(32, 191, 17), .BUTTON_INACTIVE_TEXT = rgb888torgb565(130, 130, 130), - .BUTTON_BACKGROUND = rgb888torgb565(50, 50, 50), + .BUTTON_BACKGROUND = rgb888torgb565(54, 54, 54), .FREQ_MHZ = COLOR_WHITE, .FREQ_KHZ = COLOR_WHITE, .FREQ_HZ = rgb888torgb565(150, 150, 150), diff --git a/STM32/Core/Src/fft.c b/STM32/Core/Src/fft.c index 8170633..64e7b8c 100644 --- a/STM32/Core/Src/fft.c +++ b/STM32/Core/Src/fft.c @@ -634,12 +634,12 @@ bool FFT_printFFT(void) //gradient for (uint32_t fft_x = 0; fft_x < LAY_FFT_PRINT_SIZE; fft_x++) { - if (fft_x >= bw_line_start && fft_x <= bw_line_end) //bw bar + if (fft_x == bw_line_start || fft_x == bw_line_end) //bw bar { if (fft_y >= (LAY_FFT_HEIGHT - fft_header[fft_x])) - fft_output_buffer[fft_y][fft_x] = palette_bw_fft_colors[fft_y]; + fft_output_buffer[fft_y][fft_x] = palette_fft[LAY_FFT_HEIGHT / 2]; else - fft_output_buffer[fft_y][fft_x] = palette_bw_bg_colors[fft_y]; + fft_output_buffer[fft_y][fft_x] = palette_fft[LAY_FFT_HEIGHT / 2]; } else //other fft data { @@ -668,9 +668,13 @@ bool FFT_printFFT(void) } //draw center line - for (uint32_t fft_y = 0; fft_y < LAY_FFT_HEIGHT; fft_y++) - fft_output_buffer[fft_y][(LAY_FFT_PRINT_SIZE / 2)] = palette_fft[LAY_FFT_HEIGHT / 2]; //mixColors(fft_output_buffer[fft_y][(LAY_FFT_PRINT_SIZE / 2)], palette_fft[fftHeight / 2], FFT_SCALE_LINES_BRIGHTNESS); - + for (uint32_t fft_y = 0; fft_y < LAY_FFT_HEIGHT; fft_y++) { + fft_output_buffer[fft_y] [(LAY_FFT_PRINT_SIZE / 2)] = palette_fft[LAY_FFT_HEIGHT / rgb888torgb565(0, 200, 255)]; //mixColors(fft_output_buffer[fft_y][(LAY_FFT_PRINT_SIZE / 2)], palette_fft[fftHeight / 2], FFT_SCALE_LINES_BRIGHTNESS); + fft_output_buffer[fft_y] [(LAY_FFT_PRINT_SIZE / 2) -1] = palette_fft[LAY_FFT_HEIGHT / rgb888torgb565(0, 200, 255)]; + fft_output_buffer[fft_y] [(LAY_FFT_PRINT_SIZE / 2) +1] = palette_fft[LAY_FFT_HEIGHT / rgb888torgb565(0, 200, 255)]; + } + + //Print FFT LCDDriver_SetCursorAreaPosition(0, LAY_FFT_FFTWTF_POS_Y, LAY_FFT_PRINT_SIZE - 1, (LAY_FFT_FFTWTF_POS_Y + LAY_FFT_HEIGHT)); print_fft_dma_estimated_size = LAY_FFT_PRINT_SIZE * LAY_FFT_HEIGHT; @@ -793,27 +797,27 @@ void FFT_printWaterfallDMA(void) if (margin_left == 0 && margin_right == 0) { for (uint32_t wtf_x = 0; wtf_x < LAY_FFT_PRINT_SIZE; wtf_x++) - if (wtf_x >= bw_line_start && wtf_x <= bw_line_end) //print bw bar - wtf_output_line[wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; - else +// if (wtf_x >= bw_line_start && wtf_x <= bw_line_end) //print bw bar +// wtf_output_line[wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; +// else wtf_output_line[wtf_x] = palette_fft[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; } else if (margin_left > 0) { memset(&wtf_output_line, BG_COLOR, (uint32_t)(margin_left * 2)); // fill the space to the left for (uint32_t wtf_x = 0; wtf_x < (LAY_FFT_PRINT_SIZE - margin_left); wtf_x++) - if ((margin_left + wtf_x) >= bw_line_start && (margin_left + wtf_x) <= bw_line_end) //print bw bar - wtf_output_line[margin_left + wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; - else +// if ((margin_left + wtf_x) >= bw_line_start && (margin_left + wtf_x) <= bw_line_end) //print bw bar +// wtf_output_line[margin_left + wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; +// else wtf_output_line[margin_left + wtf_x] = palette_fft[indexed_wtf_buffer[print_wtf_yindex][wtf_x]]; } if (margin_right > 0) { memset(&wtf_output_line[(LAY_FFT_PRINT_SIZE - margin_right)], BG_COLOR, (uint32_t)(margin_right * 2)); // fill the space to the right for (uint32_t wtf_x = 0; wtf_x < (LAY_FFT_PRINT_SIZE - margin_right); wtf_x++) - if (wtf_x >= bw_line_start && wtf_x <= bw_line_end) //print bw bar - wtf_output_line[wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x + margin_right]]; - else +// if (wtf_x >= bw_line_start && wtf_x <= bw_line_end) //print bw bar +// wtf_output_line[wtf_x] = palette_bw_fft_colors[indexed_wtf_buffer[print_wtf_yindex][wtf_x + margin_right]]; +// else wtf_output_line[wtf_x] = palette_fft[indexed_wtf_buffer[print_wtf_yindex][wtf_x + margin_right]]; } } diff --git a/STM32/Core/Src/fft.h b/STM32/Core/Src/fft.h index cc4d57d..4106e81 100644 --- a/STM32/Core/Src/fft.h +++ b/STM32/Core/Src/fft.h @@ -11,10 +11,10 @@ #define FFT_SIZE 512 // specify the size of the calculated FFT #define FFT_USEFUL_SIZE 512 // size after FFT cropping #define FFT_DOUBLE_SIZE_BUFFER (FFT_SIZE * 2) // Buffer size for FFT calculation -#define FFT_MIN 4.0f // MIN threshold of FFT signal +#define FFT_MIN 1.5f // MIN threshold of FFT signal #define FFT_TARGET 6.0f // average threshold of the FFT signal #define FFT_COMPRESS_INTERVAL 0.9f // compress interval of the FFT signal -#define FFT_MAX 8.0f // MAX FFT signal threshold +#define FFT_MAX 9.0f // MAX FFT signal threshold #define FFT_STEP_COEFF 10.0f // step coefficient for auto-calibration of the FFT signal (more - slower) #define FFT_HZ_IN_PIXEL (float32_t)((float32_t)TRX_SAMPLERATE / (float32_t)LAY_FFT_PRINT_SIZE) // hertz per pixel #define FFT_BW_BRIGHTNESS 10 // pixel brightness on bw bar diff --git a/STM32/Core/Src/front_unit.c b/STM32/Core/Src/front_unit.c index 61cf422..2fe21e9 100644 --- a/STM32/Core/Src/front_unit.c +++ b/STM32/Core/Src/front_unit.c @@ -53,6 +53,7 @@ static uint32_t ENCODER2_AValDeb = 0; static bool enc2_func_mode = false; //false - fast-step, true - func mode (WPM, etc...) +#if (defined(BUTTONS_R7KBI)) // static PERIPH_FrontPanel_Button PERIPH_FrontPanel_Static_Buttons[] = { {.port = 1, .channel = 0, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used {.port = 1, .channel = 1, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used @@ -74,7 +75,7 @@ static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SC }, { {.port = 1, .channel = 5, .name = "AGC", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AGC, .holdHandler = FRONTPANEL_BUTTONHANDLER_AGC_SPEED}, //SB2 - {.port = 1, .channel = 6, .name = "TUNE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_TUNE, .holdHandler = FRONTPANEL_BUTTONHANDLER_TUNE}, //SB3 + {.port = 1, .channel = 6, .name = "ZOOM", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P}, //SB3 {.port = 1, .channel = 6, .name = "NOTCH", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_NOTCH, .holdHandler = FRONTPANEL_BUTTONHANDLER_NOTCH}, //SB4 {.port = 1, .channel = 6, .name = "FAST", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_FAST, .holdHandler = FRONTPANEL_BUTTONHANDLER_FAST}, //SB5 {.port = 1, .channel = 7, .name = "CLAR", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_CLAR, .holdHandler = FRONTPANEL_BUTTONHANDLER_CLAR}, //SB3 @@ -98,7 +99,8 @@ static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SC {.port = 1, .channel = 6, .name = "BW+", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BW_P}, //SB3 {.port = 1, .channel = 6, .name = "PWR-", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_N}, //SB4 {.port = 1, .channel = 6, .name = "PWR+", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_P}, //SB5 - {.port = 1, .channel = 7, .name = "ZOOM", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P}, //SB2 + {.port = 1, .channel = 7, .name = "TUNE", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_TUNE, .holdHandler = FRONTPANEL_BUTTONHANDLER_TUNE}, //SB2 + //{.port = 1, .channel = 7, .name = "ZOOM", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P}, //SB2 }, { {.port = 1, .channel = 5, .name = "MODE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6 @@ -108,6 +110,63 @@ static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SC {.port = 1, .channel = 7, .name = "POWER", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2 }, }; +#else +static PERIPH_FrontPanel_Button PERIPH_FrontPanel_Static_Buttons[] = { + {.port = 1, .channel = 0, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 1, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 2, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 3, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 4, .name = "", .tres_min = 0, .tres_max = 1023, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used + {.port = 1, .channel = 7, .name = "MODE", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6 + {.port = 1, .channel = 7, .name = "BAND", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB1 + {.port = 1, .channel = 6, .name = "MENU", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MENU, .holdHandler = FRONTPANEL_BUTTONHANDLER_MENU}, //SB1 +}; + +static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SCROLLBUTTONS_GROUPS_COUNT][5] = { + { + {.port = 1, .channel = 5, .name = "PRE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PRE, .holdHandler = FRONTPANEL_BUTTONHANDLER_PRE}, //SB2 + {.port = 1, .channel = 5, .name = "ATT", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ATT, .holdHandler = FRONTPANEL_BUTTONHANDLER_ATTHOLD}, //SB3 + {.port = 1, .channel = 5, .name = "BW", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW, .holdHandler = FRONTPANEL_BUTTONHANDLER_HPF}, //SB4 + {.port = 1, .channel = 6, .name = "A/B", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AsB, .holdHandler = FRONTPANEL_BUTTONHANDLER_ArB}, //SB5 + {.port = 1, .channel = 6, .name = "POWER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2 + }, + { + {.port = 1, .channel = 5, .name = "AGC", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AGC, .holdHandler = FRONTPANEL_BUTTONHANDLER_AGC_SPEED}, //SB2 + {.port = 1, .channel = 5, .name = "TUNE", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_TUNE, .holdHandler = FRONTPANEL_BUTTONHANDLER_TUNE}, //SB3 + {.port = 1, .channel = 5, .name = "NOTCH", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_NOTCH, .holdHandler = FRONTPANEL_BUTTONHANDLER_NOTCH}, //SB4 + {.port = 1, .channel = 6, .name = "FAST", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_FAST, .holdHandler = FRONTPANEL_BUTTONHANDLER_FAST}, //SB5 + {.port = 1, .channel = 6, .name = "CLAR", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_CLAR, .holdHandler = FRONTPANEL_BUTTONHANDLER_CLAR}, //SB3 + }, + { + {.port = 1, .channel = 5, .name = "VOLUME", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_VOLUME, .holdHandler = FRONTPANEL_BUTTONHANDLER_VOLUME}, //SB2 + {.port = 1, .channel = 5, .name = "BANDMAP", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP, .holdHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP}, //SB3 + {.port = 1, .channel = 5, .name = "MUTE", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MUTE, .holdHandler = FRONTPANEL_BUTTONHANDLER_MUTE}, //SB4 + {.port = 1, .channel = 6, .name = "LOCK", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_LOCK, .holdHandler = FRONTPANEL_BUTTONHANDLER_LOCK}, //SB5 + {.port = 1, .channel = 6, .name = "WPM", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_WPM, .holdHandler = FRONTPANEL_BUTTONHANDLER_WPM}, //SB4 + }, + { + {.port = 1, .channel = 5, .name = "BAND-", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB2 + {.port = 1, .channel = 5, .name = "BAND+", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_P}, //SB3 + {.port = 1, .channel = 5, .name = "MODE-", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_N}, //SB4 + {.port = 1, .channel = 6, .name = "MODE+", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB5 + {.port = 1, .channel = 6, .name = "KEYER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_KEYER, .holdHandler = FRONTPANEL_BUTTONHANDLER_KEYER}, //SB5 + }, + { + {.port = 1, .channel = 5, .name = "BW-", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_BW_N}, //SB2 + {.port = 1, .channel = 5, .name = "BW+", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BW_P}, //SB3 + {.port = 1, .channel = 5, .name = "PWR-", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_N}, //SB4 + {.port = 1, .channel = 6, .name = "PWR+", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PWR_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_PWR_P}, //SB5 + {.port = 1, .channel = 6, .name = "ZOOM", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_ZOOM_P}, //SB2 + }, + { + {.port = 1, .channel = 5, .name = "MODE", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6 + {.port = 1, .channel = 5, .name = "BAND", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB1 + {.port = 1, .channel = 5, .name = "PRE", .tres_min = 10, .tres_max = 300, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PRE, .holdHandler = FRONTPANEL_BUTTONHANDLER_PRE}, //SB2 + {.port = 1, .channel = 6, .name = "A/B", .tres_min = 500, .tres_max = 700, .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AsB, .holdHandler = FRONTPANEL_BUTTONHANDLER_ArB}, //SB5 + {.port = 1, .channel = 6, .name = "POWER", .tres_min = 300, .tres_max = 500, .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2 + }, +}; +#endif PERIPH_FrontPanel_Button* PERIPH_FrontPanel_BottomScroll_Buttons_Active = PERIPH_FrontPanel_BottomScroll_Buttons[0]; int8_t PERIPH_FrontPanel_BottomScroll_index = 0; @@ -178,8 +237,6 @@ void FRONTPANEL_ENCODER_checkRotate(void) void FRONTPANEL_ENCODER2_checkRotate(void) { - static int8_t enc2_slowler = 0; - #define enc2_slowler_val 2 uint8_t ENCODER2_DTVal = HAL_GPIO_ReadPin(ENC2_DT_GPIO_Port, ENC2_DT_Pin); uint8_t ENCODER2_CLKVal = HAL_GPIO_ReadPin(ENC2_CLK_GPIO_Port, ENC2_CLK_Pin); @@ -189,24 +246,12 @@ void FRONTPANEL_ENCODER2_checkRotate(void) if (!CALIBRATE.ENCODER_ON_FALLING || ENCODER2_CLKVal == 0) { if (ENCODER2_DTVal != ENCODER2_CLKVal) - { - // If pin A changed first - clockwise rotation - enc2_slowler--; - if(enc2_slowler <= -enc2_slowler_val) - { - FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? 1 : -1); - enc2_slowler = 0; - } + { // If pin A changed first - clockwise rotation + FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? 1 : -1); } else - { - // otherwise B changed its state first - counterclockwise rotation - enc2_slowler++; - if(enc2_slowler >= enc2_slowler_val) - { - FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? -1 : 1); - enc2_slowler = 0; - } + { // otherwise B changed its state first - counterclockwise rotation + FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? -1 : 1); } } ENCODER2_AValDeb = HAL_GetTick(); diff --git a/STM32/Core/Src/functions.c b/STM32/Core/Src/functions.c index 850221c..52d448a 100644 --- a/STM32/Core/Src/functions.c +++ b/STM32/Core/Src/functions.c @@ -354,6 +354,23 @@ float32_t getMaxTXAmplitudeOnFreq(uint32_t freq) return (float32_t)CALIBRATE.rf_out_power_40m / 100.0f * (float32_t)MAX_TX_AMPLITUDE; } +//########################################################################################################################### +//uint16_t getf_calibrate(uint16_t freq) +//{ +// +// switch (freq) +// { +// case CALIBRATE.freq_correctur_160: +// break; +// case CALIBRATE.freq_correctur_80: +// break; +// case CALIBRATE.freq_correctur_40: +// break; +// +// } + +//} +//########################################################################################################################### float32_t generateSin(float32_t amplitude, uint32_t index, uint32_t samplerate, uint32_t freq) { diff --git a/STM32/Core/Src/functions.h b/STM32/Core/Src/functions.h index aacd8bc..ea5b3b9 100644 --- a/STM32/Core/Src/functions.h +++ b/STM32/Core/Src/functions.h @@ -1,6 +1,8 @@ #ifndef Functions_h #define Functions_h +__asm(".global __use_no_heap\n\t"); + #include "stm32f4xx_hal.h" #include #include @@ -134,6 +136,7 @@ extern float32_t rate2dbP(float32_t i); extern float32_t volume2rate(float32_t i); extern void shiftTextLeft(char *string, uint_fast16_t shiftLength); extern float32_t getMaxTXAmplitudeOnFreq(uint32_t freq); +//extern uint16_t getf_calibrate(uint16_t freq); extern float32_t generateSin(float32_t amplitude, uint32_t index, uint32_t samplerate, uint32_t freq); extern int32_t convertToSPIBigEndian(int32_t in); extern uint8_t rev8(uint8_t data); diff --git a/STM32/Core/Src/lcd.c b/STM32/Core/Src/lcd.c index 50c7b39..6f84c20 100644 --- a/STM32/Core/Src/lcd.c +++ b/STM32/Core/Src/lcd.c @@ -30,6 +30,7 @@ static uint16_t LCD_last_showed_freq_mhz = 9999; static uint16_t LCD_last_showed_freq_khz = 9999; static uint16_t LCD_last_showed_freq_hz = 9999; +//extern TRX_freq_correctur; static float32_t LCD_last_s_meter = 1.0f; static uint32_t Time; static uint8_t Hours; diff --git a/STM32/Core/Src/main.c b/STM32/Core/Src/main.c index 3dd837b..3ce28eb 100644 --- a/STM32/Core/Src/main.c +++ b/STM32/Core/Src/main.c @@ -638,46 +638,6 @@ static void MX_TIM3_Init(void) * @param None * @retval None */ -//static void MX_TIM4_Init(void) -//{ - -// /* USER CODE BEGIN TIM4_Init 0 */ - -// /* USER CODE END TIM4_Init 0 */ - -// TIM_ClockConfigTypeDef sClockSourceConfig = {0}; -// TIM_MasterConfigTypeDef sMasterConfig = {0}; - -// /* USER CODE BEGIN TIM4_Init 1 */ - -// /* USER CODE END TIM4_Init 1 */ -// htim4.Instance = TIM4; -// htim4.Init.Prescaler = 4199; -// htim4.Init.CounterMode = TIM_COUNTERMODE_UP; -// htim4.Init.Period = 199; -// htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; -// htim4.Init.AutoReloadPreload = TIM_AUTORELOAD_PRELOAD_DISABLE; -// if (HAL_TIM_Base_Init(&htim4) != HAL_OK) -// { -// Error_Handler(); -// } -// sClockSourceConfig.ClockSource = TIM_CLOCKSOURCE_INTERNAL; -// if (HAL_TIM_ConfigClockSource(&htim4, &sClockSourceConfig) != HAL_OK) -// { -// Error_Handler(); -// } -// sMasterConfig.MasterOutputTrigger = TIM_TRGO_UPDATE; -// sMasterConfig.MasterSlaveMode = TIM_MASTERSLAVEMODE_DISABLE; -// if (HAL_TIMEx_MasterConfigSynchronization(&htim4, &sMasterConfig) != HAL_OK) -// { -// Error_Handler(); -// } -// /* USER CODE BEGIN TIM4_Init 2 */ - -// /* USER CODE END TIM4_Init 2 */ - -//} - static void MX_TIM4_Init(void) //LCD PWM { @@ -693,7 +653,7 @@ static void MX_TIM4_Init(void) //LCD PWM /* USER CODE END TIM3_Init 1 */ htim4.Instance = TIM4; - htim4.Init.Prescaler = 64-1; + htim4.Init.Prescaler = 32-1; htim4.Init.CounterMode = TIM_COUNTERMODE_UP; htim4.Init.Period = 500-1; htim4.Init.ClockDivision = TIM_CLOCKDIVISION_DIV1; diff --git a/STM32/Core/Src/rf_unit.c b/STM32/Core/Src/rf_unit.c index 4e4a8a0..616e3bc 100644 --- a/STM32/Core/Src/rf_unit.c +++ b/STM32/Core/Src/rf_unit.c @@ -76,8 +76,8 @@ void RF_UNIT_ProcessSensors(void) else backward = 0.001f; - TRX_VLT_forward = TRX_VLT_forward + (forward - TRX_VLT_forward) / 2; - TRX_VLT_backward = TRX_VLT_backward + (backward - TRX_VLT_backward) / 2; + TRX_VLT_forward = 0.99f * TRX_VLT_forward + 0.01f * forward; + TRX_VLT_backward = 0.99f * TRX_VLT_backward + 0.01f * backward; TRX_SWR = (TRX_VLT_forward + TRX_VLT_backward) / (TRX_VLT_forward - TRX_VLT_backward); if (TRX_VLT_backward > TRX_VLT_forward) diff --git a/STM32/Core/Src/screen_layout.h b/STM32/Core/Src/screen_layout.h index ab24f1d..af03151 100644 --- a/STM32/Core/Src/screen_layout.h +++ b/STM32/Core/Src/screen_layout.h @@ -11,7 +11,7 @@ #define LAY_TOPBUTTONS_Y1 1 #define LAY_TOPBUTTONS_Y2 50 #define LAY_TOPBUTTONS_WIDTH 62 -#define LAY_TOPBUTTONS_HEIGHT 40 +#define LAY_TOPBUTTONS_HEIGHT 20 #define LAY_TOPBUTTONS_TB_MARGIN 2 #define LAY_TOPBUTTONS_LR_MARGIN 2 #define LAY_TOPBUTTONS_PRE_X (uint16_t)(LAY_TOPBUTTONS_X1 + LAY_TOPBUTTONS_LR_MARGIN) diff --git a/STM32/Core/Src/settings.c b/STM32/Core/Src/settings.c index 1a63213..984aaa8 100644 --- a/STM32/Core/Src/settings.c +++ b/STM32/Core/Src/settings.c @@ -45,6 +45,7 @@ static void EEPROM_PowerUp(void); static void EEPROM_WaitWrite(void); static uint8_t calculateCSUM(void); static uint8_t calculateCSUM_EEPROM(void); +//static uint16_t freq_correctur = 0; const char *MODE_DESCR[TRX_MODE_COUNT] = { "LSB", @@ -188,12 +189,12 @@ void LoadSettings(bool clear) TRX.Locked = false; // Lock control TRX.CLAR = false; // Split frequency mode (receive one VFO, transmit another) TRX.TWO_SIGNAL_TUNE = false; // Two-signal generator in TUNE mode (1 + 2kHz) - TRX.IF_Gain = 60; // IF gain, dB (before all processing and AGC) + TRX.IF_Gain = 40; // IF gain, dB (before all processing and AGC) TRX.CW_KEYER = true; // Automatic key TRX.CW_KEYER_WPM = 30; // Automatic key speed TRX.Debug_Console = false; // Debug output to DEBUG / UART port TRX.FFT_Color = 1; // FFT display color - TRX.FFT_Grid = 1; // FFT grid style + TRX.FFT_Grid = 3; // FFT grid style TRX.ShiftEnabled = false; // activate the SHIFT mode TRX.SHIFT_INTERVAL = 5000; // Detune range with the SHIFT knob (5000 = -5000hz / + 5000hz) TRX.DNR_SNR_THRESHOLD = 50; // Digital noise reduction level @@ -201,7 +202,7 @@ void LoadSettings(bool clear) TRX.DNR_MINIMAL = 99; // DNR averaging when searching for minimum magnitude TRX.FRQ_STEP = 10; // frequency tuning step by the main encoder TRX.FRQ_FAST_STEP = 100; // frequency tuning step by the main encoder in FAST mode - TRX.AGC_GAIN_TARGET = -35; // Maximum (target) AGC gain + TRX.AGC_GAIN_TARGET = -25; // Maximum (target) AGC gain TRX.MIC_GAIN = 3; // Microphone gain TRX.RX_EQ_LOW = 0; // Receiver Equalizer (Low) TRX.RX_EQ_MID = 0; // Receiver EQ (mids) @@ -210,7 +211,7 @@ void LoadSettings(bool clear) TRX.MIC_EQ_MID = 0; // Mic Equalizer (Mids) TRX.MIC_EQ_HIG = 0; // Mic EQ (high) TRX.Beeper = true; //Keyboard beeper - TRX.FFT_Background = true; //FFT gradient background + TRX.FFT_Background = false; //FFT gradient background TRX.FFT_Compressor = true; //Compress FFT Peaks TRX.Encoder_Accelerate = true; //Accelerate Encoder on fast rate strcpy(TRX.CALLSIGN, "HamRad"); // Callsign @@ -265,7 +266,7 @@ void LoadCalibration(bool clear) CALIBRATE.flash_id = CALIB_VERSION; // code for checking the firmware in the eeprom, if it does not match, we use the default CALIBRATE.ENCODER_INVERT = false; // invert left-right rotation of the main encoder - CALIBRATE.ENCODER2_INVERT = true; // invert left-right rotation of the optional encoder + CALIBRATE.ENCODER2_INVERT = false; // invert left-right rotation of the optional encoder CALIBRATE.ENCODER_DEBOUNCE = 0; // time to eliminate contact bounce at the main encoder, ms CALIBRATE.ENCODER2_DEBOUNCE = 50; // time to eliminate contact bounce at the additional encoder, ms CALIBRATE.ENCODER_SLOW_RATE = 25; // slow down the encoder for high resolutions @@ -282,15 +283,18 @@ void LoadCalibration(bool clear) CALIBRATE.rf_out_power_17m = 22; //17m CALIBRATE.rf_out_power_15m = 22; //15m CALIBRATE.rf_out_power_12m = 22; //12m - CALIBRATE.rf_out_power_10m = 22; //10m + CALIBRATE.rf_out_power_10m = 22; //10m + CALIBRATE.freq_correctur = 0; +// CALIBRATE.freq_correctur_80 = 0; +// CALIBRATE.freq_correctur_40 = 0; CALIBRATE.rf_out_power_lf = 40; // <2mhz CALIBRATE.rf_out_power_hf_low = 45; // <5mhz CALIBRATE.rf_out_power_hf = 26; // <30mhz CALIBRATE.rf_out_power_hf_high = 80; // >30mhz - CALIBRATE.smeter_calibration = 0; // S-Meter calibration, set when calibrating the transceiver to S9 + CALIBRATE.smeter_calibration = -10; // S-Meter calibration, set when calibrating the transceiver to S9 CALIBRATE.swr_trans_rate = 11.0f; //SWR Transormator rate - CALIBRATE.volt_cal_rate = 10.0f; //VOLTAGE + CALIBRATE.volt_cal_rate = 11.0f; //VOLTAGE CALIBRATE.ENDBit = 100; sendToDebug_strln("[OK] Loaded default calibrate settings"); diff --git a/STM32/Core/Src/settings.h b/STM32/Core/Src/settings.h index fe24fd2..db3f35a 100644 --- a/STM32/Core/Src/settings.h +++ b/STM32/Core/Src/settings.h @@ -7,24 +7,26 @@ #include "functions.h" #include "bands.h" -#define SETT_VERSION 100 // Settings config version +#define SETT_VERSION 101 // Settings config version #define CALIB_VERSION 100 // Calibration config version -#define ADC_CLOCK 64320000 // ADC generator frequency -#define DAC_CLOCK 160800000 // DAC generator frequency +//#define ADC_CLOCK 64320000 // ADC generator frequency +//#define DAC_CLOCK 160800000 // DAC generator frequency +#define ADC_CLOCK 61440000 // ADC generator frequency +#define DAC_CLOCK 153600000 // DAC generator frequency #define MAX_RX_FREQ_HZ 750000000 // Maximum receive frequency (from the ADC datasheet) #define MAX_TX_FREQ_HZ (DAC_CLOCK / 2) // Maximum transmission frequency #define TRX_SAMPLERATE 48000 // audio stream sampling rate during processing #define MAX_TX_AMPLITUDE 1.0f // Maximum amplitude when transmitting to FPGA -#define AGC_MAX_GAIN 30.0f // Maximum gain in AGC, dB +#define AGC_MAX_GAIN 10.0f // Maximum gain in AGC, dB #define AGC_CLIPPING 6.0f // Limit over target in AGC, dB #define TUNE_POWER 100 // % of the power selected in the settings when starting TUNE (100 - full) #define TX_AGC_MAXGAIN 5.0f // Maximum microphone gain during compression #define TX_AGC_NOISEGATE 0.00001f // Minimum signal level for amplification (below - noise, cut off) #define AUTOGAIN_TARGET_AMPLITUDE 20000.0f // maximum amplitude, upon reaching which the autocorrector of the input circuits terminates, and in case of overflow it reduces the gain -#define AUTOGAIN_MAX_AMPLITUDE 30000.0f // maximum amplitude, upon reaching which the autocorrector of the input circuits terminates, and in case of overflow it reduces the gain -#define AUTOGAIN_CORRECTOR_WAITSTEP 5 // waiting for the averaging of the results when the auto-corrector of the input circuits is running +#define AUTOGAIN_MAX_AMPLITUDE 30000.0f // maximum amplitude, upon reaching which the autocorrector of the input circuits terminates, and in case of overflow it reduces the gain +#define AUTOGAIN_CORRECTOR_WAITSTEP 5 // waiting for the averaging of the results when the auto-corrector of the input circuits is running #define KEY_HOLD_TIME 500 // time of long pressing of the keyboard button for triggering, ms -#define MAX_RF_POWER 7.0f // Maximum power (for meter scale) +#define MAX_RF_POWER 50.0f // Maximum power (for meter scale) #define SHOW_LOGO true // Show logo on boot (from images.h) #define POWERDOWN_TIMEOUT 1000 // time of pressing the shutdown button, for operation, ms #define USB_RESTART_TIMEOUT 5000 // time after which USB restart occurs if there are no packets @@ -32,6 +34,8 @@ #define ENCODER_MIN_RATE_ACCELERATION 1.2f //encoder enable rounding if lower than value #define TRX_MAX_SWR 5 //maximum SWR to enable protect (NOT IN TUNE MODE!) +#define BUTTONS_R7KBI true //Author board buttons + // select LCD, comment on others //#define LCD_ILI9481 true //#define LCD_HX8357B true @@ -46,6 +50,7 @@ #define SPI_EEPROM_PRESCALER SPI_BAUDRATEPRESCALER_8 #define CODEC_BITS_FULL_SCALE 65536 // maximum signal amplitude in the bus // powf (2, FPGA_BUS_BITS) +#define ADC_FULL_SCALE 4095 #define FLOAT_FULL_SCALE_POW 4 #define USB_DEBUG_ENABLED true // allow using USB as a console #define SWD_DEBUG_ENABLED false // enable SWD as a console @@ -53,6 +58,8 @@ #define ADC_INPUT_IMPEDANCE 200.0f //50ohm -> 1:4 trans #define ADC_RANGE 1.0f #define ADC_DRIVER_GAIN_DB 20.0f //on 14mhz +#define AUTOGAINER_TAGET (ADC_FULL_SCALE / 3) +#define AUTOGAINER_HYSTERESIS (ADC_FULL_SCALE / 10) #define MAX_CALLSIGN_LENGTH 16 @@ -198,6 +205,7 @@ extern struct TRX_CALIBRATE uint8_t TXCICFIR_GAINER_val; uint8_t DAC_GAINER_val; uint8_t rf_out_power_lf; + uint8_t rf_out_power_hf_low; uint8_t rf_out_power_hf; uint8_t rf_out_power_hf_high; @@ -205,6 +213,9 @@ extern struct TRX_CALIBRATE int16_t smeter_calibration; float32_t swr_trans_rate; float32_t volt_cal_rate; + int16_t freq_correctur; +// int16_t freq_correctur_80; +// int16_t freq_correctur_40; uint8_t rf_out_power_160m; uint8_t rf_out_power_80m; uint8_t rf_out_power_40m; diff --git a/STM32/Core/Src/system_menu.c b/STM32/Core/Src/system_menu.c index 07853fe..38e61c5 100644 --- a/STM32/Core/Src/system_menu.c +++ b/STM32/Core/Src/system_menu.c @@ -114,6 +114,7 @@ static void SYSMENU_HANDL_CALIB_RF_GAIN_17M(int8_t direction); static void SYSMENU_HANDL_CALIB_RF_GAIN_15M(int8_t direction); static void SYSMENU_HANDL_CALIB_RF_GAIN_12M(int8_t direction); static void SYSMENU_HANDL_CALIB_RF_GAIN_10M(int8_t direction); +static void SYSMENU_HANDL_CALIB_FREQUENCY(int8_t direction); static void SYSMENU_HANDL_TRXMENU(int8_t direction); static void SYSMENU_HANDL_AUDIOMENU(int8_t direction); @@ -246,6 +247,7 @@ static const struct sysmenu_item_handler sysmenu_calibration_handlers[] = {"S METER", SYSMENU_INT16, (uint32_t *)&CALIBRATE.smeter_calibration, SYSMENU_HANDL_CALIB_S_METER}, {"SWR TRANS RATE", SYSMENU_FLOAT32, (uint32_t *)&CALIBRATE.swr_trans_rate, SYSMENU_HANDL_CALIB_SWR_TRANS_RATE}, {"VOLT CALIBR", SYSMENU_FLOAT32, (uint32_t *)&CALIBRATE.volt_cal_rate, SYSMENU_HANDL_CALIB_VOLT}, + {"F-correctur", SYSMENU_INT16, (uint32_t *)&CALIBRATE.freq_correctur, SYSMENU_HANDL_CALIB_FREQUENCY}, {"RF GAIN 160m", SYSMENU_UINT8, (uint32_t *)&CALIBRATE.rf_out_power_160m, SYSMENU_HANDL_CALIB_RF_GAIN_160M}, {"RF GAIN 80m", SYSMENU_UINT8, (uint32_t *)&CALIBRATE.rf_out_power_80m, SYSMENU_HANDL_CALIB_RF_GAIN_80M}, {"RF GAIN 40m", SYSMENU_UINT8, (uint32_t *)&CALIBRATE.rf_out_power_40m, SYSMENU_HANDL_CALIB_RF_GAIN_40M}, @@ -1917,7 +1919,19 @@ static void SYSMENU_HANDL_CALIB_VOLT(int8_t direction) if (CALIBRATE.volt_cal_rate > 50.0f) CALIBRATE.volt_cal_rate = 50.0f; } +//F-CALIBR +//########################################################################################################### +static void SYSMENU_HANDL_CALIB_FREQUENCY(int8_t direction) +{ + CALIBRATE.freq_correctur += direction; + if (CALIBRATE.freq_correctur < -500) + CALIBRATE.freq_correctur = -500; + if (CALIBRATE.freq_correctur > 500) + CALIBRATE.freq_correctur = 500; + TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO()); +} +//########################################################################################################## //SERVICES void SYSMENU_HANDL_SERVICESMENU(int8_t direction) { diff --git a/STM32/Core/Src/trx_manager.c b/STM32/Core/Src/trx_manager.c index 3e36a8f..1620f8b 100644 --- a/STM32/Core/Src/trx_manager.c +++ b/STM32/Core/Src/trx_manager.c @@ -209,8 +209,8 @@ void TRX_setFrequency(uint32_t _freq, VFO *vfo) //get fpga freq phrase 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 + TRX_SHIFT); + TRX_freq_phrase = getRXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur); + TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX_SHIFT + CALIBRATE.freq_correctur); if (!TRX_on_TX()) { switch (current_vfo->Mode) @@ -281,138 +281,47 @@ void TRX_setMode(uint_fast8_t _mode, VFO *vfo) void TRX_DoAutoGain(void) { - #define SKIP_CYCLES_DOWNSTAGE 10 //skip cycles on stage downgrade - static uint8_t skip_cycles = 0; - + uint8_t skip_cycles = 0; + if (skip_cycles > 0) + { + skip_cycles--; + return; + } + //Process AutoGain feature if (TRX.AutoGain && !TRX_on_TX()) { - int32_t max_amplitude = abs(TRX_ADC_MAXAMPLITUDE); - if(abs(TRX_ADC_MINAMPLITUDE) > max_amplitude) - max_amplitude = abs(TRX_ADC_MINAMPLITUDE); - - switch (TRX_AutoGain_Stage) + if (!TRX.ATT) { - case 0: // stage 1 - ATT - TRX.ADC_Driver = false; TRX.ATT = true; - FPGA_NeedSendParams = true; LCD_UpdateQuery.TopButtons = true; - autogain_wait_reaction = 0; - if(skip_cycles == 0) - { - sendToDebug_strln("AUTOGAIN BPF + ATT"); - TRX_AutoGain_Stage++; - } - else - skip_cycles--; - break; - case 1: // changed the state, process the results - if ((max_amplitude * db2rateV(TRX.ATT_DB)) <= AUTOGAIN_TARGET_AMPLITUDE) // if we can turn off ATT - go to the next stage (+ 12dB) - autogain_wait_reaction++; - else - autogain_wait_reaction = 0; - if (autogain_wait_reaction >= AUTOGAIN_CORRECTOR_WAITSTEP) - { - TRX_AutoGain_Stage++; - autogain_wait_reaction = 0; - } - break; - case 2: // stage 2 - NONE - TRX.ATT = false; - TRX.ADC_Driver = false; - FPGA_NeedSendParams = true; - LCD_UpdateQuery.TopButtons = true; - autogain_wait_reaction = 0; - if(skip_cycles == 0) - { - sendToDebug_strln("AUTOGAIN BPF"); - TRX_AutoGain_Stage++; - } - else - skip_cycles--; - break; - case 3: // changed the state, process the results - if (max_amplitude > AUTOGAIN_MAX_AMPLITUDE || TRX_ADC_OTR) - { - TRX_AutoGain_Stage -= 3; // too much gain, go back one step - skip_cycles = SKIP_CYCLES_DOWNSTAGE; - } - if ((max_amplitude * db2rateV(ADC_DRIVER_GAIN_DB) * db2rateV(-TRX.ATT_DB)) <= AUTOGAIN_TARGET_AMPLITUDE) // if we can turn off ATT - go to the next stage (+ 12dB) - autogain_wait_reaction++; - else - { - autogain_wait_reaction = 0; - } - if (autogain_wait_reaction >= AUTOGAIN_CORRECTOR_WAITSTEP) - { - TRX_AutoGain_Stage++; - autogain_wait_reaction = 0; - } - break; - case 5: // stage 4 - BPF + DRIVER + ATT - TRX.ATT = false; - TRX.ADC_Driver = true; - FPGA_NeedSendParams = true; - LCD_UpdateQuery.TopButtons = true; - autogain_wait_reaction = 0; - if(skip_cycles == 0) - { - sendToDebug_strln("AUTOGAIN BPF + DRIVER + ATT"); - TRX_AutoGain_Stage++; - } - else - skip_cycles--; - break; - case 6: // changed the state, process the results - if (max_amplitude > AUTOGAIN_MAX_AMPLITUDE || TRX_ADC_OTR) - { - TRX_AutoGain_Stage -= 3; // too much gain, go back one step - skip_cycles = SKIP_CYCLES_DOWNSTAGE; - } - if ((max_amplitude * db2rateV(TRX.ATT_DB)) <= AUTOGAIN_TARGET_AMPLITUDE) // if we can turn off ATT - go to the next stage (+ 12dB) - autogain_wait_reaction++; - else - autogain_wait_reaction = 0; - if (autogain_wait_reaction >= AUTOGAIN_CORRECTOR_WAITSTEP) - { - TRX_AutoGain_Stage++; - autogain_wait_reaction = 0; - } - break; - case 7: // stage 5 - BPF + DRIVER - TRX.ATT = false; - TRX.ADC_Driver = true; - FPGA_NeedSendParams = true; - LCD_UpdateQuery.TopButtons = true; - autogain_wait_reaction = 0; - if(skip_cycles == 0) - { - sendToDebug_strln("AUTOGAIN BPF + DRIVER"); - TRX_AutoGain_Stage++; - } - else - skip_cycles--; - break; - case 9: // changed the state, process the results - if (max_amplitude > AUTOGAIN_MAX_AMPLITUDE || TRX_ADC_OTR) - { - TRX_AutoGain_Stage -= 3; // too much gain, go back one step - skip_cycles = SKIP_CYCLES_DOWNSTAGE; - } - break; - - default: - TRX_AutoGain_Stage = 0; - break; } - - int8_t band = getBandFromFreq(CurrentVFO()->Freq, true); - if (band > 0) + + 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.BANDS_SAVED_SETTINGS[band].ATT = TRX.ATT; + 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; - TRX.BANDS_SAVED_SETTINGS[band].AutoGain_Stage = TRX_AutoGain_Stage; } } } diff --git a/STM32/Core/Src/usbd_ua3reo.c b/STM32/Core/Src/usbd_ua3reo.c index 84305b1..ef4b84a 100644 --- a/STM32/Core/Src/usbd_ua3reo.c +++ b/STM32/Core/Src/usbd_ua3reo.c @@ -544,11 +544,14 @@ static uint8_t USBD_UA3REO_Init(USBD_HandleTypeDef *pdev) pdev->ep_in[DEBUG_CMD_EP & 0xFU].is_used = 1U; pdev->ep_in[CAT_CMD_EP & 0xFU].is_used = 1U; - pdev->pClassDataDEBUG = USBD_malloc(sizeof(USBD_DEBUG_HandleTypeDef)); + static USBD_DEBUG_HandleTypeDef debug_class; + pdev->pClassDataDEBUG = &debug_class; memset(pdev->pClassDataDEBUG,0,sizeof(USBD_DEBUG_HandleTypeDef)); - pdev->pClassDataCAT = USBD_malloc(sizeof(USBD_CAT_HandleTypeDef)); + static USBD_CAT_HandleTypeDef cat_class; + pdev->pClassDataCAT = &cat_class; memset(pdev->pClassDataCAT,0,sizeof(USBD_CAT_HandleTypeDef)); - pdev->pClassDataAUDIO = USBD_malloc(sizeof(USBD_AUDIO_HandleTypeDef)); + static USBD_AUDIO_HandleTypeDef audio_class; + pdev->pClassDataAUDIO = &audio_class; memset(pdev->pClassDataAUDIO,0,sizeof(USBD_AUDIO_HandleTypeDef)); if (pdev->pClassDataDEBUG == NULL) @@ -644,20 +647,20 @@ static uint8_t USBD_UA3REO_DeInit(USBD_HandleTypeDef *pdev) if (pdev->pClassDataDEBUG != NULL) { ((USBD_DEBUG_ItfTypeDef *)pdev->pUserDataDEBUG)->DeInit(); - USBD_free(pdev->pClassDataDEBUG); - pdev->pClassDataDEBUG = NULL; + //USBD_free(pdev->pClassDataDEBUG); + //pdev->pClassDataDEBUG = NULL; } if (pdev->pClassDataCAT != NULL) { ((USBD_CAT_ItfTypeDef *)pdev->pUserDataCAT)->DeInit(); - USBD_free(pdev->pClassDataCAT); - pdev->pClassDataCAT = NULL; + //USBD_free(pdev->pClassDataCAT); + //pdev->pClassDataCAT = NULL; } if (pdev->pClassDataAUDIO != NULL) { ((USBD_AUDIO_ItfTypeDef *)pdev->pUserDataAUDIO)->DeInit(); - USBD_free(pdev->pClassDataAUDIO); - pdev->pClassDataAUDIO = NULL; + //USBD_free(pdev->pClassDataAUDIO); + //pdev->pClassDataAUDIO = NULL; } return ret; } diff --git a/STM32/Core/USBDevice/usbd_desc.c b/STM32/Core/USBDevice/usbd_desc.c index 9b4476e..76254a4 100644 --- a/STM32/Core/USBDevice/usbd_desc.c +++ b/STM32/Core/USBDevice/usbd_desc.c @@ -66,7 +66,7 @@ #define USBD_VID 1155 #define USBD_LANGID_STRING 1033 #define USBD_MANUFACTURER_STRING "UA3REO" -#define USBD_PID_FS 0xf002 +#define USBD_PID_FS 0xf001 #define USBD_PRODUCT_STRING_FS "WOLF-Lite Transceiver" #define USBD_CONFIGURATION_STRING_FS "WOLF-Lite Transceiver Config" #define USBD_INTERFACE1_STRING_FS "WOLF-Lite Transceiver Debug/Key Port" diff --git a/STM32/DEBUG.bat b/STM32/DEBUG.bat index a76ded5..c162e22 100644 --- a/STM32/DEBUG.bat +++ b/STM32/DEBUG.bat @@ -1,3 +1,3 @@ :start -"c:\Program Files\PuTTY\plink.exe" -serial COM6 -sercfg 115200,8,1,n,D +"c:\Program Files\PuTTY\plink.exe" -serial COM5 -sercfg 115200,8,1,n,D GOTO start diff --git a/STM32/MDK-ARM/RTE/_WOLF-Lite/RTE_Components.h b/STM32/MDK-ARM/RTE/_WOLF-Lite/RTE_Components.h index 4769186..1ca03f5 100644 --- a/STM32/MDK-ARM/RTE/_WOLF-Lite/RTE_Components.h +++ b/STM32/MDK-ARM/RTE/_WOLF-Lite/RTE_Components.h @@ -1,21 +1,21 @@ - -/* - * Auto generated Run-Time-Environment Configuration File - * *** Do not modify ! *** - * - * Project: 'WOLF-Lite' - * Target: 'WOLF-Lite' - */ - -#ifndef RTE_COMPONENTS_H -#define RTE_COMPONENTS_H - - -/* - * Define the Device Header File: - */ -#define CMSIS_device_header "stm32f4xx.h" - - - -#endif /* RTE_COMPONENTS_H */ + +/* + * Auto generated Run-Time-Environment Configuration File + * *** Do not modify ! *** + * + * Project: 'WOLF-Lite' + * Target: 'WOLF-Lite' + */ + +#ifndef RTE_COMPONENTS_H +#define RTE_COMPONENTS_H + + +/* + * Define the Device Header File: + */ +#define CMSIS_device_header "stm32f4xx.h" + + + +#endif /* RTE_COMPONENTS_H */ diff --git a/STM32/MDK-ARM/WOLF-Lite.uvprojx b/STM32/MDK-ARM/WOLF-Lite.uvprojx index f37f1fd..cc0265d 100644 --- a/STM32/MDK-ARM/WOLF-Lite.uvprojx +++ b/STM32/MDK-ARM/WOLF-Lite.uvprojx @@ -10,7 +10,7 @@ WOLF-Lite 0x4 ARM-ADS - 6150000::V6.15::ARMCLANG + 6160000::V6.16::ARMCLANG 1 diff --git a/STM32/MDK-ARM/startup_stm32f407xx.s b/STM32/MDK-ARM/startup_stm32f407xx.s index 637113b..b85a8b5 100644 --- a/STM32/MDK-ARM/startup_stm32f407xx.s +++ b/STM32/MDK-ARM/startup_stm32f407xx.s @@ -41,7 +41,7 @@ __initial_sp ; Heap Size (in Bytes) <0x0-0xFFFFFFFF:8> ; -Heap_Size EQU 0x1F00 +Heap_Size EQU 0x0000 AREA HEAP, NOINIT, READWRITE, ALIGN=3 __heap_base diff --git a/Stuff/CIC_Filters/61.440/rx_fir_filter.coe b/Stuff/CIC_Filters/61.440/rx_fir_filter.coe new file mode 100644 index 0000000..57219cc --- /dev/null +++ b/Stuff/CIC_Filters/61.440/rx_fir_filter.coe @@ -0,0 +1 @@ +6.160389e+02,-1.254326e+03,2.073709e+03,-2.985762e+03,3.644892e+03,-3.211168e+03,3.367669e+00,8.934959e+03,-2.840443e+04,6.565076e+04,-1.311246e+05,2.391202e+05,-4.086516e+05,6.639102e+05,-1.035224e+06,1.559083e+06,-2.279355e+06,3.246689e+06,-4.520654e+06,6.168546e+06,-8.270048e+06,1.091595e+07,-1.421878e+07,1.831292e+07,-2.337827e+07,2.964384e+07,-3.743402e+07,4.715361e+07,-5.927014e+07,7.373269e+07,-8.732875e+07,7.814946e+07,7.814946e+07,-8.732875e+07,7.373269e+07,-5.927014e+07,4.715361e+07,-3.743402e+07,2.964384e+07,-2.337827e+07,1.831292e+07,-1.421878e+07,1.091595e+07,-8.270048e+06,6.168546e+06,-4.520654e+06,3.246689e+06,-2.279355e+06,1.559083e+06,-1.035224e+06,6.639102e+05,-4.086516e+05,2.391202e+05,-1.311246e+05,6.565076e+04,-2.840443e+04,8.934959e+03,3.367669e+00,-3.211168e+03,3.644892e+03,-2.985762e+03,2.073709e+03,-1.254326e+03,6.160389e+02 diff --git a/Stuff/CIC_Filters/61.440/tx_fir_filter.coe b/Stuff/CIC_Filters/61.440/tx_fir_filter.coe new file mode 100644 index 0000000..c744a3a --- /dev/null +++ b/Stuff/CIC_Filters/61.440/tx_fir_filter.coe @@ -0,0 +1 @@ +6.161497e+02,-1.254535e+03,2.074031e+03,-2.986189e+03,3.645372e+03,-3.211556e+03,3.366267e+00,8.935861e+03,-2.840701e+04,6.565611e+04,-1.311341e+05,2.391355e+05,-4.086745e+05,6.639421e+05,-1.035267e+06,1.559136e+06,-2.279417e+06,3.246759e+06,-4.520725e+06,6.168611e+06,-8.270094e+06,1.091596e+07,-1.421874e+07,1.831280e+07,-2.337804e+07,2.964346e+07,-3.743345e+07,4.715280e+07,-5.926902e+07,7.373120e+07,-8.732690e+07,7.814774e+07,7.814774e+07,-8.732690e+07,7.373120e+07,-5.926902e+07,4.715280e+07,-3.743345e+07,2.964346e+07,-2.337804e+07,1.831280e+07,-1.421874e+07,1.091596e+07,-8.270094e+06,6.168611e+06,-4.520725e+06,3.246759e+06,-2.279417e+06,1.559136e+06,-1.035267e+06,6.639421e+05,-4.086745e+05,2.391355e+05,-1.311341e+05,6.565611e+04,-2.840701e+04,8.935861e+03,3.366267e+00,-3.211556e+03,3.645372e+03,-2.986189e+03,2.074031e+03,-1.254535e+03,6.161497e+02