pull/1/head
Антон 2021-02-01 13:23:14 +03:00
rodzic 98d9201c65
commit bb77ca4956
63 zmienionych plików z 2 dodań i 30035 usunięć

2
.gitattributes vendored 100644
Wyświetl plik

@ -0,0 +1,2 @@
# Auto detect text files and perform LF normalization
* text=auto

Wyświetl plik

@ -1,168 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file : main.h
* @brief : Header for main.c file.
* This file contains the common defines of the application.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __MAIN_H
#define __MAIN_H
#ifdef __cplusplus
extern "C" {
#endif
/* Includes ------------------------------------------------------------------*/
#include "stm32f4xx_hal.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
extern SRAM_HandleTypeDef hsram1;
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
extern ADC_HandleTypeDef hadc1;
extern ADC_HandleTypeDef hadc2;
extern I2S_HandleTypeDef hi2s3;
extern SPI_HandleTypeDef hspi2;
extern RTC_HandleTypeDef hrtc;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream7;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream6;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream5;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream4;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream3;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream2;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream1;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void Error_Handler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
/* Private defines -----------------------------------------------------------*/
#define ENC_CLK_Pin GPIO_PIN_3
#define ENC_CLK_GPIO_Port GPIOE
#define ENC_CLK_EXTI_IRQn EXTI3_IRQn
#define ENC2_SW_Pin GPIO_PIN_4
#define ENC2_SW_GPIO_Port GPIOE
#define ENC_DT_Pin GPIO_PIN_5
#define ENC_DT_GPIO_Port GPIOE
#define ENC2_DT_Pin GPIO_PIN_6
#define ENC2_DT_GPIO_Port GPIOE
#define ENC2_CLK_Pin GPIO_PIN_13
#define ENC2_CLK_GPIO_Port GPIOC
#define SWR_FORW_Pin GPIO_PIN_0
#define SWR_FORW_GPIO_Port GPIOC
#define SWR_BACKW_Pin GPIO_PIN_1
#define SWR_BACKW_GPIO_Port GPIOC
#define FPGA_CLK_Pin GPIO_PIN_2
#define FPGA_CLK_GPIO_Port GPIOC
#define FPGA_SYNC_Pin GPIO_PIN_3
#define FPGA_SYNC_GPIO_Port GPIOC
#define FPGA_BUS_D0_Pin GPIO_PIN_0
#define FPGA_BUS_D0_GPIO_Port GPIOA
#define FPGA_BUS_D1_Pin GPIO_PIN_1
#define FPGA_BUS_D1_GPIO_Port GPIOA
#define FPGA_BUS_D2_Pin GPIO_PIN_2
#define FPGA_BUS_D2_GPIO_Port GPIOA
#define FPGA_BUS_D3_Pin GPIO_PIN_3
#define FPGA_BUS_D3_GPIO_Port GPIOA
#define FPGA_BUS_D4_Pin GPIO_PIN_4
#define FPGA_BUS_D4_GPIO_Port GPIOA
#define FPGA_BUS_D5_Pin GPIO_PIN_5
#define FPGA_BUS_D5_GPIO_Port GPIOA
#define FPGA_BUS_D6_Pin GPIO_PIN_6
#define FPGA_BUS_D6_GPIO_Port GPIOA
#define FPGA_BUS_D7_Pin GPIO_PIN_7
#define FPGA_BUS_D7_GPIO_Port GPIOA
#define Power_IN_Pin GPIO_PIN_4
#define Power_IN_GPIO_Port GPIOC
#define ALC_IN_Pin GPIO_PIN_5
#define ALC_IN_GPIO_Port GPIOC
#define PTT_SW1_Pin GPIO_PIN_0
#define PTT_SW1_GPIO_Port GPIOB
#define PTT_SW2_Pin GPIO_PIN_1
#define PTT_SW2_GPIO_Port GPIOB
#define PTT_IN_Pin GPIO_PIN_2
#define PTT_IN_GPIO_Port GPIOB
#define PTT_IN_EXTI_IRQn EXTI2_IRQn
#define AUDIO_48K_CLOCK_Pin GPIO_PIN_10
#define AUDIO_48K_CLOCK_GPIO_Port GPIOB
#define AUDIO_48K_CLOCK_EXTI_IRQn EXTI15_10_IRQn
#define W25Q16_CS_Pin GPIO_PIN_12
#define W25Q16_CS_GPIO_Port GPIOB
#define PERI_SCK_Pin GPIO_PIN_13
#define PERI_SCK_GPIO_Port GPIOB
#define PERI_MISO_Pin GPIO_PIN_14
#define PERI_MISO_GPIO_Port GPIOB
#define PERI_MOSI_Pin GPIO_PIN_15
#define PERI_MOSI_GPIO_Port GPIOB
#define MUTE_Pin GPIO_PIN_7
#define MUTE_GPIO_Port GPIOC
#define AD1_CS_Pin GPIO_PIN_8
#define AD1_CS_GPIO_Port GPIOC
#define WM8731_WS_LRC_Pin GPIO_PIN_15
#define WM8731_WS_LRC_GPIO_Port GPIOA
#define WM8731_BCLK_Pin GPIO_PIN_10
#define WM8731_BCLK_GPIO_Port GPIOC
#define WM8731_ADC_SD_Pin GPIO_PIN_11
#define WM8731_ADC_SD_GPIO_Port GPIOC
#define WM8731_DAC_SD_Pin GPIO_PIN_12
#define WM8731_DAC_SD_GPIO_Port GPIOC
#define WM8731_SCK_Pin GPIO_PIN_3
#define WM8731_SCK_GPIO_Port GPIOD
#define WM8731_SDA_Pin GPIO_PIN_6
#define WM8731_SDA_GPIO_Port GPIOD
#define CPU_PW_HOLD_Pin GPIO_PIN_6
#define CPU_PW_HOLD_GPIO_Port GPIOB
#define CPU_PW_Pin GPIO_PIN_7
#define CPU_PW_GPIO_Port GPIOB
#define CPU_PW_EXTI_IRQn EXTI9_5_IRQn
#define KEY_IN_DASH_Pin GPIO_PIN_0
#define KEY_IN_DASH_GPIO_Port GPIOE
#define KEY_IN_DASH_EXTI_IRQn EXTI0_IRQn
#define KEY_IN_DOT_Pin GPIO_PIN_1
#define KEY_IN_DOT_GPIO_Port GPIOE
#define KEY_IN_DOT_EXTI_IRQn EXTI1_IRQn
/* USER CODE BEGIN Private defines */
/* USER CODE END Private defines */
#ifdef __cplusplus
}
#endif
#endif /* __MAIN_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -1,486 +0,0 @@
/**
******************************************************************************
* @file stm32f4xx_hal_conf_template.h
* @author MCD Application Team
* @brief HAL configuration template file.
* This file should be copied to the application folder and renamed
* to stm32f4xx_hal_conf.h.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_HAL_CONF_H
#define __STM32F4xx_HAL_CONF_H
#ifdef __cplusplus
extern "C" {
#endif
/* Exported types ------------------------------------------------------------*/
/* Exported constants --------------------------------------------------------*/
/* ########################## Module Selection ############################## */
/**
* @brief This is the list of modules to be used in the HAL driver
*/
#define HAL_MODULE_ENABLED
#define HAL_ADC_MODULE_ENABLED
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_CAN_MODULE_ENABLED */
/* #define HAL_CRC_MODULE_ENABLED */
/* #define HAL_CAN_LEGACY_MODULE_ENABLED */
/* #define HAL_CRYP_MODULE_ENABLED */
/* #define HAL_DAC_MODULE_ENABLED */
/* #define HAL_DCMI_MODULE_ENABLED */
/* #define HAL_DMA2D_MODULE_ENABLED */
/* #define HAL_ETH_MODULE_ENABLED */
/* #define HAL_NAND_MODULE_ENABLED */
/* #define HAL_NOR_MODULE_ENABLED */
/* #define HAL_PCCARD_MODULE_ENABLED */
#define HAL_SRAM_MODULE_ENABLED
/* #define HAL_SDRAM_MODULE_ENABLED */
/* #define HAL_HASH_MODULE_ENABLED */
/* #define HAL_I2C_MODULE_ENABLED */
#define HAL_I2S_MODULE_ENABLED
/* #define HAL_IWDG_MODULE_ENABLED */
/* #define HAL_LTDC_MODULE_ENABLED */
/* #define HAL_RNG_MODULE_ENABLED */
#define HAL_RTC_MODULE_ENABLED
/* #define HAL_SAI_MODULE_ENABLED */
/* #define HAL_SD_MODULE_ENABLED */
/* #define HAL_MMC_MODULE_ENABLED */
#define HAL_SPI_MODULE_ENABLED
#define HAL_TIM_MODULE_ENABLED
/* #define HAL_UART_MODULE_ENABLED */
/* #define HAL_USART_MODULE_ENABLED */
/* #define HAL_IRDA_MODULE_ENABLED */
/* #define HAL_SMARTCARD_MODULE_ENABLED */
/* #define HAL_SMBUS_MODULE_ENABLED */
/* #define HAL_WWDG_MODULE_ENABLED */
#define HAL_PCD_MODULE_ENABLED
/* #define HAL_HCD_MODULE_ENABLED */
/* #define HAL_DSI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_QSPI_MODULE_ENABLED */
/* #define HAL_CEC_MODULE_ENABLED */
/* #define HAL_FMPI2C_MODULE_ENABLED */
/* #define HAL_SPDIFRX_MODULE_ENABLED */
/* #define HAL_DFSDM_MODULE_ENABLED */
/* #define HAL_LPTIM_MODULE_ENABLED */
#define HAL_GPIO_MODULE_ENABLED
#define HAL_EXTI_MODULE_ENABLED
#define HAL_DMA_MODULE_ENABLED
#define HAL_RCC_MODULE_ENABLED
#define HAL_FLASH_MODULE_ENABLED
#define HAL_PWR_MODULE_ENABLED
#define HAL_CORTEX_MODULE_ENABLED
/* ########################## HSE/HSI Values adaptation ##################### */
/**
* @brief Adjust the value of External High Speed oscillator (HSE) used in your application.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSE is used as system clock source, directly or through the PLL).
*/
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)8000000U) /*!< Value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSE_STARTUP_TIMEOUT)
#define HSE_STARTUP_TIMEOUT ((uint32_t)100U) /*!< Time out for HSE start up, in ms */
#endif /* HSE_STARTUP_TIMEOUT */
/**
* @brief Internal High Speed oscillator (HSI) value.
* This value is used by the RCC HAL module to compute the system frequency
* (when HSI is used as system clock source, directly or through the PLL).
*/
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000U) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @brief Internal Low Speed oscillator (LSI) value.
*/
#if !defined (LSI_VALUE)
#define LSI_VALUE ((uint32_t)32000U) /*!< LSI Typical Value in Hz*/
#endif /* LSI_VALUE */ /*!< Value of the Internal Low Speed oscillator in Hz
The real value may vary depending on the variations
in voltage and temperature.*/
/**
* @brief External Low Speed oscillator (LSE) value.
*/
#if !defined (LSE_VALUE)
#define LSE_VALUE ((uint32_t)32768U) /*!< Value of the External Low Speed oscillator in Hz */
#endif /* LSE_VALUE */
#if !defined (LSE_STARTUP_TIMEOUT)
#define LSE_STARTUP_TIMEOUT ((uint32_t)5000U) /*!< Time out for LSE start up, in ms */
#endif /* LSE_STARTUP_TIMEOUT */
/**
* @brief External clock source for I2S peripheral
* This value is used by the I2S HAL module to compute the I2S clock source
* frequency, this source is inserted directly through I2S_CKIN pad.
*/
#if !defined (EXTERNAL_CLOCK_VALUE)
#define EXTERNAL_CLOCK_VALUE ((uint32_t)12288000U) /*!< Value of the External audio frequency in Hz*/
#endif /* EXTERNAL_CLOCK_VALUE */
/* Tip: To avoid modifying this file each time you need to use different HSE,
=== you can define the HSE value in your toolchain compiler preprocessor. */
/* ########################### System Configuration ######################### */
/**
* @brief This is the HAL system configuration section
*/
#define VDD_VALUE ((uint32_t)3300U) /*!< Value of VDD in mv */
#define TICK_INT_PRIORITY ((uint32_t)0U) /*!< tick interrupt priority */
#define USE_RTOS 0U
#define PREFETCH_ENABLE 1U
#define INSTRUCTION_CACHE_ENABLE 1U
#define DATA_CACHE_ENABLE 1U
#define USE_HAL_ADC_REGISTER_CALLBACKS 0U /* ADC register callback disabled */
#define USE_HAL_CAN_REGISTER_CALLBACKS 0U /* CAN register callback disabled */
#define USE_HAL_CEC_REGISTER_CALLBACKS 0U /* CEC register callback disabled */
#define USE_HAL_CRYP_REGISTER_CALLBACKS 0U /* CRYP register callback disabled */
#define USE_HAL_DAC_REGISTER_CALLBACKS 0U /* DAC register callback disabled */
#define USE_HAL_DCMI_REGISTER_CALLBACKS 0U /* DCMI register callback disabled */
#define USE_HAL_DFSDM_REGISTER_CALLBACKS 0U /* DFSDM register callback disabled */
#define USE_HAL_DMA2D_REGISTER_CALLBACKS 0U /* DMA2D register callback disabled */
#define USE_HAL_DSI_REGISTER_CALLBACKS 0U /* DSI register callback disabled */
#define USE_HAL_ETH_REGISTER_CALLBACKS 0U /* ETH register callback disabled */
#define USE_HAL_HASH_REGISTER_CALLBACKS 0U /* HASH register callback disabled */
#define USE_HAL_HCD_REGISTER_CALLBACKS 0U /* HCD register callback disabled */
#define USE_HAL_I2C_REGISTER_CALLBACKS 0U /* I2C register callback disabled */
#define USE_HAL_FMPI2C_REGISTER_CALLBACKS 0U /* FMPI2C register callback disabled */
#define USE_HAL_I2S_REGISTER_CALLBACKS 0U /* I2S register callback disabled */
#define USE_HAL_IRDA_REGISTER_CALLBACKS 0U /* IRDA register callback disabled */
#define USE_HAL_LPTIM_REGISTER_CALLBACKS 0U /* LPTIM register callback disabled */
#define USE_HAL_LTDC_REGISTER_CALLBACKS 0U /* LTDC register callback disabled */
#define USE_HAL_MMC_REGISTER_CALLBACKS 0U /* MMC register callback disabled */
#define USE_HAL_NAND_REGISTER_CALLBACKS 0U /* NAND register callback disabled */
#define USE_HAL_NOR_REGISTER_CALLBACKS 0U /* NOR register callback disabled */
#define USE_HAL_PCCARD_REGISTER_CALLBACKS 0U /* PCCARD register callback disabled */
#define USE_HAL_PCD_REGISTER_CALLBACKS 0U /* PCD register callback disabled */
#define USE_HAL_QSPI_REGISTER_CALLBACKS 0U /* QSPI register callback disabled */
#define USE_HAL_RNG_REGISTER_CALLBACKS 0U /* RNG register callback disabled */
#define USE_HAL_RTC_REGISTER_CALLBACKS 0U /* RTC register callback disabled */
#define USE_HAL_SAI_REGISTER_CALLBACKS 0U /* SAI register callback disabled */
#define USE_HAL_SD_REGISTER_CALLBACKS 0U /* SD register callback disabled */
#define USE_HAL_SMARTCARD_REGISTER_CALLBACKS 0U /* SMARTCARD register callback disabled */
#define USE_HAL_SDRAM_REGISTER_CALLBACKS 0U /* SDRAM register callback disabled */
#define USE_HAL_SRAM_REGISTER_CALLBACKS 0U /* SRAM register callback disabled */
#define USE_HAL_SPDIFRX_REGISTER_CALLBACKS 0U /* SPDIFRX register callback disabled */
#define USE_HAL_SMBUS_REGISTER_CALLBACKS 0U /* SMBUS register callback disabled */
#define USE_HAL_SPI_REGISTER_CALLBACKS 0U /* SPI register callback disabled */
#define USE_HAL_TIM_REGISTER_CALLBACKS 0U /* TIM register callback disabled */
#define USE_HAL_UART_REGISTER_CALLBACKS 0U /* UART register callback disabled */
#define USE_HAL_USART_REGISTER_CALLBACKS 0U /* USART register callback disabled */
#define USE_HAL_WWDG_REGISTER_CALLBACKS 0U /* WWDG register callback disabled */
/* ########################## Assert Selection ############################## */
/**
* @brief Uncomment the line below to expanse the "assert_param" macro in the
* HAL drivers code
*/
/* #define USE_FULL_ASSERT 1U */
/* ################## Ethernet peripheral configuration ##################### */
/* Section 1 : Ethernet peripheral configuration */
/* MAC ADDRESS: MAC_ADDR0:MAC_ADDR1:MAC_ADDR2:MAC_ADDR3:MAC_ADDR4:MAC_ADDR5 */
#define MAC_ADDR0 2U
#define MAC_ADDR1 0U
#define MAC_ADDR2 0U
#define MAC_ADDR3 0U
#define MAC_ADDR4 0U
#define MAC_ADDR5 0U
/* Definition of the Ethernet driver buffers size and count */
#define ETH_RX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for receive */
#define ETH_TX_BUF_SIZE ETH_MAX_PACKET_SIZE /* buffer size for transmit */
#define ETH_RXBUFNB ((uint32_t)4U) /* 4 Rx buffers of size ETH_RX_BUF_SIZE */
#define ETH_TXBUFNB ((uint32_t)4U) /* 4 Tx buffers of size ETH_TX_BUF_SIZE */
/* Section 2: PHY configuration section */
/* DP83848_PHY_ADDRESS Address*/
#define DP83848_PHY_ADDRESS 0x01U
/* PHY Reset delay these values are based on a 1 ms Systick interrupt*/
#define PHY_RESET_DELAY ((uint32_t)0x000000FFU)
/* PHY Configuration delay */
#define PHY_CONFIG_DELAY ((uint32_t)0x00000FFFU)
#define PHY_READ_TO ((uint32_t)0x0000FFFFU)
#define PHY_WRITE_TO ((uint32_t)0x0000FFFFU)
/* Section 3: Common PHY Registers */
#define PHY_BCR ((uint16_t)0x0000U) /*!< Transceiver Basic Control Register */
#define PHY_BSR ((uint16_t)0x0001U) /*!< Transceiver Basic Status Register */
#define PHY_RESET ((uint16_t)0x8000U) /*!< PHY Reset */
#define PHY_LOOPBACK ((uint16_t)0x4000U) /*!< Select loop-back mode */
#define PHY_FULLDUPLEX_100M ((uint16_t)0x2100U) /*!< Set the full-duplex mode at 100 Mb/s */
#define PHY_HALFDUPLEX_100M ((uint16_t)0x2000U) /*!< Set the half-duplex mode at 100 Mb/s */
#define PHY_FULLDUPLEX_10M ((uint16_t)0x0100U) /*!< Set the full-duplex mode at 10 Mb/s */
#define PHY_HALFDUPLEX_10M ((uint16_t)0x0000U) /*!< Set the half-duplex mode at 10 Mb/s */
#define PHY_AUTONEGOTIATION ((uint16_t)0x1000U) /*!< Enable auto-negotiation function */
#define PHY_RESTART_AUTONEGOTIATION ((uint16_t)0x0200U) /*!< Restart auto-negotiation function */
#define PHY_POWERDOWN ((uint16_t)0x0800U) /*!< Select the power down mode */
#define PHY_ISOLATE ((uint16_t)0x0400U) /*!< Isolate PHY from MII */
#define PHY_AUTONEGO_COMPLETE ((uint16_t)0x0020U) /*!< Auto-Negotiation process completed */
#define PHY_LINKED_STATUS ((uint16_t)0x0004U) /*!< Valid link established */
#define PHY_JABBER_DETECTION ((uint16_t)0x0002U) /*!< Jabber condition detected */
/* Section 4: Extended PHY Registers */
#define PHY_SR ((uint16_t)0x10U) /*!< PHY status register Offset */
#define PHY_SPEED_STATUS ((uint16_t)0x0002U) /*!< PHY Speed mask */
#define PHY_DUPLEX_STATUS ((uint16_t)0x0004U) /*!< PHY Duplex mask */
/* ################## SPI peripheral configuration ########################## */
/* CRC FEATURE: Use to activate CRC feature inside HAL SPI Driver
* Activated: CRC code is present inside driver
* Deactivated: CRC code cleaned from driver
*/
#define USE_SPI_CRC 0U
/* Includes ------------------------------------------------------------------*/
/**
* @brief Include module's header file
*/
#ifdef HAL_RCC_MODULE_ENABLED
#include "stm32f4xx_hal_rcc.h"
#endif /* HAL_RCC_MODULE_ENABLED */
#ifdef HAL_GPIO_MODULE_ENABLED
#include "stm32f4xx_hal_gpio.h"
#endif /* HAL_GPIO_MODULE_ENABLED */
#ifdef HAL_EXTI_MODULE_ENABLED
#include "stm32f4xx_hal_exti.h"
#endif /* HAL_EXTI_MODULE_ENABLED */
#ifdef HAL_DMA_MODULE_ENABLED
#include "stm32f4xx_hal_dma.h"
#endif /* HAL_DMA_MODULE_ENABLED */
#ifdef HAL_CORTEX_MODULE_ENABLED
#include "stm32f4xx_hal_cortex.h"
#endif /* HAL_CORTEX_MODULE_ENABLED */
#ifdef HAL_ADC_MODULE_ENABLED
#include "stm32f4xx_hal_adc.h"
#endif /* HAL_ADC_MODULE_ENABLED */
#ifdef HAL_CAN_MODULE_ENABLED
#include "stm32f4xx_hal_can.h"
#endif /* HAL_CAN_MODULE_ENABLED */
#ifdef HAL_CAN_LEGACY_MODULE_ENABLED
#include "stm32f4xx_hal_can_legacy.h"
#endif /* HAL_CAN_LEGACY_MODULE_ENABLED */
#ifdef HAL_CRC_MODULE_ENABLED
#include "stm32f4xx_hal_crc.h"
#endif /* HAL_CRC_MODULE_ENABLED */
#ifdef HAL_CRYP_MODULE_ENABLED
#include "stm32f4xx_hal_cryp.h"
#endif /* HAL_CRYP_MODULE_ENABLED */
#ifdef HAL_DMA2D_MODULE_ENABLED
#include "stm32f4xx_hal_dma2d.h"
#endif /* HAL_DMA2D_MODULE_ENABLED */
#ifdef HAL_DAC_MODULE_ENABLED
#include "stm32f4xx_hal_dac.h"
#endif /* HAL_DAC_MODULE_ENABLED */
#ifdef HAL_DCMI_MODULE_ENABLED
#include "stm32f4xx_hal_dcmi.h"
#endif /* HAL_DCMI_MODULE_ENABLED */
#ifdef HAL_ETH_MODULE_ENABLED
#include "stm32f4xx_hal_eth.h"
#endif /* HAL_ETH_MODULE_ENABLED */
#ifdef HAL_FLASH_MODULE_ENABLED
#include "stm32f4xx_hal_flash.h"
#endif /* HAL_FLASH_MODULE_ENABLED */
#ifdef HAL_SRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sram.h"
#endif /* HAL_SRAM_MODULE_ENABLED */
#ifdef HAL_NOR_MODULE_ENABLED
#include "stm32f4xx_hal_nor.h"
#endif /* HAL_NOR_MODULE_ENABLED */
#ifdef HAL_NAND_MODULE_ENABLED
#include "stm32f4xx_hal_nand.h"
#endif /* HAL_NAND_MODULE_ENABLED */
#ifdef HAL_PCCARD_MODULE_ENABLED
#include "stm32f4xx_hal_pccard.h"
#endif /* HAL_PCCARD_MODULE_ENABLED */
#ifdef HAL_SDRAM_MODULE_ENABLED
#include "stm32f4xx_hal_sdram.h"
#endif /* HAL_SDRAM_MODULE_ENABLED */
#ifdef HAL_HASH_MODULE_ENABLED
#include "stm32f4xx_hal_hash.h"
#endif /* HAL_HASH_MODULE_ENABLED */
#ifdef HAL_I2C_MODULE_ENABLED
#include "stm32f4xx_hal_i2c.h"
#endif /* HAL_I2C_MODULE_ENABLED */
#ifdef HAL_SMBUS_MODULE_ENABLED
#include "stm32f4xx_hal_smbus.h"
#endif /* HAL_SMBUS_MODULE_ENABLED */
#ifdef HAL_I2S_MODULE_ENABLED
#include "stm32f4xx_hal_i2s.h"
#endif /* HAL_I2S_MODULE_ENABLED */
#ifdef HAL_IWDG_MODULE_ENABLED
#include "stm32f4xx_hal_iwdg.h"
#endif /* HAL_IWDG_MODULE_ENABLED */
#ifdef HAL_LTDC_MODULE_ENABLED
#include "stm32f4xx_hal_ltdc.h"
#endif /* HAL_LTDC_MODULE_ENABLED */
#ifdef HAL_PWR_MODULE_ENABLED
#include "stm32f4xx_hal_pwr.h"
#endif /* HAL_PWR_MODULE_ENABLED */
#ifdef HAL_RNG_MODULE_ENABLED
#include "stm32f4xx_hal_rng.h"
#endif /* HAL_RNG_MODULE_ENABLED */
#ifdef HAL_RTC_MODULE_ENABLED
#include "stm32f4xx_hal_rtc.h"
#endif /* HAL_RTC_MODULE_ENABLED */
#ifdef HAL_SAI_MODULE_ENABLED
#include "stm32f4xx_hal_sai.h"
#endif /* HAL_SAI_MODULE_ENABLED */
#ifdef HAL_SD_MODULE_ENABLED
#include "stm32f4xx_hal_sd.h"
#endif /* HAL_SD_MODULE_ENABLED */
#ifdef HAL_SPI_MODULE_ENABLED
#include "stm32f4xx_hal_spi.h"
#endif /* HAL_SPI_MODULE_ENABLED */
#ifdef HAL_TIM_MODULE_ENABLED
#include "stm32f4xx_hal_tim.h"
#endif /* HAL_TIM_MODULE_ENABLED */
#ifdef HAL_UART_MODULE_ENABLED
#include "stm32f4xx_hal_uart.h"
#endif /* HAL_UART_MODULE_ENABLED */
#ifdef HAL_USART_MODULE_ENABLED
#include "stm32f4xx_hal_usart.h"
#endif /* HAL_USART_MODULE_ENABLED */
#ifdef HAL_IRDA_MODULE_ENABLED
#include "stm32f4xx_hal_irda.h"
#endif /* HAL_IRDA_MODULE_ENABLED */
#ifdef HAL_SMARTCARD_MODULE_ENABLED
#include "stm32f4xx_hal_smartcard.h"
#endif /* HAL_SMARTCARD_MODULE_ENABLED */
#ifdef HAL_WWDG_MODULE_ENABLED
#include "stm32f4xx_hal_wwdg.h"
#endif /* HAL_WWDG_MODULE_ENABLED */
#ifdef HAL_PCD_MODULE_ENABLED
#include "stm32f4xx_hal_pcd.h"
#endif /* HAL_PCD_MODULE_ENABLED */
#ifdef HAL_HCD_MODULE_ENABLED
#include "stm32f4xx_hal_hcd.h"
#endif /* HAL_HCD_MODULE_ENABLED */
#ifdef HAL_DSI_MODULE_ENABLED
#include "stm32f4xx_hal_dsi.h"
#endif /* HAL_DSI_MODULE_ENABLED */
#ifdef HAL_QSPI_MODULE_ENABLED
#include "stm32f4xx_hal_qspi.h"
#endif /* HAL_QSPI_MODULE_ENABLED */
#ifdef HAL_CEC_MODULE_ENABLED
#include "stm32f4xx_hal_cec.h"
#endif /* HAL_CEC_MODULE_ENABLED */
#ifdef HAL_FMPI2C_MODULE_ENABLED
#include "stm32f4xx_hal_fmpi2c.h"
#endif /* HAL_FMPI2C_MODULE_ENABLED */
#ifdef HAL_SPDIFRX_MODULE_ENABLED
#include "stm32f4xx_hal_spdifrx.h"
#endif /* HAL_SPDIFRX_MODULE_ENABLED */
#ifdef HAL_DFSDM_MODULE_ENABLED
#include "stm32f4xx_hal_dfsdm.h"
#endif /* HAL_DFSDM_MODULE_ENABLED */
#ifdef HAL_LPTIM_MODULE_ENABLED
#include "stm32f4xx_hal_lptim.h"
#endif /* HAL_LPTIM_MODULE_ENABLED */
#ifdef HAL_MMC_MODULE_ENABLED
#include "stm32f4xx_hal_mmc.h"
#endif /* HAL_MMC_MODULE_ENABLED */
/* Exported macro ------------------------------------------------------------*/
#ifdef USE_FULL_ASSERT
/**
* @brief The assert_param macro is used for function's parameters check.
* @param expr If expr is false, it calls assert_failed function
* which reports the name of the source file and the source
* line number of the call that failed.
* If expr is true, it returns no value.
* @retval None
*/
#define assert_param(expr) ((expr) ? (void)0U : assert_failed((uint8_t *)__FILE__, __LINE__))
/* Exported functions ------------------------------------------------------- */
void assert_failed(uint8_t* file, uint32_t line);
#else
#define assert_param(expr) ((void)0U)
#endif /* USE_FULL_ASSERT */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_HAL_CONF_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -1,89 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.h
* @brief This file contains the headers of the interrupt handlers.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Define to prevent recursive inclusion -------------------------------------*/
#ifndef __STM32F4xx_IT_H
#define __STM32F4xx_IT_H
#ifdef __cplusplus
extern "C" {
#endif
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Exported types ------------------------------------------------------------*/
/* USER CODE BEGIN ET */
/* USER CODE END ET */
/* Exported constants --------------------------------------------------------*/
/* USER CODE BEGIN EC */
/* USER CODE END EC */
/* Exported macro ------------------------------------------------------------*/
/* USER CODE BEGIN EM */
/* USER CODE END EM */
/* Exported functions prototypes ---------------------------------------------*/
void NMI_Handler(void);
void HardFault_Handler(void);
void MemManage_Handler(void);
void BusFault_Handler(void);
void UsageFault_Handler(void);
void SVC_Handler(void);
void DebugMon_Handler(void);
void PendSV_Handler(void);
void SysTick_Handler(void);
void EXTI0_IRQHandler(void);
void EXTI1_IRQHandler(void);
void EXTI2_IRQHandler(void);
void EXTI3_IRQHandler(void);
void DMA1_Stream0_IRQHandler(void);
void DMA1_Stream5_IRQHandler(void);
void EXTI9_5_IRQHandler(void);
void TIM3_IRQHandler(void);
void TIM4_IRQHandler(void);
void EXTI15_10_IRQHandler(void);
void TIM8_UP_TIM13_IRQHandler(void);
void TIM5_IRQHandler(void);
void SPI3_IRQHandler(void);
void TIM6_DAC_IRQHandler(void);
void TIM7_IRQHandler(void);
void DMA2_Stream1_IRQHandler(void);
void DMA2_Stream2_IRQHandler(void);
void OTG_FS_IRQHandler(void);
void DMA2_Stream5_IRQHandler(void);
void DMA2_Stream6_IRQHandler(void);
/* USER CODE BEGIN EFP */
/* USER CODE END EFP */
#ifdef __cplusplus
}
#endif
#endif /* __STM32F4xx_IT_H */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

118
Src/agc.c
Wyświetl plik

@ -1,118 +0,0 @@
#include "stm32f4xx_hal.h"
#include "agc.h"
#include "settings.h"
#include "audio_filters.h"
//Private variables
static float32_t AGC_RX_need_gain_db = 0.0f;
static float32_t AGC_RX_need_gain_db_old = 0.0f;
IRAM2 static float32_t AGC_RX_ringbuffer[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)
{
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;
}
else
{
RX_AGC_STEPSIZE_UP = 200.0f / (float32_t)TRX.RX_AGC_SSB_speed;
RX_AGC_STEPSIZE_DOWN = 20.0f / (float32_t)TRX.RX_AGC_SSB_speed;
}
//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);
//move ring buffer index
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);
//calculate the magnitude in dBFS
float32_t AGC_RX_magnitude = 0;
arm_rms_f32(agcBuffer, 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)
{
float32_t diff = ((float32_t)TRX.AGC_GAIN_TARGET - (AGC_RX_dbFS + *AGC_need_gain_db));
if (diff > 0)
*AGC_need_gain_db += diff / RX_AGC_STEPSIZE_UP;
else
*AGC_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))
{
*AGC_need_gain_db = (float32_t)TRX.AGC_GAIN_TARGET - AGC_RX_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;*/
//AGC off, not adjustable
if (!CurrentVFO()->AGC)
*AGC_need_gain_db = 1.0f;
//Muting if need
if(WM8731_Muting)
*AGC_need_gain_db = -200.0f;
//gain limitation
if (*AGC_need_gain_db > AGC_MAX_GAIN)
*AGC_need_gain_db = AGC_MAX_GAIN;
//apply gain
if (fabsf(*AGC_need_gain_db_old - *AGC_need_gain_db) > 0.0f) //gain changed
{
float32_t gainApplyStep = 0;
if (*AGC_need_gain_db_old > *AGC_need_gain_db)
gainApplyStep = -(*AGC_need_gain_db_old - *AGC_need_gain_db) / (float32_t)blockSize;
if (*AGC_need_gain_db_old < *AGC_need_gain_db)
gainApplyStep = (*AGC_need_gain_db - *AGC_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_need_gain_db_old += gainApplyStep;
agcBuffer[i] = agcBuffer[i] * db2rateV(*AGC_need_gain_db_old);
val_prev = agcBuffer[i];
}
}
else //gain did not change, apply gain across all samples
{
arm_scale_f32(agcBuffer, db2rateV(*AGC_need_gain_db), agcBuffer, blockSize);
}
}
void ResetAGC(void)
{
AGC_RX_need_gain_db = 0.0f;
memset(AGC_RX_ringbuffer, 0x00, sizeof(AGC_RX_ringbuffer));
}

Wyświetl plik

@ -1,14 +0,0 @@
#ifndef AGC_H
#define AGC_H
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#include "audio_processor.h"
#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 ResetAGC(void);
#endif

Wyświetl plik

@ -1,741 +0,0 @@
#include "audio_filters.h"
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "arm_math.h"
#include "functions.h"
#include "wm8731.h"
#include "settings.h"
#include "auto_notch.h"
#include "trx_manager.h"
//Private variables
static float32_t Fir_RX_Hilbert_State_I[FIR_RX_HILBERT_STATE_SIZE] = {0}; // buffers of filter states
static float32_t Fir_RX_Hilbert_State_Q[FIR_RX_HILBERT_STATE_SIZE] = {0};
static float32_t Fir_Tx_Hilbert_State_I[FIR_TX_HILBERT_STATE_SIZE] = {0};
static float32_t Fir_Tx_Hilbert_State_Q[FIR_TX_HILBERT_STATE_SIZE] = {0};
static float32_t IIR_RX_LPF_I_State[IIR_RX_LPF_Taps_STATE_SIZE] = {0};
static float32_t IIR_RX_LPF_Q_State[IIR_RX_LPF_Taps_STATE_SIZE] = {0};
static float32_t IIR_RX_GAUSS_State[IIR_RX_GAUSS_Taps_STATE_SIZE] = {0};
static float32_t IIR_TX_LPF_I_State[IIR_RX_LPF_Taps_STATE_SIZE] = {0};
static float32_t IIR_RX_HPF_I_State[IIR_RX_HPF_Taps_STATE_SIZE] = {0};
static float32_t IIR_TX_HPF_I_State[IIR_RX_HPF_Taps_STATE_SIZE] = {0};
static float32_t IIR_RX_HPF_SQL_State[IIR_RX_HPF_SQL_STATE_SIZE] = {0};
static float32_t EQ_RX_LOW_FILTER_State[2 * EQ_STAGES] = {0};
static float32_t EQ_RX_MID_FILTER_State[2 * EQ_STAGES] = {0};
static float32_t EQ_RX_HIG_FILTER_State[2 * EQ_STAGES] = {0};
static float32_t EQ_RX_LOW_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
static float32_t EQ_RX_MID_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
static float32_t EQ_RX_HIG_FILTER_Coeffs[BIQUAD_COEFF_IN_STAGE * EQ_STAGES] = {0};
static float32_t EQ_MIC_LOW_FILTER_State[2 * EQ_STAGES] = {0};
static float32_t EQ_MIC_MID_FILTER_State[2 * EQ_STAGES] = {0};
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 DC_filter_state_type DC_Filter_State[8] = {0}; // states of the DC corrector
// Collection of filters
//IQ Hilbert with (+45 q / -45 i) degrees phase added, 48000 sampling frequency Fc=1.95kHz, BW=4.53kHz Sinc, Raised Cosine 0.910 // Iowa Hills Hilbert Filters
//static const float32_t FIR_HILB_I_coeffs[IQ_HILBERT_TAPS] = {223.7509881945750E-9, 948.5448959443470E-9, 2.239548070940360E-6, 4.104081513478730E-6, 6.473278399896580E-6, 9.243363618311680E-6, 0.000012375306830145, 0.000016008470118094, 0.000020514831353058, 0.000026428582704618, 0.000034238287518054, 0.000044107685972401, 0.000055658388468059, 0.000067960735122181, 0.000079814414911969, 0.000090271019268658, 0.000099208267996747, 0.000107682375571142, 0.000117820188231993, 0.000132178448300499, 0.000152741505943579, 0.000179946397181736, 0.000212200254787838, 0.000246219865497213, 0.000278197754411937, 0.000305403847133994, 0.000327547176022056, 0.000347211639892836, 0.000369004605143288, 0.000397624259417610, 0.000435628238606010, 0.000481985678838541, 0.000532308421669435, 0.000580973374933797, 0.000624402160968576, 0.000663975552226445, 0.000706866273201483, 0.000763718418281774, 0.000843470610359944, 0.000947212263362751, 0.001064042332409273, 0.001171796460180425, 0.001243951997037104, 0.001261369267521314, 0.001224751811749544, 0.001162086034885813, 0.001125920875792500, 0.001178490669945493, 0.001367614744816024, 0.001701279127048149, 0.002131623535440460, 0.002557937761052193, 0.002852717842663536, 0.002906138181592429, 0.002675393927642395, 0.002219948090046554, 0.001704839436171120, 0.001362891287901267, 0.001421041702098347, 0.002011509947420330, 0.003099138284411245, 0.004456751183384506, 0.005708484289066565, 0.006438931350315933, 0.006340243026888855, 0.005349242515151897, 0.003720982515017856, 0.001998787552236407, 0.000872042233036055, 0.000953170264748813, 0.002540912444746210, 0.005454091829370742, 0.009009087200446018, 0.012174602696360195, 0.013878843787567130, 0.013385124179631247, 0.010613479505888278, 0.006285039489443841, 0.001808717781247508, -0.001092430678638297, -0.000927283437365230, 0.003006301950665575, 0.010243640800918661, 0.019112611427735394, 0.027098107257607106, 0.031553929105355837, 0.030581250057604290, 0.023812767466428037, 0.012836160782847062, 0.001069713701562541, -0.006949315019545316, -0.006726605747478962, 0.004866458991959632, 0.028477691298525291, 0.061710400362786785, 0.099325780000166744, 0.134224240487393925, 0.158999573746049172, 0.167687454575943418, 0.157256673476852710, 0.128442847558250611, 0.085689313488739788, 0.036193922460058224, -0.011702019132317934, -0.050372660860353115, -0.074543394440449343, -0.082300601206559604, -0.075248447552329234, -0.057817989610136365, -0.035955570364459531, -0.015567203459010078, -0.001134744675231588, 0.005157014696688749, 0.003607309109247389, -0.003474931963170549, -0.012705711479376576, -0.020715053812433180, -0.025075301617804493, -0.024833661635348364, -0.020552614868337892, -0.013912891586523883, -0.007052065843042134, -0.001866246821034922, 0.000516223781271204, -0.000041989114492909, -0.002791021180205989, -0.006447927676302333, -0.009659645602751786, -0.011419791177594530, -0.011319648039713963, -0.009580882713672524, -0.006891697580158546, -0.004125421384087170, -0.002045398082686481, -0.001089117339142527, -0.001286193727599866, -0.002314945400675894, -0.003658321010890728, -0.004794865749544438, -0.005359485571258614, -0.005228661686680162, -0.004515964267980362, -0.003494458365862956, -0.002483052706789675, -0.001739036113379079, -0.001389760063268084, -0.001418064078799173, -0.001696122343817232, -0.002047716179087368, -0.002313436442110995, -0.002397200313346026, -0.002282760930956755, -0.002020990464106081, -0.001698228383151980, -0.001400181098315894, -0.001184326559787539, -0.001068152544581845, -0.001033582851205000, -0.001042310654116016, -0.001054161971946344, -0.001041346771202241, -0.000994567685711711, -0.000920829128941494, -0.000835855182120961, -0.000755329158990894, -0.000688603234807107, -0.000636705673632633, -0.000594357900905697, -0.000554181925717891, -0.000510804932678112, -0.000463118664475597, -0.000414096319555456, -0.000368727521834393, -0.000331328678648681, -0.000303524506053571, -0.000283683901660525, -0.000267842266116449, -0.000251506689829605, -0.000231463646998481, -0.000206844002176803, -0.000179121332298031, -0.000151204743056522, -0.000126126266083465, -0.000105901672116307, -0.000090974893900219, -0.000080352409047133, -0.000072242785698550, -0.000064854267073064, -0.000057011646034372, -0.000048396414268341, -0.000039406214264031, -0.000030781942374507, -0.000023208699143715, -0.000017056318020772, -0.000012325180003317, -8.759613105575410E-6, -6.029969405701850E-6, -3.882492263574330E-6, -2.200025615965410E-6, -975.1397524474980E-9, -239.2027170806280E-9};
//static const float32_t FIR_HILB_Q_coeffs[IQ_HILBERT_TAPS] = {-239.2027170806560E-9, -975.1397524476660E-9, -2.200025615965810E-6, -3.882492263574850E-6, -6.029969405702120E-6, -8.759613105574830E-6, -0.000012325180003315, -0.000017056318020768, -0.000023208699143709, -0.000030781942374500, -0.000039406214264024, -0.000048396414268337, -0.000057011646034372, -0.000064854267073069, -0.000072242785698559, -0.000080352409047147, -0.000090974893900237, -0.000105901672116327, -0.000126126266083482, -0.000151204743056535, -0.000179121332298038, -0.000206844002176803, -0.000231463646998477, -0.000251506689829601, -0.000267842266116452, -0.000283683901660539, -0.000303524506053597, -0.000331328678648716, -0.000368727521834428, -0.000414096319555478, -0.000463118664475595, -0.000510804932678080, -0.000554181925717832, -0.000594357900905625, -0.000636705673632569, -0.000688603234807070, -0.000755329158990898, -0.000835855182121003, -0.000920829128941556, -0.000994567685711768, -0.001041346771202267, -0.001054161971946331, -0.001042310654115978, -0.001033582851204978, -0.001068152544581889, -0.001184326559787687, -0.001400181098316153, -0.001698228383152308, -0.002020990464106389, -0.002282760930956934, -0.002397200313345985, -0.002313436442110709, -0.002047716179086903, -0.001696122343816746, -0.001418064078798878, -0.001389760063268167, -0.001739036113379629, -0.002483052706790617, -0.003494458365864043, -0.004515964267981224, -0.005228661686680431, -0.005359485571258059, -0.004794865749543089, -0.003658321010888926, -0.002314945400674231, -0.001286193727599023, -0.001089117339143038, -0.002045398082688510, -0.004125421384090377, -0.006891697580162112, -0.009580882713675352, -0.011319648039715023, -0.011419791177593237, -0.009659645602748290, -0.006447927676297602, -0.002791021180201610, -0.000041989114490631, 0.000516223781270046, -0.001866246821039895, -0.007052065843050045, -0.013912891586532689, -0.020552614868344893, -0.024833661635351008, -0.025075301617801304, -0.020715053812424448, -0.012705711479364563, -0.003474931963159146, 0.003607309109253661, 0.005157014696686077, -0.001134744675244962, -0.015567203459032938, -0.035955570364487460, -0.057817989610162497, -0.075248447552345707, -0.082300601206559548, -0.074543394440428748, -0.050372660860312120, -0.011702019132261260, 0.036193922460122083, 0.085689313488800323, 0.128442847558297574, 0.157256673476878356, 0.167687454575944500, 0.158999573746027162, 0.134224240487354735, 0.099325780000119254, 0.061710400362740524, 0.028477691298488390, 0.004866458991937123, -0.006726605747485966, -0.006949315019539358, 0.001069713701576379, 0.012836160782862767, 0.023812767466440302, 0.030581250057609779, 0.031553929105353769, 0.027098107257598970, 0.019112611427724233, 0.010243640800907937, 0.003006301950658107, -0.000927283437367983, -0.001092430678636460, 0.001808717781252494, 0.006285039489449838, 0.010613479505893192, 0.013385124179633633, 0.013878843787566531, 0.012174602696357130, 0.009009087200441680, 0.005454091829366533, 0.002540912444743289, 0.000953170264747782, 0.000872042233036866, 0.001998787552238471, 0.003720982515020316, 0.005349242515153926, 0.006340243026889902, 0.006438931350315841, 0.005708484289065552, 0.004456751183383028, 0.003099138284409812, 0.002011509947419342, 0.001421041702097986, 0.001362891287901485, 0.001704839436171697, 0.002219948090047204, 0.002675393927642869, 0.002906138181592586, 0.002852717842663368, 0.002557937761051797, 0.002131623535439987, 0.001701279127047741, 0.001367614744815772, 0.001178490669945418, 0.001125920875792563, 0.001162086034885941, 0.001224751811749666, 0.001261369267521385, 0.001243951997037112, 0.001171796460180390, 0.001064042332409229, 0.000947212263362729, 0.000843470610359959, 0.000763718418281822, 0.000706866273201547, 0.000663975552226500, 0.000624402160968601, 0.000580973374933785, 0.000532308421669388, 0.000481985678838475, 0.000435628238605942, 0.000397624259417553, 0.000369004605143252, 0.000347211639892820, 0.000327547176022054, 0.000305403847133999, 0.000278197754411941, 0.000246219865497210, 0.000212200254787827, 0.000179946397181720, 0.000152741505943561, 0.000132178448300484, 0.000117820188231982, 0.000107682375571138, 0.000099208267996750, 0.000090271019268667, 0.000079814414911980, 0.000067960735122194, 0.000055658388468071, 0.000044107685972409, 0.000034238287518059, 0.000026428582704620, 0.000020514831353058, 0.000016008470118092, 0.000012375306830142, 9.243363618309360E-6, 6.473278399895030E-6, 4.104081513477980E-6, 2.239548070940140E-6, 948.5448959443480E-9, 223.7509881945930E-9};
static const float32_t FIR_HILB_Q_coeffs[IQ_HILBERT_TAPS] = {-5.702029823289780E-6,-0.000039219921881772,-0.000125961068157237,-0.000270915868650029,-0.000435993654001520,-0.000540377608401144,-0.000497504547388838,-0.000282830558176925,-2.421702967718130E-6,0.000082954298431622,-0.000382670153833527,-0.001700621211116391,-0.003920158431250949,-0.006681314536912206,-0.009200409429965023,-0.010466629248141970,-0.009637173648363497,-0.006516625440883324,-0.001926794263403978,0.002239659354791165,0.003411293934926346,-0.000850063052119150,-0.011826169645843291,-0.028755507153826302,-0.048456557469219834,-0.065717656839010666,-0.074471271884586326,-0.069486353007572735,-0.048086624492331379,-0.011328593299850849,0.035805263058567308,0.085352373172954799,0.128243450680040061,0.156577648180890816,0.165625340599039911,0.154958903256784741,0.128386567929334255,0.092744251946634576,0.055953014535082536,0.024955620998299490,0.004140778180043780,-0.005338445681787938,-0.005262344892036169,0.000716546420940858,0.008462390387404947,0.014602504124462335,0.017281600304896699,0.016291703631702837,0.012671228801091745,0.008020781513322696,0.003824038292439508,0.000995567718524096,-0.000252182117595943,-0.000263867482074276,0.000353056290897718,0.001023718549879908,0.001394469069796279,0.001377552373787447,0.001080605783388492,0.000686212071331413,0.000346610446248922,0.000131756987082392,0.000033840379282726,5.495187851186830E-6,1.184916684512400E-6,};
static const float32_t FIR_HILB_I_coeffs[IQ_HILBERT_TAPS] = {1.184916684511330E-6,5.495187851192830E-6,0.000033840379282765,0.000131756987082493,0.000346610446249087,0.000686212071331583,0.001080605783388535,0.001377552373787196,0.001394469069795626,0.001023718549878922,0.000353056290896726,-0.000263867482074702,-0.000252182117595157,0.000995567718526529,0.003824038292443482,0.008020781513327347,0.012671228801095511,0.016291703631703871,0.017281600304893549,0.014602504124454760,0.008462390387394530,0.000716546420931058,-0.005262344892040617,-0.005338445681782295,0.004140778180062659,0.024955620998331700,0.055953014535124364,0.092744251946678791,0.128386567929371614,0.154958903256806030,0.165625340599038717,0.156577648180865114,0.128243450679993098,0.085352373172894513,0.035805263058504240,-0.011328593299906053,-0.048086624492370562,-0.069486353007591969,-0.074471271884586368,-0.065717656838996275,-0.048456557469197976,-0.028755507153804018,-0.011826169645826008,-0.000850063052109614,0.003411293934928160,0.002239659354787342,-0.001926794263410410,-0.006516625440889521,-0.009637173648367584,-0.010466629248143317,-0.009200409429964055,-0.006681314536909944,-0.003920158431248482,-0.001700621211114497,-0.000382670153832524,0.000082954298431821,-2.421702968013570E-6,-0.000282830558177374,-0.000497504547389206,-0.000540377608401341,-0.000435993654001571,-0.000270915868650005,-0.000125961068157200,-0.000039219921881752,-5.702029823285370E-6};
static const IIR_BIQUAD_FILTER IIR_Biquad_Filters[IIR_FILTERS_COUNT] = (const IIR_BIQUAD_FILTER[]){
//IIR RX/TX IIR Highpass Fs=48000 Apass=1 Astop=120 // coefficients converted to Direct-Form II Transposed by MATLAB // https://ua3reo.ru/services/matlab_to_arm_biquad.php
{
.width = 60,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9998945186242, 0, 0, 0, 0, 1, -2, 1, 1.999758132887, -0.99981994161, 0.9996889367649, 0, 0, 0, 0, 1, -2, 1, 1.999343665899, -0.9994120811608, 0.9993922022251, 0, 0, 0, 0, 1, -2, 1, 1.99874202768, -0.9988267812205, 0.9988594148129, 0, 0, 0, 0, 1, -2, 1, 1.997658474509, -0.9977791847428, 0.9976379235525, 0, 0, 0, 0, 1, -2, 1, 1.995171008271, -0.9953806859393, 0.993575273017, 0, 0, 0, 0, 1, -2, 1, 1.9868941568, -0.9874069352679, 0.9658298859242, 0, 0, 0, 0, 1, -2, 1, 1.930363237657, -0.9329563060393, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 100,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9998070433437, 0, 0, 0, 0, 1, -2, 1, 1.99952824718, -0.9996999261949, 0.9994626733323, 0, 0, 0, 0, 1, -2, 1, 1.998830345237, -0.9990203480919, 0.998963895279, 0, 0, 0, 0, 1, -2, 1, 1.997810125605, -0.9980454555113, 0.9980670102991, 0, 0, 0, 0, 1, -2, 1, 1.995966497435, -0.9963015437617, 0.9960114376034, 0, 0, 0, 0, 1, -2, 1, 1.991732125694, -0.99231362472, 0.9891973898471, 0, 0, 0, 0, 1, -2, 1, 1.977685712474, -0.9791038469146, 0.9436531717078, 0, 0, 0, 0, 1, -2, 1, 1.883787490005, -0.8908251968259, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 200,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9995283511221, 0, 0, 0, 0, 1, -2, 1, 1.998713410513, -0.9993999939754, 0.9988310262326, 0, 0, 0, 0, 1, -2, 1, 1.997282254376, -0.9980418505545, 0.9978125457543, 0, 0, 0, 0, 1, -2, 1, 1.995154933871, -0.9960952491464, 0.9959747660947, 0, 0, 0, 0, 1, -2, 1, 1.991280786954, -0.9926182774253, 0.9917669813622, 0, 0, 0, 0, 1, -2, 1, 1.98237582151, -0.9846921039384, 0.9779386809936, 0, 0, 0, 0, 1, -2, 1, 1.953073134305, -0.9586815896694, 0.8903472269478, 0, 0, 0, 0, 1, -2, 1, 1.767413007236, -0.7939759005556, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 300,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9991640098344, 0, 0, 0, 0, 1, -2, 1, 1.997555784552, -0.9991002547852, 0.998105326748, 0, 0, 0, 0, 1, -2, 1, 1.995356606708, -0.9970647002838, 0.9965466117696, 0, 0, 0, 0, 1, -2, 1, 1.992036560075, -0.9941498870033, 0.9937250727065, 0, 0, 0, 0, 1, -2, 1, 1.985948652965, -0.9889516378612, 0.9872730937592, 0, 0, 0, 0, 1, -2, 1, 1.971951806778, -0.9771405682585, 0.9662614994334, 0, 0, 0, 0, 1, -2, 1, 1.926287935636, -0.9387580620975, 0.8400927948412, 0, 0, 0, 0, 1, -2, 1, 1.651985027197, -0.7083861521682, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 400,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9987141206486, 0, 0, 0, 0, 1, -2, 1, 1.996055722606, -0.9988007599883, 0.997285863546, 0, 0, 0, 0, 1, -2, 1, 1.993054364875, -0.9960890893095, 0.9951667918349, 0, 0, 0, 0, 1, -2, 1, 1.988457296701, -0.9922098706388, 0.9913198227663, 0, 0, 0, 0, 1, -2, 1, 1.979976254042, -0.9853030370226, 0.982536466246, 0, 0, 0, 0, 1, -2, 1, 1.960481910207, -0.9696639547771, 0.9542033020911, 0, 0, 0, 0, 1, -2, 1, 1.897458185064, -0.9193550233007, 0.7928443133024, 0, 0, 0, 0, 1, -2, 1, 1.538364485671, -0.6330127675387, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 500,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.9981787993571, 0, 0, 0, 0, 1, -2, 1, 1.994213636568, -0.9985015608603, 0.9963729457258, 0, 0, 0, 0, 1, -2, 1, 1.990376574159, -0.9951152087441, 0.9936738219286, 0, 0, 0, 0, 1, -2, 1, 1.98441959088, -0.9902756968342, 0.9887609930392, 0, 0, 0, 0, 1, -2, 1, 1.973370111394, -0.9816738607631, 0.9775639982538, 0, 0, 0, 0, 1, -2, 1, 1.947988992653, -0.9622670003627, 0.9418011512827, 0, 0, 0, 0, 1, -2, 1, 1.866713400754, -0.9004912043762, 0.748515491982, 0, 0, 0, 0, 1, -2, 1, 1.427203352458, -0.5668586154696, 0.8912509381337, 0, 0, 0, 0},
},
//used for the FM noise squelch
{
.width = 15000,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.3049851455408, 0, 0, 0, 0, 1, -2, 1, -0.7591287465444, -0.9790693287075, 0.2780078711753, 0, 0, 0, 0, 1, -2, 1, -0.8256589275237, -0.9376904122248, 0.2323960275367, 0, 0, 0, 0, 1, -2, 1, -0.9664437350711, -0.8960278452179, 0.1720665990118, 0, 0, 0, 0, 1, -2, 1, -1.165936151782, -0.8542025478295, 0.1051104068231, 0, 0, 0, 0, 1, -2, 1, -1.394079028152, -0.8145206554444, 0.04513708899945, 0, 0, 0, 0, 1, -2, 1, -1.601425033622, -0.78197338962, 0.008951452064989, 0, 0, 0, 0, 1, -2, 1, -1.727386349532, -0.7631921577923, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 20000,
.type = IIR_BIQUAD_HPF,
.stages = 15,
.coeffs = (float32_t[]){0.0664759669061, 0, 0, 0, 0, 1, -2, 1, -1.722719616758, -0.9886234843822, 0.05976585969453, 0, 0, 0, 0, 1, -2, 1, -1.727533129144, -0.9665965679221, 0.04829462608705, 0, 0, 0, 0, 1, -2, 1, -1.752941532896, -0.9461200372446, 0.03407949397928, 0, 0, 0, 0, 1, -2, 1, -1.791673048598, -0.9279910245151, 0.0197409684492, 0, 0, 0, 0, 1, -2, 1, -1.834168405903, -0.9131322796994, 0.00809367952317, 0, 0, 0, 0, 1, -2, 1, -1.870134827536, -0.9025095456287, 0.001562021017125, 0, 0, 0, 0, 1, -2, 1, -1.890706281461, -0.8969543655294, 0.8912509381337, 0, 0, 0, 0},
},
//IIR RX/TX IIR Lowpass Fs=48000 Apass=1 Astop=120 // coefficients converted to Direct-Form II Transposed by MATLAB // https://ua3reo.ru/services/matlab_to_arm_biquad.php
{
.width = 100,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7208249334091,0,0,0,0,1,-1.999778997495,1,1.999439781257,-0.9996040129205,0.7429805216488,0,0,0,0,1,-1.999754828728,1,1.999056772806,-0.9992054066203,0.6060753731942,0,0,0,0,1,-1.99969848302,1,1.998483224057,-0.9986051015077,0.4040649675117,0,0,0,0,1,-1.999550310328,1,1.997690564915,-0.9977738396473,0.1851242413914,0,0,0,0,1,-1.998994965209,1,1.996804854186,-0.9968443765289,0.03938043700753,0,0,0,0,1,-1.992011689511,1,1.996176352021,-0.9961846783158,0.00104216721092,0,0,0,0,1,-1.999788340031,1,1.999709903108,-0.9998811122444,1,0,0,0,0},
},
{
.width = 100, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0002143270359125,0,0,0,0,1,0,-1,1.999528518437,-0.9995713459282,1,0,0,0,0},
},
{
.width = 150,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7207663679481,0,0,0,0,1,-1.999502760955,1,1.999036619167,-0.9994060980585,0.7428553682145,0,0,0,0,1,-1.99944838721,1,1.998474024666,-0.9988083807338,0.6058981026978,0,0,0,0,1,-1.9993216265,1,1.997634295991,-0.9979084240038,0.4038864514181,0,0,0,0,1,-1.998988304298,1,1.996475378457,-0.996662644194,0.185034119949,0,0,0,0,1,-1.997739301064,1,1.99518141299,-0.9952702702351,0.03944102586584,0,0,0,0,1,-1.982070421081,1,1.994263667199,-0.9942823841278,0.001042149410275,0,0,0,0,1,-1.99952377957,1,1.999436477776,-0.999821680025,1,0,0,0,0},
},
{
.width = 150, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0003214561070949,0,0,0,0,1,0,-1,1.999260736687,-0.9993570877858,1,0,0,0,0},
},
{
.width = 200,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.72071293336,0,0,0,0,1,-1.999116060767,1,1.998551474236,-0.9992082462229,0.74273923566,0,0,0,0,1,-1.999019411215,1,1.997817269575,-0.9984115533916,0.6057345646873,0,0,0,0,1,-1.998794101473,1,1.996725115572,-0.9972122828077,0.4037266243069,0,0,0,0,1,-1.998201693769,1,1.995219980663,-0.995552716956,0.1849664489646,0,0,0,0,1,-1.995982544993,1,1.993540763584,-0.9936986127449,0.03954071763951,0,0,0,0,1,-1.968234357343,1,1.992350363641,-0.992383608041,0.00104213688186,0,0,0,0,1,-1.999153421989,1,1.99907749239,-0.999762258967,1,0,0,0,0},
},
{
.width = 200, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0004285622244523,0,0,0,0,1,0,-1,1.998971604131,-0.9991428755511,1,0,0,0,0},
},
{
.width = 250,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.720664630314,0,0,0,0,1,-1.998618927893,1,1.997984389508,-0.999010465336,0.7426321228591,0,0,0,0,1,-1.998467942861,1,1.997086571898,-0.9980149380731,0.6055847496559,0,0,0,0,1,-1.998115982012,1,1.995755763839,-0.9965166942234,0.4035854587266,0,0,0,0,1,-1.99719067651,1,1.993924446042,-0.9944440666845,0.1849211788432,0,0,0,0,1,-1.993725868381,1,1.991882932514,-0.9921293880475,0.03967941092905,0,0,0,0,1,-1.950583777507,1,1.99043640762,-0.9904883056732,0.001042129625741,0,0,0,0,1,-1.998677294347,1,1.998632969917,-0.9997028516111,1,0,0,0,0},
},
{
.width = 250, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0005356453959978,0,0,0,0,1,0,-1,1.998661128432,-0.998928709208,1,0,0,0,0},
},
{
.width = 300,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7206214592866,0,0,0,0,1,-1.998011402133,1,1.997335411073,-0.9988127633125,0.7425340284537,0,0,0,0,1,-1.997794036286,1,1.996281997835,-0.9976185482359,0.6054486480294,0,0,0,0,1,-1.997287363311,1,1.994726322031,-0.9958216745118,0.4034629277141,0,0,0,0,1,-1.995955506583,1,1.992588847953,-0.9933367020948,0.1848982613918,0,0,0,0,1,-1.990970773959,1,1.990207945175,-0.9905625802184,0.03985700780755,0,0,0,0,1,-1.929219894403,1,1.988521765331,-0.9885964329325,0.00104212764176,0,0,0,0,1,-1.998095431429,1,1.998102936976,-0.999643460497,1,0,0,0,0},
},
{
.width = 300, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0006427056297418,0,0,0,0,1,0,-1,1.99832931748,-0.9987145887405,1,0,0,0,0},
},
{
.width = 350,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205834205616,0,0,0,0,1,-1.997293532117,1,1.99660458806,-0.99861514806,0.7424449508537,0,0,0,0,1,-1.996997757633,1,1.99540361542,-0.9972223973154,0.6053262501675,0,0,0,0,1,-1.996308361653,1,1.993636871581,-0.9951272398908,0.4033590047953,0,0,0,0,1,-1.994496494189,1,1.991213258601,-0.992230631867,0.1848976498142,0,0,0,0,1,-1.987719093305,1,1.988515825824,-0.9889981734199,0.04007341379976,0,0,0,0,1,-1.90426342632,1,1.986606402888,-0.9867079460128,0.001042130929534,0,0,0,0,1,-1.997407875739,1,1.99748742383,-0.9995840881632,1,0,0,0,0},
},
{
.width = 350, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0007497429336899,0,0,0,0,1,0,-1,1.997976179388,-0.9985005141326,1,0,0,0,0},
},
{
.width = 400,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205505142308,0,0,0,0,1,-1.996465375298,1,1.995791972632,-0.9984176274778,0.7423648882386,0,0,0,0,1,-1.996079185037,1,1.994451494511,-0.9968264987251,0.6052175463649,0,0,0,0,1,-1.995179114375,1,1.992487494118,-0.9944334065369,0.4032736639842,0,0,0,0,1,-1.992814005477,1,1.989797749049,-0.9911258646493,0.1849192987046,0,0,0,0,1,-1.98397298382,1,1.986806597581,-0.9874361519016,0.04032853786182,0,0,0,0,1,-1.875852930095,1,1.984690286325,-0.98482280139,0.001042139488453,0,0,0,0,1,-1.996614677492,1,1.996786464388,-0.999524737147,1,0,0,0,0},
},
{
.width = 400, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0008567573158444,0,0,0,0,1,0,-1,1.997601722498,-0.9982864853683,1,0,0,0,0},
},
{
.width = 450,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.720522740194,0,0,0,0,1,-1.995526997943,1,1.994897619985,-0.9982202094577,0.7422938385575,0,0,0,0,1,-1.995038408611,1,1.993425706782,-0.9964308658566,0.6051225268525,0,0,0,0,1,-1.993899779815,1,1.991278271456,-0.9937401905854,0.4032068797833,0,0,0,0,1,-1.990908462318,1,1.988342389214,-0.9900224090586,0.1849631640421,0,0,0,0,1,-1.979734925169,1,1.985080282437,-0.9858765000009,0.04062229236161,0,0,0,0,1,-1.844142937358,1,1.982773381593,-0.9829409558176,0.001042153317685,0,0,0,0,1,-1.995715894613,1,1.9960000962,-0.9994654099842,1,0,0,0,0},
},
{
.width = 450, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.0009637487842045,0,0,0,0,1,0,-1,1.997205955375,-0.9980725024316,1,0,0,0,0},
},
{
.width = 500,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205000981589,0,0,0,0,1,-1.994478475121,1,1.993921588337,-0.9980229018828,0.7422317995304,0,0,0,0,1,-1.99387553042,1,1.992326325722,-0.9960355120791,0.605041181799,0,0,0,0,1,-1.992470537271,1,1.990009285596,-0.9930476081313,0.4031586271833,0,0,0,0,1,-1.988780342047,1,1.986847247871,-0.9889202736833,0.1850292031848,0,0,0,0,1,-1.975007715206,1,1.983336901258,-0.9843192021433,0.04095459305977,0,0,0,0,1,-1.80930193913,1,1.980855654558,-0.9810623663232,0.001042172416172,0,0,0,0,1,-1.994711592723,1,1.995128360456,-0.9994061092093,1,0,0,0,0},
},
{
.width = 500, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001070717346765,0,0,0,0,1,0,-1,1.99678888681,-0.9978585653065,1,0,0,0,0},
},
{
.width = 550,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.720482587642,0,0,0,0,1,-1.993319890691,1,1.992863938922,-0.9978257126279,0.7421787686485,0,0,0,0,1,-1.992590664465,1,1.991153426622,-0.9956404507398,0.6049735013114,0,0,0,0,1,-1.99089158693,1,1.988680618721,-0.9923556752304,0.4031288816626,0,0,0,0,1,-1.986430177167,1,1.985312392662,-0.987819467085,0.1851173748647,0,0,0,0,1,-1.969794465394,1,1.981576473791,-0.9827642428434,0.04132535909133,0,0,0,0,1,-1.771510265592,1,1.978937070998,-0.979186990204,0.001042196782629,0,0,0,0,1,-1.993601845129,1,1.994171301981,-0.9993468373552,1,0,0,0,0},
},
{
.width = 550, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001177663011516,0,0,0,0,1,0,-1,1.99635052582,-0.997644673977,1,0,0,0,0},
},
{
.width = 600,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7204702079685,0,0,0,0,1,-1.992051337287,1,1.991724735993,-0.9976286495591,0.7421347431752,0,0,0,0,1,-1.991183936653,1,1.989907086576,-0.9952456951636,0.604919475437,0,0,0,0,1,-1.98916314981,1,1.987292353191,-0.9916644078999,0.4031176191874,0,0,0,0,1,-1.983858555024,1,1.983737890091,-0.9867199977999,0.1852276391821,0,0,0,0,1,-1.964098595732,1,1.979799018669,-0.9812116067047,0.04173451294799,0,0,0,0,1,-1.730957907744,1,1.977017596602,-0.9773147850232,0.00104222641555,0,0,0,0,1,-1.992386732821,1,1.993128969233,-0.999287596953,1,0,0,0,0},
},
{
.width = 600, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001284585786447,0,0,0,0,1,0,-1,1.995890881647,-0.9974308284271,1,0,0,0,0},
},
{
.width = 650,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7204629582723,0,0,0,0,1,-1.990672916305,1,1.990504046804,-0.9974317205332,0.7420997201468,0,0,0,0,1,-1.989655484775,1,1.988587384469,-0.9948512586532,0.6048790941635,0,0,0,0,1,-1.987285467683,1,1.985844571543,-0.9909738221192,0.4031248162113,0,0,0,0,1,-1.98106611745,1,1.982123805535,-0.9856218743413,0.1853599576003,0,0,0,0,1,-1.957923829211,1,1.978004553417,-0.9796612784204,0.04218198046103,0,0,0,0,1,-1.687842326134,1,1.975097196968,-0.975445708606,0.001042261313204,0,0,0,0,1,-1.991066344448,1,1.992001414299,-0.9992283905322,1,0,0,0,0},
},
{
.width = 650, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001391485679541,0,0,0,0,1,0,-1,1.995409963756,-0.9972170286409,1,0,0,0,0},
},
{
.width = 700,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7204608374967,0,0,0,0,1,-1.989184737884,1,1.989201941615,-0.997234933398,0.7420736963727,0,0,0,0,1,-1.988005458472,1,1.987194400975,-0.9944571544889,0.6048523474207,0,0,0,0,1,-1.985258802999,1,1.984337356487,-0.9902839338306,0.403150449675,0,0,0,0,1,-1.978053560366,1,1.980470203241,-0.9845251052012,0.1855142929409,0,0,0,0,1,-1.951274185804,1,1.976193094456,-0.9781132427738,0.04266769078477,0,0,0,0,1,-1.642366288879,1,1.9731758376,-0.9735797190357,0.001042301473633,0,0,0,0,1,-1.989640776319,1,1.990788692891,-0.9991692206202,1,0,0,0,0},
},
{
.width = 700, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001498362698778,0,0,0,0,1,0,-1,1.99490778184,-0.9970032746024,1,0,0,0,0},
},
{
.width = 750,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7204638443945,0,0,0,0,1,-1.987586920891,1,1.987818493681,-0.9970382959918,0.7420566684368,0,0,0,0,1,-1.986234019206,1,1.985728218548,-0.9940633959286,0.6048392250815,0,0,0,0,1,-1.983083438794,1,1.982770790904,-0.9895947589406,0.4031944970061,0,0,0,0,1,-1.974821633363,1,1.978777146333,-0.9834296988519,0.1856906093788,0,0,0,0,1,-1.944153976023,1,1.974364657107,-0.976567484639,0.04319157638077,0,0,0,0,1,-1.594735777206,1,1.971253483906,-0.9717167746503,0.001042346894657,0,0,0,0,1,-1.988110132376,1,1.989490864345,-0.9991100897426,1,0,0,0,0},
},
{
.width = 750, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001605216852135,0,0,0,0,1,0,-1,1.994384345814,-0.9967895662957,1,0,0,0,0},
},
{
.width = 800,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.720471977528,0,0,0,0,1,-1.985879592896,1,1.986353779246,-0.9968418161432,0.7420486326976,0,0,0,0,1,-1.984341340221,1,1.984188921422,-0.9936699962079,0.6048397169624,0,0,0,0,1,-1.980759678604,1,1.981144957841,-0.9889063133199,0.4032569361186,0,0,0,0,1,-1.971371139242,1,1.977044696816,-0.9823356637484,0.1858888724372,0,0,0,0,1,-1.93656779404,1,1.972519255598,-0.9750239889809,0.0437535730025,0,0,0,0,1,-1.545157991834,1,1.969330101199,-0.9698568340382,0.001042397573873,0,0,0,0,1,-1.986474524189,1,1.988107991613,-0.9990510004227,1,0,0,0,0},
},
{
.width = 800, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001712048147584,0,0,0,0,1,0,-1,1.993839665819,-0.9965759037048,1,0,0,0,0},
},
{
.width = 850,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7204852352697,0,0,0,0,1,-1.984062890156,1,1.98480787754,-0.9966455016707,0.7420495852893,0,0,0,0,1,-1.98232760651,1,1.982576595597,-0.9932769685399,0.6048538128248,0,0,0,0,1,-1.97828784636,1,1.979459940513,-0.9882186128049,0.4033377454126,0,0,0,0,1,-1.967702933531,1,1.975272915576,-0.9812430083297,0.1861090489832,0,0,0,0,1,-1.928520510423,1,1.970656903068,-0.9734827408562,0.0443536196807,0,0,0,0,1,-1.493839488122,1,1.967405654688,-0.9679998560349,0.001042453508653,0,0,0,0,1,-1.984734070936,1,1.986640141262,-0.9989919551816,1,0,0,0,0},
},
{
.width = 850, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001818856593095,0,0,0,0,1,0,-1,1.993273752219,-0.9963622868138,1,0,0,0,0},
},
{
.width = 900,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205036158022,0,0,0,0,1,-1.98213695759,1,1.983180870771,-0.9964493603827,0.7420595221218,0,0,0,0,1,-1.980193014772,1,1.980891328841,-0.9928843261151,0.6048815023758,0,0,0,0,1,-1.975668286282,1,1.977715822298,-0.9875316731982,0.403436903774,0,0,0,0,1,-1.963817923963,1,1.973461862386,-0.9801517410209,0.1863511072234,0,0,0,0,1,-1.920017264481,1,1.968777611568,-0.9719437254133,0.0449916587093,0,0,0,0,1,-1.440984462172,1,1.965480109483,-0.9661457997193,0.001042514696144,0,0,0,0,1,-1.982888899384,1,1.985087383472,-0.9989329565383,1,0,0,0,0},
},
{
.width = 900, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.001925642196633,0,0,0,0,1,0,-1,1.992686615605,-0.9961487156067,1,0,0,0,0},
},
{
.width = 950,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205271171187,0,0,0,0,1,-1.980101948756,1,1.981472844121,-0.9962534000772,0.7420784388822,0,0,0,0,1,-1.977937773369,1,1.979133210681,-0.9924920821014,0.6049227752688,0,0,0,0,1,-1.972901362771,1,1.975912686735,-0.9868455102693,0.403554390574,0,0,0,0,1,-1.959717069935,1,1.971611595912,-0.979061870235,0.1866150166993,0,0,0,0,1,-1.911063456245,1,1.966881392071,-0.9704069278933,0.04566763563196,0,0,0,0,1,-1.386793204296,1,1.96355343059,-0.96429462441,0.001042581133273,0,0,0,0,1,-1.980939143872,1,1.983449792026,-0.9988740070091,1,0,0,0,0},
},
{
.width = 950, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.00203240496616,0,0,0,0,1,0,-1,1.992078266787,-0.9959351900677,1,0,0,0,0},
},
{
.width = 1000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.7205557370232,0,0,0,0,1,-1.977958025827,1,1.979683885735,-0.9960576285415,0.7421063310346,0,0,0,0,1,-1.975562102286,1,1.977302332398,-0.9921002496442,0.6049776211049,0,0,0,0,1,-1.969987460285,1,1.974050617525,-0.9861601397558,0.4036901856686,0,0,0,0,1,-1.955401381923,1,1.96972217371,-0.9779734043745,0.1869007482833,0,0,0,0,1,-1.90166473813,1,1.964968254472,-0.9688723336301,0.04638149922917,0,0,0,0,1,-1.331460730689,1,1.961625582906,-0.9624462896615,0.001042652816742,0,0,0,0,1,-1.978884946296,1,1.981727444308,-0.998815109108,1,0,0,0,0},
},
{
.width = 1000, //gauss Q30
.type = IIR_BIQUAD_LPF_GAUSS,
.stages = 3,
.coeffs = (float32_t[]){0.002139144909634,0,0,0,0,1,0,-1,1.991448716805,-0.9957217101807,1,0,0,0,0},
},
{
.width = 1400,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.008337759067718, 0, 0, 0, 0, 1, 2, 1, 1.962488019523, -0.9958390557937, 0.007506676076303, 0, 0, 0, 0, 1, 2, 1, 1.957738871263, -0.9877655755683, 0.006043957858058, 0, 0, 0, 0, 1, 2, 1, 1.956161255776, -0.9803370872084, 0.004235277493261, 0, 0, 0, 0, 1, 2, 1, 1.956962928023, -0.9739040379958, 0.002433354390642, 0, 0, 0, 0, 1, 2, 1, 1.959042241511, -0.9687756590733, 0.0009906129953076, 0, 0, 0, 0, 1, 2, 1, 1.961242450501, -0.9652049024823, 0.00019040061388, 0, 0, 0, 0, 1, 2, 1, 1.962610750926, -0.9633723533813, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 1600,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.01087767183753, 0, 0, 0, 0, 1, 2, 1, 1.951743475923, -0.9952541632731, 0.009790251369373, 0, 0, 0, 0, 1, 2, 1, 1.946889322437, -0.9860503279146, 0.007881911933017, 0, 0, 0, 0, 1, 2, 1, 1.946054588275, -0.9775822360066, 0.005523739386766, 0, 0, 0, 0, 1, 2, 1, 1.948150114001, -0.9702450715483, 0.003174223932421, 0, 0, 0, 0, 1, 2, 1, 1.951694105105, -0.9643910008345, 0.001292461661961, 0, 0, 0, 0, 1, 2, 1, 1.955141533597, -0.9603113802446, 0.0002484458717897, 0, 0, 0, 0, 1, 2, 1, 1.957222530892, -0.9582163143789, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 1800,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.01374975760108, 0, 0, 0, 0, 1, 2, 1, 1.939673816033, -0.9946728464377, 0.01237165909396, 0, 0, 0, 0, 1, 2, 1, 1.934859504021, -0.9843461403965, 0.00995992424776, 0, 0, 0, 0, 1, 2, 1, 1.935004390016, -0.9748440870071, 0.006981215584571, 0, 0, 0, 0, 1, 2, 1, 1.938680240252, -0.96660510259, 0.004012807567963, 0, 0, 0, 0, 1, 2, 1, 1.943973272573, -0.960024502845, 0.001634314057146, 0, 0, 0, 0, 1, 2, 1, 1.948896382515, -0.9554336387438, 0.0003142054006989, 0, 0, 0, 0, 1, 2, 1, 1.951817350883, -0.9530741724857, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 2100,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.0186757712085, 0, 0, 0, 0, 1, 2, 1, 1.919105345061, -0.9938084298953, 0.01679782577699, 0, 0, 0, 0, 1, 2, 1, 1.914621379821, -0.9818126829289, 0.01352433909839, 0, 0, 0, 0, 1, 2, 1, 1.916673090488, -0.9707704468821, 0.009483344041549, 0, 0, 0, 0, 1, 2, 1, 1.923248669381, -0.9611820455475, 0.005453911681508, 0, 0, 0, 0, 1, 2, 1, 1.931692622294, -0.9535082690199, 0.002222306584324, 0, 0, 0, 0, 1, 2, 1, 1.939254929475, -0.948144155812, 0.0004273708029279, 0, 0, 0, 0, 1, 2, 1, 1.943673846642, -0.9453833298533, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 2300,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.02236805492097, 0, 0, 0, 0, 1, 2, 1, 1.903765535654, -0.9932377553382, 0.02011484257157, 0, 0, 0, 0, 1, 2, 1, 1.899680932944, -0.9801403032298, 0.01619704186404, 0, 0, 0, 0, 1, 2, 1, 1.903290409888, -0.9680785773444, 0.01136147999554, 0, 0, 0, 0, 1, 2, 1, 1.91214621026, -0.9575921302427, 0.006536937451987, 0, 0, 0, 0, 1, 2, 1, 1.92303837058, -0.9491861203884, 0.002664657794376, 0, 0, 0, 0, 1, 2, 1, 1.932642344124, -0.9433009753017, 0.0005125568415544, 0, 0, 0, 0, 1, 2, 1, 1.938218356086, -0.9402685834517, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 2500,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.02638375826711, 0, 0, 0, 0, 1, 2, 1, 1.887136976642, -0.9926720097103, 0.023722179526, 0, 0, 0, 0, 1, 2, 1, 1.883593567933, -0.9784822860373, 0.01910539136227, 0, 0, 0, 0, 1, 2, 1, 1.888985449532, -0.9654070149807, 0.0134072873595, 0, 0, 0, 0, 1, 2, 1, 1.900394125441, -0.9540232748791, 0.007718006483406, 0, 0, 0, 0, 1, 2, 1, 1.914009303952, -0.9448813298853, 0.003147525588083, 0, 0, 0, 0, 1, 2, 1, 1.925879604901, -0.9384697072535, 0.0006055973457388, 0, 0, 0, 0, 1, 2, 1, 1.932739506253, -0.9351618956361, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 2700,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.03071990044993, 0, 0, 0, 0, 1, 2, 1, 1.869231969467, -0.9921115712663, 0.02761740656234, 0, 0, 0, 0, 1, 2, 1, 1.866369928111, -0.9768395543603, 0.02224808606729, 0, 0, 0, 0, 1, 2, 1, 1.873764434848, -0.9627567791176, 0.01562051628912, 0, 0, 0, 0, 1, 2, 1, 1.887994019063, -0.9504760842192, 0.008997387142466, 0, 0, 0, 0, 1, 2, 1, 1.904604155312, -0.9405937038814, 0.003671160986692, 0, 0, 0, 0, 1, 2, 1, 1.918964639434, -0.9336492833803, 0.0007065561783843, 0, 0, 0, 0, 1, 2, 1, 1.927235402943, -0.9300616276564, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 2900,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.03537329213245, 0, 0, 0, 0, 1, 2, 1, 1.850063645572, -0.9915568141019, 0.03179797016664, 0, 0, 0, 0, 1, 2, 1, 1.848021141171, -0.9752130218375, 0.02562380547135, 0, 0, 0, 0, 1, 2, 1, 1.857633663767, -0.9601288856525, 0.01800097496312, 0, 0, 0, 0, 1, 2, 1, 1.874947272759, -0.9469511726113, 0.01037542521106, 0, 0, 0, 0, 1, 2, 1, 1.894821365712, -0.9363230665567, 0.004235862132326, 0, 0, 0, 0, 1, 2, 1, 1.911895202355, -0.9288386508847, 0.0008155080256104, 0, 0, 0, 0, 1, 2, 1, 1.92170411798, -0.9249661500829, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 3000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.0378179035225, 0, 0, 0, 0, 1, 2, 1, 1.840010067621, -0.991281681711, 0.03399442178565, 0, 0, 0, 0, 1, 2, 1, 1.838428426034, -0.9744061131769, 0.02739863142844, 0, 0, 0, 0, 1, 2, 1, 1.849229108307, -0.9588236340205, 0.01925387115406, 0, 0, 0, 0, 1, 2, 1, 1.868181781801, -0.9451972664171, 0.01110157002227, 0, 0, 0, 0, 1, 2, 1, 1.889787788767, -0.9341940688557, 0.004533718545948, 0, 0, 0, 0, 1, 2, 1, 1.908301807349, -0.9264366815325, 0.0008730076728553, 0, 0, 0, 0, 1, 2, 1, 1.918927669868, -0.9224197005598, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 3200,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.04294074008438, 0, 0, 0, 0, 1, 2, 1, 1.818973177899, -0.9907361382365, 0.03859793564407, 0, 0, 0, 0, 1, 2, 1, 1.818413829065, -0.9728055716408, 0.03112136875327, 0, 0, 0, 0, 1, 2, 1, 1.831745678148, -0.9562311531615, 0.0218849394564, 0, 0, 0, 0, 1, 2, 1, 1.854167192034, -0.9417069498599, 0.01262841216123, 0, 0, 0, 0, 1, 2, 1, 1.879434978023, -0.9299486266681, 0.005160681770831, 0, 0, 0, 0, 1, 2, 1, 1.900996067857, -0.9216387949399, 0.0009941132114779, 0, 0, 0, 0, 1, 2, 1, 1.913351916063, -0.9173283689091, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 3400,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.04837195881699, 0, 0, 0, 0, 1, 2, 1, 1.796709356328, -0.9901971915964, 0.04347987080713, 0, 0, 0, 0, 1, 2, 1, 1.797303988281, -0.9712234715099, 0.03507374176562, 0, 0, 0, 0, 1, 2, 1, 1.813368576892, -0.9536635439548, 0.02468300567677, 0, 0, 0, 0, 1, 2, 1, 1.839508477053, -0.93824049976, 0.01425511571928, 0, 0, 0, 0, 1, 2, 1, 1.868699356243, -0.9257198191201, 0.005829666089407, 0, 0, 0, 0, 1, 2, 1, 1.893529468422, -0.9168481327797, 0.001123447109388, 0, 0, 0, 0, 1, 2, 1, 1.90774399342, -0.9122377818571, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 3600,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.05410766292916, 0, 0, 0, 0, 1, 2, 1, 1.773234547842, -0.9896651995582, 0.04863725173841, 0, 0, 0, 0, 1, 2, 1, 1.775111685656, -0.9696606926092, 0.03925435731034, 0, 0, 0, 0, 1, 2, 1, 1.794104386414, -0.9511218156552, 0.02764807346692, 0, 0, 0, 0, 1, 2, 1, 1.824206281656, -0.9347985755237, 0.01598229875604, 0, 0, 0, 0, 1, 2, 1, 1.857578346955, -0.9215075419793, 0.006541139568672, 0, 0, 0, 0, 1, 2, 1, 1.885899135105, -0.9120636933801, 0.00126112358591, 0, 0, 0, 0, 1, 2, 1, 1.902101832716, -0.9071463270599, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 3800,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.06014376034101, 0, 0, 0, 0, 1, 2, 1, 1.748565473372, -0.9891405147361, 0.05406698488614, 0, 0, 0, 0, 1, 2, 1, 1.75185016527, -0.9681181048143, 0.04366179904764, 0, 0, 0, 0, 1, 2, 1, 1.773959780893, -0.9486069770836, 0.03078019985087, 0, 0, 0, 0, 1, 2, 1, 1.808261053311, -0.9313818527144, 0.01781065782937, 0, 0, 0, 0, 1, 2, 1, 1.846069082969, -0.9173117142862, 0.007295620714451, 0, 0, 0, 0, 1, 2, 1, 1.878102006143, -0.9072844890005, 0.001407268766049, 0, 0, 0, 0, 1, 2, 1, 1.896423317628, -0.9020523926923, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 4000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.0664759669061, 0, 0, 0, 0, 1, 2, 1, 1.722719616758, -0.9886234843822, 0.05976585969453, 0, 0, 0, 0, 1, 2, 1, 1.727533129144, -0.9665965679221, 0.04829462608705, 0, 0, 0, 0, 1, 2, 1, 1.752941532896, -0.9461200372446, 0.03407949397928, 0, 0, 0, 0, 1, 2, 1, 1.791673048598, -0.9279910245151, 0.0197409684492, 0, 0, 0, 0, 1, 2, 1, 1.834168405903, -0.9131322796994, 0.00809367952317, 0, 0, 0, 0, 1, 2, 1, 1.870134827536, -0.9025095456287, 0.001562021017125, 0, 0, 0, 0, 1, 2, 1, 1.890706281461, -0.8969543655294, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 4500,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.08357215221717, 0, 0, 0, 0, 1, 2, 1, 1.653078015998, -0.987366624867, 0.07516842731719, 0, 0, 0, 0, 1, 2, 1, 1.662216664048, -0.9628903733163, 0.06085305871942, 0, 0, 0, 0, 1, 2, 1, 1.696619139932, -0.9400313748092, 0.043060258968, 0, 0, 0, 0, 1, 2, 1, 1.747390932282, -0.9196319681538, 0.02501859112256, 0, 0, 0, 0, 1, 2, 1, 1.802680917653, -0.9027552821436, 0.01028369816962, 0, 0, 0, 0, 1, 2, 1, 1.849449766852, -0.8905845595302, 0.001987580597066, 0, 0, 0, 0, 1, 2, 1, 1.876230447368, -0.8841807697568, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 5000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.1024156725791, 0, 0, 0, 0, 1, 2, 1, 1.576502212425, -0.9861649027415, 0.09217691252119, 0, 0, 0, 0, 1, 2, 1, 1.590626367525, -0.9593340176097, 0.07478718663087, 0, 0, 0, 0, 1, 2, 1, 1.63499047411, -0.9341392206335, 0.0530907744763, 0, 0, 0, 0, 1, 2, 1, 1.699087884799, -0.9114509827042, 0.03095453675841, 0, 0, 0, 0, 1, 2, 1, 1.768662790286, -0.8924809373192, 0.01276135116726, 0, 0, 0, 0, 1, 2, 1, 1.827620197021, -0.8786656016897, 0.002470638805861, 0, 0, 0, 0, 1, 2, 1, 1.861463480239, -0.8713460354626, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 6000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.1450110967848, 0, 0, 0, 0, 1, 2, 1, 1.403901955866, -0.9839463430048, 0.1307691226309, 0, 0, 0, 0, 1, 2, 1, 1.429644184424, -0.9527206749475, 0.1066810357534, 0, 0, 0, 0, 1, 2, 1, 1.496284169193, -0.9230083122063, 0.07632499046678, 0, 0, 0, 0, 1, 2, 1, 1.590375038731, -0.8956750005979, 0.04487973895608, 0, 0, 0, 0, 1, 2, 1, 1.692728831788, -0.8722477876128, 0.01863599384496, 0, 0, 0, 0, 1, 2, 1, 1.780245937312, -0.8547899126915, 0.003623004541629, 0, 0, 0, 0, 1, 2, 1, 1.830897212635, -0.8453892308013, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 7000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.1935320872064, 0, 0, 0, 0, 1, 2, 1, 1.207875690811, -0.9820040396369, 0.1750141161592, 0, 0, 0, 0, 1, 2, 1, 1.246795349816, -0.9468518144529, 0.1437565297358, 0, 0, 0, 0, 1, 2, 1, 1.337830681316, -0.9128568002589, 0.1038445422874, 0, 0, 0, 0, 1, 2, 1, 1.465400321994, -0.8807784911441, 0.06170673134055, 0, 0, 0, 0, 1, 2, 1, 1.605636412052, -0.8524633374146, 0.02585632577245, 0, 0, 0, 0, 1, 2, 1, 1.727351325001, -0.8307766280909, 0.005053269625901, 0, 0, 0, 0, 1, 2, 1, 1.798655982283, -0.8188690607867, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 8000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.2471567962157, 0, 0, 0, 0, 1, 2, 1, 0.9917423657721, -0.9803695506349, 0.224315091642, 0, 0, 0, 0, 1, 2, 1, 1.044554840447, -0.9418152070148, 0.1857606943562, 0, 0, 0, 0, 1, 2, 1, 1.160774872447, -0.9038176498723, 0.1357293808017, 0, 0, 0, 0, 1, 2, 1, 1.323981745373, -0.8668992685794, 0.0816816657689, 0, 0, 0, 0, 1, 2, 1, 1.506461203918, -0.8331878669936, 0.0346084620725, 0, 0, 0, 0, 1, 2, 1, 1.668097114322, -0.8065309626121, 0.006808262659746, 0, 0, 0, 0, 1, 2, 1, 1.764321649588, -0.7915547002269, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 9000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.3049851455408, 0, 0, 0, 0, 1, 2, 1, 0.7591287465444, -0.9790693287075, 0.2780078711753, 0, 0, 0, 0, 1, 2, 1, 0.8256589275237, -0.9376904122248, 0.2323960275367, 0, 0, 0, 0, 1, 2, 1, 0.9664437350711, -0.8960278452179, 0.1720665990118, 0, 0, 0, 0, 1, 2, 1, 1.165936151782, -0.8542025478295, 0.1051104068231, 0, 0, 0, 0, 1, 2, 1, 1.394079028152, -0.8145206554444, 0.04513708899945, 0, 0, 0, 0, 1, 2, 1, 1.601425033622, -0.78197338962, 0.008951452064989, 0, 0, 0, 0, 1, 2, 1, 1.727386349532, -0.7631921577923, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 10000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.3660530366546, 0, 0, 0, 0, 1, 2, 1, 0.5139122219498, -0.9781243685681, 0.3353618895079, 0, 0, 0, 0, 1, 2, 1, 0.5931003386238, -0.9345478966556, 0.2833072224337, 0, 0, 0, 0, 1, 2, 1, 0.7563993155832, -0.889628205318, 0.2129361875021, 0, 0, 0, 0, 1, 2, 1, 0.9911412275405, -0.8428859775489, 0.1323619182589, 0, 0, 0, 0, 1, 2, 1, 1.267164478707, -0.7966121517422, 0.0577608794396, 0, 0, 0, 0, 1, 2, 1, 1.526003705736, -0.7570472234945, 0.01156881757925, 0, 0, 0, 0, 1, 2, 1, 1.687220763409, -0.7334960337262, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 15000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.6836575636023, 0, 0, 0, 0, 1, 2, 1, -0.7555775647369, -0.9790526896722, 0.647099990577, 0, 0, 0, 0, 1, 2, 1, -0.6531521361674, -0.9352478261406, 0.5835442055703, 0, 0, 0, 0, 1, 2, 1, -0.4507362158414, -0.8834406064397, 0.4845398400426, 0, 0, 0, 0, 1, 2, 1, -0.1214617070015, -0.816697653169, 0.343041904988, 0, 0, 0, 0, 1, 2, 1, 0.3575721235141, -0.729739743466, 0.1720099445637, 0, 0, 0, 0, 1, 2, 1, 0.9410108109328, -0.6290505891876, 0.03796886246342, 0, 0, 0, 0, 1, 2, 1, 1.399673185533, -0.5515486353869, 0.8912509381337, 0, 0, 0, 0},
},
{
.width = 20000,
.type = IIR_BIQUAD_LPF,
.stages = 15,
.coeffs = (float32_t[]){0.9275653605469, 0, 0, 0, 0, 1, 2, 1, -1.721658533587, -0.9886029086012, 0.9093240243363, 0, 0, 0, 0, 1, 2, 1, -1.673785057778, -0.9635110395671, 0.8781513561579, 0, 0, 0, 0, 1, 2, 1, -1.582945488801, -0.9296599358312, 0.8220243799729, 0, 0, 0, 0, 1, 2, 1, -1.41280229903, -0.8752952208621, 0.712966251766, 0, 0, 0, 0, 1, 2, 1, -1.07711451342, -0.7747504936445, 0.4918611014088, 0, 0, 0, 0, 1, 2, 1, -0.3928110912436, -0.5746333143917, 0.1540100983629, 0, 0, 0, 0, 1, 2, 1, 0.6545074245328, -0.2705478179843, 0.8912509381337, 0, 0, 0, 0},
},
};
//Public variables
const uint32_t AUTIO_FILTERS_HPF_CW_LIST[CW_HPF_COUNT] = {0, 60, 100};
const uint32_t AUTIO_FILTERS_HPF_SSB_LIST[SSB_HPF_COUNT] = {0, 60, 100, 200, 300, 400, 500};
const uint32_t AUTIO_FILTERS_LPF_CW_LIST[CW_LPF_COUNT] = {100, 150, 200, 250, 300, 350, 400, 450, 500, 550, 600, 650, 700, 750, 800, 850, 900, 950, 1000};
const uint32_t AUTIO_FILTERS_LPF_SSB_LIST[SSB_LPF_COUNT] = {1400, 1600, 1800, 2100, 2300, 2500, 2700, 2900, 3000, 3200, 3400};
const uint32_t AUTIO_FILTERS_LPF_AM_LIST[AM_LPF_COUNT] = {2100, 2300, 2500, 2700, 2900, 3000, 3200, 3400, 3600, 3800, 4000, 4500, 5000, 6000, 7000, 8000, 9000, 10000};
const uint32_t AUTIO_FILTERS_LPF_NFM_LIST[NFM_LPF_COUNT] = {5000, 6000, 7000, 8000, 9000, 10000, 15000, 20000};
arm_fir_instance_f32 FIR_RX_Hilbert_I; // filter instances
arm_fir_instance_f32 FIR_RX_Hilbert_Q;
arm_fir_instance_f32 FIR_TX_Hilbert_I;
arm_fir_instance_f32 FIR_TX_Hilbert_Q;
arm_biquad_cascade_df2T_instance_f32 IIR_RX_LPF_I;
arm_biquad_cascade_df2T_instance_f32 IIR_RX_LPF_Q;
arm_biquad_cascade_df2T_instance_f32 IIR_RX_GAUSS;
arm_biquad_cascade_df2T_instance_f32 IIR_TX_LPF_I;
arm_biquad_cascade_df2T_instance_f32 IIR_RX_HPF_I;
arm_biquad_cascade_df2T_instance_f32 IIR_TX_HPF_I;
arm_biquad_cascade_df2T_instance_f32 IIR_RX_Squelch_HPF;
arm_biquad_cascade_df2T_instance_f32 EQ_RX_LOW_FILTER = {EQ_STAGES, EQ_RX_LOW_FILTER_State, EQ_RX_LOW_FILTER_Coeffs};
arm_biquad_cascade_df2T_instance_f32 EQ_RX_MID_FILTER = {EQ_STAGES, EQ_RX_MID_FILTER_State, EQ_RX_MID_FILTER_Coeffs};
arm_biquad_cascade_df2T_instance_f32 EQ_RX_HIG_FILTER = {EQ_STAGES, EQ_RX_HIG_FILTER_State, EQ_RX_HIG_FILTER_Coeffs};
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};
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
// Prototypes
static void calcBiquad(BIQUAD_TYPE type, uint32_t Fc, uint32_t Fs, float32_t Q, float32_t peakGain, float32_t *outCoeffs); // automatic calculation of the Biquad filter for Notch
static IIR_BIQUAD_FILTER *getIIRFilter(IIR_BIQUAD_FILTER_TYPE type, uint_fast16_t width); // get filter from collection
static void arm_biquad_cascade_df2T_initNoClean_f32(arm_biquad_cascade_df2T_instance_f32 * S, uint8_t numStages, const float32_t * pCoeffs, float32_t * pState); //init without state-clean version
// initialize audio filters
void InitAudioFilters(void)
{
arm_fir_init_f32(&FIR_RX_Hilbert_I, IQ_HILBERT_TAPS, (float32_t *)&FIR_HILB_I_coeffs, (float32_t *)&Fir_RX_Hilbert_State_I[0], AUDIO_BUFFER_HALF_SIZE);
arm_fir_init_f32(&FIR_RX_Hilbert_Q, IQ_HILBERT_TAPS, (float32_t *)&FIR_HILB_Q_coeffs, (float32_t *)&Fir_RX_Hilbert_State_Q[0], AUDIO_BUFFER_HALF_SIZE);
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);
//Other
InitAutoNotchReduction();
ReinitAudioFilters();
}
// reinitialize audio filters
void ReinitAudioFilters(void)
{
//LPF
uint32_t lpf1_width = 2700; //default settings
if (CurrentVFO()->LPF_Filter_Width > 0)
lpf1_width = CurrentVFO()->LPF_Filter_Width;
IIR_BIQUAD_FILTER *lpf_filter = getIIRFilter(IIR_BIQUAD_LPF, lpf1_width);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_RX_LPF_I, lpf_filter->stages, (float32_t *)lpf_filter->coeffs, (float32_t *)&IIR_RX_LPF_I_State[0]);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_RX_LPF_Q, lpf_filter->stages, (float32_t *)lpf_filter->coeffs, (float32_t *)&IIR_RX_LPF_Q_State[0]);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_TX_LPF_I, lpf_filter->stages, (float32_t *)lpf_filter->coeffs, (float32_t *)&IIR_TX_LPF_I_State[0]);
//RX GAUSS
IIR_BIQUAD_FILTER *gauss_filter = getIIRFilter(IIR_BIQUAD_LPF_GAUSS, 1000);
if (CurrentVFO()->Mode == TRX_MODE_CW_L || CurrentVFO()->Mode == TRX_MODE_CW_U)
gauss_filter = getIIRFilter(IIR_BIQUAD_LPF_GAUSS, lpf1_width);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_RX_GAUSS, gauss_filter->stages, (float32_t *)gauss_filter->coeffs, (float32_t *)&IIR_RX_GAUSS_State[0]);
//HPF
uint32_t hpf1_width = 300; //default settings
if (CurrentVFO()->HPF_Filter_Width > 0)
hpf1_width = CurrentVFO()->HPF_Filter_Width;
IIR_BIQUAD_FILTER *hpf_filter = getIIRFilter(IIR_BIQUAD_HPF, hpf1_width);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_RX_HPF_I, hpf_filter->stages, (float32_t *)hpf_filter->coeffs, (float32_t *)&IIR_RX_HPF_I_State[0]);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_TX_HPF_I, hpf_filter->stages, (float32_t *)hpf_filter->coeffs, (float32_t *)&IIR_TX_HPF_I_State[0]);
//FM Squelch
IIR_BIQUAD_FILTER *fm_sql_hpf_filter;
if (CurrentVFO()->LPF_Filter_Width > 15000 || CurrentVFO()->LPF_Filter_Width == 0)
fm_sql_hpf_filter = getIIRFilter(IIR_BIQUAD_HPF, 20000);
else
fm_sql_hpf_filter = getIIRFilter(IIR_BIQUAD_HPF, 15000);
arm_biquad_cascade_df2T_initNoClean_f32(&IIR_RX_Squelch_HPF, fm_sql_hpf_filter->stages, (float32_t *)fm_sql_hpf_filter->coeffs, (float32_t *)&IIR_RX_HPF_SQL_State[0]);
//RX Equalizer
calcBiquad(BIQUAD_peak, 400, TRX_SAMPLERATE, 0.5f, TRX.RX_EQ_LOW, EQ_RX_LOW_FILTER_Coeffs);
calcBiquad(BIQUAD_peak, 1000, TRX_SAMPLERATE, 1.0f, TRX.RX_EQ_MID, EQ_RX_MID_FILTER_Coeffs);
calcBiquad(BIQUAD_peak, 2000, TRX_SAMPLERATE, 1.5f, TRX.RX_EQ_HIG, EQ_RX_HIG_FILTER_Coeffs);
//MIC Equalizer
calcBiquad(BIQUAD_peak, 400, TRX_SAMPLERATE, 0.5f, TRX.MIC_EQ_LOW, EQ_MIC_LOW_FILTER_Coeffs);
calcBiquad(BIQUAD_peak, 1000, TRX_SAMPLERATE, 1.0f, TRX.MIC_EQ_MID, EQ_MIC_MID_FILTER_Coeffs);
calcBiquad(BIQUAD_peak, 2000, TRX_SAMPLERATE, 1.5f, TRX.MIC_EQ_HIG, EQ_MIC_HIG_FILTER_Coeffs);
//All done
NeedReinitAudioFilters = false;
NeedReinitAudioFiltersClean = false;
}
// start DC corrector
void dc_filter(float32_t *Buffer, int16_t blockSize, DC_FILTER_STATE stateNum) // removes the constant component of the signal
{
static const float32_t A1 = (1.0f - 0.00048828125f); // (1-2^(-11))
for (uint16_t i = 0; i < blockSize; i++)
{
float32_t sampleIn = Buffer[i];
float32_t sampleOut = 0;
float32_t delta_x = sampleIn - DC_Filter_State[stateNum].x_prev;
float32_t a1_y_prev = A1 * DC_Filter_State[stateNum].y_prev;
sampleOut = delta_x + a1_y_prev;
DC_Filter_State[stateNum].x_prev = sampleIn;
DC_Filter_State[stateNum].y_prev = sampleOut;
Buffer[i] = sampleOut;
}
}
// get filter from collection
static IIR_BIQUAD_FILTER *getIIRFilter(IIR_BIQUAD_FILTER_TYPE type, uint_fast16_t width)
{
for (uint16_t i = 0; i < IIR_FILTERS_COUNT; i++)
if (IIR_Biquad_Filters[i].type == type && IIR_Biquad_Filters[i].width == width)
return (IIR_BIQUAD_FILTER *)&IIR_Biquad_Filters[i];
sendToDebug_strln("Wrong filter length");
sendToDebug_uint16(type, false);
sendToDebug_uint16((uint16_t)width, false);
return (IIR_BIQUAD_FILTER *)&IIR_Biquad_Filters[0];
}
// automatic calculation of the Biquad filter
static void calcBiquad(BIQUAD_TYPE type, uint32_t Fc, uint32_t Fs, float32_t Q, float32_t peakGain, float32_t *outCoeffs)
{
float32_t a0, a1, a2, b1, b2, norm;
float32_t V = powf(10.0f, fabsf(peakGain) / 20.0f);
float32_t K = tanf(PI * Fc / Fs);
switch (type)
{
case BIQUAD_onepolelp:
b1 = expf(-2.0f * PI * (Fc / Fs));
a0 = 1.0f - b1;
b1 = -b1;
a1 = a2 = b2 = 0.0f;
break;
case BIQUAD_onepolehp:
b1 = -expf(-2.0f * PI * (0.5f - Fc / Fs));
a0 = 1.0f + b1;
b1 = -b1;
a1 = a2 = b2 = 0.0f;
break;
case BIQUAD_lowpass:
norm = 1.0f / (1.0f + K / Q + K * K);
a0 = K * K * norm;
a1 = 2.0f * a0;
a2 = a0;
b1 = 2.0f * (K * K - 1.0f) * norm;
b2 = (1.0f - K / Q + K * K) * norm;
break;
case BIQUAD_highpass:
norm = 1.0f / (1.0f + K / Q + K * K);
a0 = 1.0f * norm;
a1 = -2.0f * a0;
a2 = a0;
b1 = 2.0f * (K * K - 1.0f) * norm;
b2 = (1.0f - K / Q + K * K) * norm;
break;
case BIQUAD_bandpass:
norm = 1.0f / (1.0f + K / Q + K * K);
a0 = K / Q * norm;
a1 = 0.0f;
a2 = -a0;
b1 = 2.0f * (K * K - 1.0f) * norm;
b2 = (1.0f - K / Q + K * K) * norm;
break;
case BIQUAD_notch:
norm = 1.0f / (1.0f + K / Q + K * K);
a0 = (1.0f + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = a0;
b1 = a1;
b2 = (1.0f - K / Q + K * K) * norm;
break;
case BIQUAD_peak:
if (peakGain >= 0.0f)
{
norm = 1.0f / (1.0f + 1.0f / Q * K + K * K);
a0 = (1.0f + V / Q * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - V / Q * K + K * K) * norm;
b1 = a1;
b2 = (1.0f - 1.0f / Q * K + K * K) * norm;
}
else
{
norm = 1.0f / (1.0f + V / Q * K + K * K);
a0 = (1.0f + 1.0f / Q * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - 1.0f / Q * K + K * K) * norm;
b1 = a1;
b2 = (1.0f - V / Q * K + K * K) * norm;
}
break;
case BIQUAD_lowShelf:
if (peakGain >= 0.0f)
{
norm = 1.0f / (1.0f + SQRT2 * K + K * K);
a0 = (1.0f + sqrtf(2.0f * V) * K + V * K * K) * norm;
a1 = 2.0f * (V * K * K - 1.0f) * norm;
a2 = (1.0f - sqrtf(2.0f * V) * K + V * K * K) * norm;
b1 = 2.0f * (K * K - 1.0f) * norm;
b2 = (1.0f - SQRT2 * K + K * K) * norm;
}
else
{
norm = 1.0f / (1.0f + sqrtf(2.0f * V) * K + V * K * K);
a0 = (1.0f + SQRT2 * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - SQRT2 * K + K * K) * norm;
b1 = 2.0f * (V * K * K - 1.0f) * norm;
b2 = (1.0f - sqrtf(2.0f * V) * K + V * K * K) * norm;
}
break;
case BIQUAD_highShelf:
if (peakGain >= 0.0f)
{
norm = 1.0f / (1.0f + SQRT2 * K + K * K);
a0 = (V + sqrtf(2.0f * V) * K + K * K) * norm;
a1 = 2.0f * (K * K - V) * norm;
a2 = (V - sqrtf(2.0f * V) * K + K * K) * norm;
b1 = 2.0f * (K * K - 1.0f) * norm;
b2 = (1.0f - SQRT2 * K + K * K) * norm;
}
else
{
norm = 1.0f / (V + sqrtf(2.0f * V) * K + K * K);
a0 = (1.0f + SQRT2 * K + K * K) * norm;
a1 = 2.0f * (K * K - 1.0f) * norm;
a2 = (1.0f - SQRT2 * K + K * K) * norm;
b1 = 2.0f * (K * K - V) * norm;
b2 = (V - sqrtf(2.0f * V) * K + K * K) * norm;
}
break;
}
//save coefficients
outCoeffs[0] = a0;
outCoeffs[1] = a1;
outCoeffs[2] = a2;
outCoeffs[3] = -b1;
outCoeffs[4] = -b2;
}
static void arm_biquad_cascade_df2T_initNoClean_f32(arm_biquad_cascade_df2T_instance_f32 * S, uint8_t numStages, const float32_t * pCoeffs, float32_t * pState)
{
if(NeedReinitAudioFiltersClean) //original func
{
arm_biquad_cascade_df2T_init_f32(S, numStages, pCoeffs, pState);
return;
}
/* Assign filter stages */
S->numStages = numStages;
/* Assign coefficient pointer */
S->pCoeffs = pCoeffs;
/* Assign state pointer */
S->pState = pState;
}

Wyświetl plik

@ -1,111 +0,0 @@
#ifndef AUDIO_FILTERS_h
#define AUDIO_FILTERS_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "fpga.h"
#include "functions.h"
#define IIR_FILTERS_COUNT 69 // Total Filters In The Collection
#define IQ_HILBERT_TAPS 65 // Hilbert filter order
#define IIR_MAX_STAGES 15 // Maximum order of IIR filters
#define EQ_STAGES 1 // order of the biquad of the equalizer filter
#define BIQUAD_COEFF_IN_STAGE 5 // coefficients in manual Notch filter order
#define FIR_RX_HILBERT_STATE_SIZE (IQ_HILBERT_TAPS + AUDIO_BUFFER_HALF_SIZE - 1) // size of state buffers
#define FIR_TX_HILBERT_STATE_SIZE (IQ_HILBERT_TAPS + AUDIO_BUFFER_HALF_SIZE - 1)
#define IIR_RX_LPF_Taps_STATE_SIZE (IIR_MAX_STAGES * 2)
#define IIR_RX_GAUSS_Taps_STATE_SIZE (IIR_MAX_STAGES * 2)
#define IIR_TX_LPF_Taps_STATE_SIZE (IIR_MAX_STAGES * 2)
#define IIR_RX_HPF_Taps_STATE_SIZE (IIR_MAX_STAGES * 2)
#define IIR_TX_HPF_Taps_STATE_SIZE (IIR_MAX_STAGES * 2)
#define IIR_RX_HPF_SQL_STATE_SIZE (IIR_MAX_STAGES * 2)
#define CW_HPF_COUNT 3
#define SSB_HPF_COUNT 7
#define CW_LPF_COUNT 19
#define SSB_LPF_COUNT 11
#define AM_LPF_COUNT 18
#define NFM_LPF_COUNT 8
#define MAX_HPF_WIDTH_CW 100
#define MAX_HPF_WIDTH_SSB 500
#define MAX_LPF_WIDTH_CW 1000
#define MAX_LPF_WIDTH_SSB 3400
#define MAX_LPF_WIDTH_AM 10000
#define MAX_LPF_WIDTH_NFM 20000
typedef enum // BiQuad filter type for automatic calculation
{
BIQUAD_onepolelp,
BIQUAD_onepolehp,
BIQUAD_lowpass,
BIQUAD_highpass,
BIQUAD_bandpass,
BIQUAD_notch,
BIQUAD_peak,
BIQUAD_lowShelf,
BIQUAD_highShelf
} BIQUAD_TYPE;
typedef enum // type of filter in the collection
{
IIR_BIQUAD_HPF,
IIR_BIQUAD_LPF,
IIR_BIQUAD_LPF_GAUSS
} IIR_BIQUAD_FILTER_TYPE;
typedef enum // states of DC correctors for each user
{
DC_FILTER_RX_I,
DC_FILTER_RX_Q,
DC_FILTER_TX_I,
DC_FILTER_TX_Q,
DC_FILTER_FFT_I,
DC_FILTER_FFT_Q,
} DC_FILTER_STATE;
typedef struct // keep old sample values for DC filter. Multiple states for different consumers
{
float32_t x_prev;
float32_t y_prev;
} DC_filter_state_type;
typedef struct // filter in collection
{
const IIR_BIQUAD_FILTER_TYPE type;
const float32_t *coeffs; // Coefficients converted to ARMA in reverse order by MATLAB
const uint8_t stages;
const uint16_t width;
} IIR_BIQUAD_FILTER;
// Public variables
extern arm_fir_instance_f32 FIR_RX_Hilbert_I; // filter instances
extern arm_fir_instance_f32 FIR_RX_Hilbert_Q;
extern arm_fir_instance_f32 FIR_TX_Hilbert_I;
extern arm_fir_instance_f32 FIR_TX_Hilbert_Q;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_LPF_I;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_LPF_Q;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_GAUSS;
extern arm_biquad_cascade_df2T_instance_f32 IIR_TX_LPF_I;
extern arm_biquad_cascade_df2T_instance_f32 IIR_TX_LPF_Q;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_HPF_I;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_HPF_Q;
extern arm_biquad_cascade_df2T_instance_f32 IIR_TX_HPF_I;
extern arm_biquad_cascade_df2T_instance_f32 IIR_TX_HPF_Q;
extern arm_biquad_cascade_df2T_instance_f32 IIR_RX_Squelch_HPF;
extern arm_biquad_cascade_df2T_instance_f32 EQ_RX_LOW_FILTER;
extern arm_biquad_cascade_df2T_instance_f32 EQ_RX_MID_FILTER;
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 volatile bool NeedReinitAudioFilters; // need to reinitialize the Audio filters
//Public methods
extern void InitAudioFilters(void); // initialize audio filters
extern void ReinitAudioFilters(void); // reinitialize audio filters
extern void dc_filter(float32_t *Buffer, int16_t blockSize, uint8_t stateNum); // start DC corrector
#endif

Wyświetl plik

@ -1,868 +0,0 @@
#include "audio_processor.h"
#include "wm8731.h"
#include "audio_filters.h"
#include "agc.h"
#include "settings.h"
#include "usbd_audio_if.h"
#include "auto_notch.h"
#include "trx_manager.h"
// Public variables
volatile uint32_t AUDIOPROC_samples = 0; // audio samples processed in the processor
IRAM1 int32_t Processor_AudioBuffer_A[AUDIO_BUFFER_SIZE] = {0}; // buffer A of the audio processor
IRAM1 int32_t Processor_AudioBuffer_B[AUDIO_BUFFER_SIZE] = {0}; // buffer B of the audio processor
volatile uint_fast8_t Processor_AudioBuffer_ReadyBuffer = 0; // which buffer is currently in use, A or B
volatile bool Processor_NeedRXBuffer = false; // codec needs data from processor for RX
volatile bool Processor_NeedTXBuffer = false; // codec needs data from processor for TX
IRAM1 float32_t FPGA_Audio_Buffer_RX_Q_tmp[FPGA_RX_IQ_BUFFER_HALF_SIZE] = {0}; // copy of the working part of the FPGA buffers for processing
IRAM1 float32_t FPGA_Audio_Buffer_RX_I_tmp[FPGA_RX_IQ_BUFFER_HALF_SIZE] = {0};
IRAM1 float32_t FPGA_Audio_Buffer_TX_Q_tmp[FPGA_TX_IQ_BUFFER_HALF_SIZE] = {0};
IRAM1 float32_t FPGA_Audio_Buffer_TX_I_tmp[FPGA_TX_IQ_BUFFER_HALF_SIZE] = {0};
volatile float32_t Processor_RX_Power_value; // RX signal magnitude
volatile float32_t Processor_selected_RFpower_amplitude = 0.0f; // target TX signal amplitude
volatile float32_t Processor_TX_MAX_amplitude_OUT; // TX uplift after ALC
// Private variables
static uint32_t two_signal_gen_position = 0; // signal position in a two-signal generator
static float32_t ALC_need_gain = 1.0f; // current gain of ALC and audio compressor
static float32_t ALC_need_gain_target = 1.0f; // Target Gain Of ALC And Audio Compressor
static float32_t DFM_RX_lpf_prev = 0, DFM_RX_hpf_prev_a = 0, DFM_RX_hpf_prev_b = 0; // used in FM detection and low / high pass processing
static float32_t DFM_RX_i_prev = 0, DFM_RX_q_prev = 0; // used in FM detection and low / high pass processing
static uint_fast8_t DFM_RX_fm_sql_count = 0; // used for squelch processing and debouncing tone detection, respectively
static float32_t DFM_RX_fm_sql_avg = 0.0f; // average SQL in FM
static bool DFM_RX_Squelched = false;
static float32_t current_if_gain = 0.0f;
static float32_t volume_gain = 0.0f;
// Prototypes
static void doRX_HILBERT(uint16_t size); // Hilbert filter for phase shift of signals
static void doRX_LPF_IQ(uint16_t size); // Low-pass filter for I and Q
static void doRX_LPF_I(uint16_t size); // LPF filter for I
static void doRX_GAUSS_I(uint16_t size); // Gauss filter for I
static void doRX_HPF_I(uint16_t size); // HPF filter for I
static void doRX_AGC(uint16_t size, uint_fast8_t mode); // automatic gain control
static void doRX_NOTCH(uint16_t size); // notch filter
static void doRX_SMETER(uint16_t size); // s-meter
static void doRX_COPYCHANNEL(uint16_t size); // copy I to Q channel
static void DemodulateFM(uint16_t size); // FM demodulator
static void ModulateFM(uint16_t size); // FM modulator
static void doRX_EQ(uint16_t size); // receiver equalizer
static void doMIC_EQ(uint16_t size); // microphone equalizer
static void doRX_IFGain(uint16_t size); //IF gain
// initialize audio processor
void initAudioProcessor(void)
{
InitAudioFilters();
}
// start audio processor for RX
void processRxAudio(void)
{
if (!Processor_NeedRXBuffer)
return;
VFO *current_vfo = CurrentVFO();
AUDIOPROC_samples++;
uint_fast16_t FPGA_Audio_Buffer_Index_tmp = FPGA_Audio_RXBuffer_Index;
if (FPGA_Audio_Buffer_Index_tmp == 0)
FPGA_Audio_Buffer_Index_tmp = FPGA_RX_IQ_BUFFER_SIZE;
else
FPGA_Audio_Buffer_Index_tmp--;
// copy buffer from FPGA
readFromCircleBuffer32((uint32_t *)&FPGA_Audio_Buffer_RX_Q[0], (uint32_t *)&FPGA_Audio_Buffer_RX_Q_tmp[0], FPGA_Audio_Buffer_Index_tmp, FPGA_RX_IQ_BUFFER_SIZE, FPGA_RX_IQ_BUFFER_HALF_SIZE);
readFromCircleBuffer32((uint32_t *)&FPGA_Audio_Buffer_RX_I[0], (uint32_t *)&FPGA_Audio_Buffer_RX_I_tmp[0], FPGA_Audio_Buffer_Index_tmp, FPGA_RX_IQ_BUFFER_SIZE, FPGA_RX_IQ_BUFFER_HALF_SIZE);
//Process DC corrector filter
if (current_vfo->Mode != TRX_MODE_AM && current_vfo->Mode != TRX_MODE_NFM && current_vfo->Mode != TRX_MODE_WFM)
{
dc_filter(FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE, DC_FILTER_RX_I);
dc_filter(FPGA_Audio_Buffer_RX_Q_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE, DC_FILTER_RX_Q);
}
//IQ Phase corrector https://github.com/df8oe/UHSDR/wiki/IQ---correction-and-mirror-frequencies
if(AUDIOPROC_samples == 1)
{
float32_t teta1_new = 0;
float32_t teta3_new = 0;
static float32_t teta1 = 0;
static float32_t teta3 = 0;
for (uint16_t i = 0; i < FPGA_RX_IQ_BUFFER_HALF_SIZE; i++)
{
teta1_new += FPGA_Audio_Buffer_RX_Q_tmp[i] * (FPGA_Audio_Buffer_RX_I_tmp[i] < 0.0f ? -1.0f : 1.0f);
teta3_new += FPGA_Audio_Buffer_RX_Q_tmp[i] * (FPGA_Audio_Buffer_RX_Q_tmp[i] < 0.0f ? -1.0f : 1.0f);
}
teta1_new = teta1_new / (float32_t)FPGA_RX_IQ_BUFFER_HALF_SIZE;
teta3_new = teta3_new / (float32_t)FPGA_RX_IQ_BUFFER_HALF_SIZE;
teta1 = 0.003f * teta1_new + 0.997f * teta1;
teta3 = 0.003f * teta3_new + 0.997f * teta3;
if (teta3 > 0.0f)
TRX_IQ_phase_error = asinf(teta1 / teta3);
}
if(current_vfo->Mode != TRX_MODE_IQ)
doRX_IFGain(FPGA_RX_IQ_BUFFER_HALF_SIZE);
switch (current_vfo->Mode) // first receiver
{
case TRX_MODE_LSB:
case TRX_MODE_CW_L:
doRX_HILBERT(FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_sub_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE); // difference of I and Q - LSB
doRX_HPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_LPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_GAUSS_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_NOTCH(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_DIGI_L:
doRX_HILBERT(FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_sub_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE); // difference of I and Q - LSB
doRX_LPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_USB:
case TRX_MODE_CW_U:
doRX_HILBERT(FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_add_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE); // sum of I and Q - USB
doRX_HPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_LPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_GAUSS_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_NOTCH(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_DIGI_U:
doRX_HILBERT(FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_add_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE); // sum of I and Q - USB
doRX_LPF_I(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_AM:
doRX_LPF_IQ(FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_mult_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_mult_f32(FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE);
arm_add_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE);
//arm_vsqrt_f32(FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, FPGA_AUDIO_BUFFER_HALF_SIZE);
for (uint_fast16_t i = 0; i < FPGA_RX_IQ_BUFFER_HALF_SIZE; i++)
arm_sqrt_f32(FPGA_Audio_Buffer_RX_I_tmp[i], &FPGA_Audio_Buffer_RX_I_tmp[i]);
arm_scale_f32(FPGA_Audio_Buffer_RX_I_tmp, 0.5f, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_NOTCH(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_NFM:
doRX_LPF_IQ(FPGA_RX_IQ_BUFFER_HALF_SIZE);
case TRX_MODE_WFM:
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
DemodulateFM(FPGA_RX_IQ_BUFFER_HALF_SIZE);
//end decimate
doRX_AGC(FPGA_RX_IQ_BUFFER_HALF_SIZE, current_vfo->Mode);
doRX_COPYCHANNEL(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
case TRX_MODE_IQ:
default:
doRX_SMETER(FPGA_RX_IQ_BUFFER_HALF_SIZE);
break;
}
//Prepare data to DMA
int32_t *Processor_AudioBuffer_current;
if (Processor_AudioBuffer_ReadyBuffer == 0)
Processor_AudioBuffer_current = &Processor_AudioBuffer_B[0];
else
Processor_AudioBuffer_current = &Processor_AudioBuffer_A[0];
// receiver equalizer
if (current_vfo->Mode != TRX_MODE_DIGI_L && current_vfo->Mode != TRX_MODE_DIGI_U && current_vfo->Mode != TRX_MODE_IQ)
doRX_EQ(FPGA_RX_IQ_BUFFER_HALF_SIZE);
// muting
if (TRX_Mute)
arm_scale_f32(FPGA_Audio_Buffer_RX_I_tmp, 0.0f, FPGA_Audio_Buffer_RX_I_tmp, FPGA_RX_IQ_BUFFER_HALF_SIZE);
// create buffers for transmission to the codec
for (uint_fast16_t i = 0; i < FPGA_RX_IQ_BUFFER_HALF_SIZE; i++)
{
arm_float_to_q31(&FPGA_Audio_Buffer_RX_I_tmp[i], &Processor_AudioBuffer_current[i * 2], 1); //left channel
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
}
if (Processor_AudioBuffer_ReadyBuffer == 0)
Processor_AudioBuffer_ReadyBuffer = 1;
else
Processor_AudioBuffer_ReadyBuffer = 0;
//Send to USB Audio
if (USB_AUDIO_need_rx_buffer && TRX_Inited)
{
uint8_t *USB_AUDIO_rx_buffer_current;
if (!USB_AUDIO_current_rx_buffer)
USB_AUDIO_rx_buffer_current = &USB_AUDIO_rx_buffer_a[0];
else
USB_AUDIO_rx_buffer_current = &USB_AUDIO_rx_buffer_b[0];
//drop LSB 32b->24b
for (uint_fast16_t i = 0; i < (USB_AUDIO_RX_BUFFER_SIZE / BYTES_IN_SAMPLE_AUDIO_OUT_PACKET); i++)
{
USB_AUDIO_rx_buffer_current[i * BYTES_IN_SAMPLE_AUDIO_OUT_PACKET + 0] = (Processor_AudioBuffer_current[i] >> 8) & 0xFF;
USB_AUDIO_rx_buffer_current[i * BYTES_IN_SAMPLE_AUDIO_OUT_PACKET + 1] = (Processor_AudioBuffer_current[i] >> 16) & 0xFF;
USB_AUDIO_rx_buffer_current[i * BYTES_IN_SAMPLE_AUDIO_OUT_PACKET + 2] = (Processor_AudioBuffer_current[i] >> 24) & 0xFF;
}
USB_AUDIO_need_rx_buffer = false;
}
//OUT Volume
float32_t volume_gain_new = volume2rate((float32_t)TRX.Volume / 100.0f);
volume_gain = 0.9f * volume_gain + 0.1f * volume_gain_new;
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_SIZE; i++)
{
Processor_AudioBuffer_current[i] = (int32_t)((float32_t)Processor_AudioBuffer_current[i] * volume_gain);
Processor_AudioBuffer_current[i] = convertToSPIBigEndian(Processor_AudioBuffer_current[i]); //for 32bit audio
}
//Beep signal
if(WM8731_Beeping)
{
float32_t signal = 0;
int32_t out = 0;
float32_t amplitude = volume2rate((float32_t)TRX.Volume / 100.0f) * 0.1f;
for(uint32_t pos = 0; pos < AUDIO_BUFFER_HALF_SIZE; pos++)
{
signal = generateSin(amplitude, pos, TRX_SAMPLERATE, 1500);
arm_float_to_q31(&signal, &out, 1);
Processor_AudioBuffer_current[pos * 2] = convertToSPIBigEndian(out); //left channel
Processor_AudioBuffer_current[pos * 2 + 1] = Processor_AudioBuffer_current[pos * 2]; //right channel
}
}
//Mute codec
if(WM8731_Muting)
{
for(uint32_t pos = 0; pos < AUDIO_BUFFER_HALF_SIZE; pos++)
{
Processor_AudioBuffer_current[pos * 2] = 0; //left channel
Processor_AudioBuffer_current[pos * 2 + 1] = 0; //right channel
}
}
//Send to Codec DMA
if (TRX_Inited)
{
if (WM8731_DMA_state) //complete
{
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream1, (uint32_t)&Processor_AudioBuffer_current[0], (uint32_t)&CODEC_Audio_Buffer_RX[AUDIO_BUFFER_SIZE], CODEC_AUDIO_BUFFER_HALF_SIZE); //*2 -> left_right
//HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream1, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
else //half
{
HAL_DMA_Start_IT(&hdma_memtomem_dma2_stream2, (uint32_t)&Processor_AudioBuffer_current[0], (uint32_t)&CODEC_Audio_Buffer_RX[0], CODEC_AUDIO_BUFFER_HALF_SIZE); //*2 -> left_right
//HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
}
Processor_NeedRXBuffer = false;
}
// start audio processor for TX
void processTxAudio(void)
{
if (!Processor_NeedTXBuffer)
return;
VFO *current_vfo = CurrentVFO();
AUDIOPROC_samples++;
uint_fast8_t mode = current_vfo->Mode;
// get the amplitude for the selected power and range
Processor_selected_RFpower_amplitude = log10f_fast(((float32_t)TRX.RF_Power * 0.9f + 10.0f) / 10.0f) * TRX_MAX_TX_Amplitude;
if (Processor_selected_RFpower_amplitude < 0.0f)
Processor_selected_RFpower_amplitude = 0.0f;
if (mode == TRX_MODE_LOOPBACK && !TRX_Tune)
Processor_selected_RFpower_amplitude = 0.5f;
// zero beats
if ((TRX_Tune && !TRX.TWO_SIGNAL_TUNE) || (TRX_Tune && (mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U)))
Processor_selected_RFpower_amplitude = Processor_selected_RFpower_amplitude * 1.0f;
if (TRX.InputType_USB) //USB AUDIO
{
uint32_t buffer_index = USB_AUDIO_GetTXBufferIndex_FS() / BYTES_IN_SAMPLE_AUDIO_OUT_PACKET; //buffer 8bit, data 24 bit
if ((buffer_index % BYTES_IN_SAMPLE_AUDIO_OUT_PACKET) == 1)
buffer_index -= (buffer_index % BYTES_IN_SAMPLE_AUDIO_OUT_PACKET);
readHalfFromCircleUSBBuffer24Bit(&USB_AUDIO_tx_buffer[0], &Processor_AudioBuffer_A[0], buffer_index, (USB_AUDIO_TX_BUFFER_SIZE / BYTES_IN_SAMPLE_AUDIO_OUT_PACKET));
}
else //AUDIO CODEC AUDIO
{
uint32_t dma_index = CODEC_AUDIO_BUFFER_SIZE - (uint16_t)__HAL_DMA_GET_COUNTER(hi2s3.hdmarx);
if ((dma_index % 2) == 1)
dma_index--;
readFromCircleBuffer32((uint32_t *)&CODEC_Audio_Buffer_TX[0], (uint32_t *)&Processor_AudioBuffer_A[0], dma_index, CODEC_AUDIO_BUFFER_SIZE, AUDIO_BUFFER_SIZE);
}
//One-signal zero-tune generator
if (TRX_Tune && !TRX.TWO_SIGNAL_TUNE)
{
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
FPGA_Audio_Buffer_TX_I_tmp[i] = (Processor_selected_RFpower_amplitude / 100.0f * TUNE_POWER);
FPGA_Audio_Buffer_TX_Q_tmp[i] = 0.0f;
}
}
//Two-signal tune generator
if (TRX_Tune && TRX.TWO_SIGNAL_TUNE)
{
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
float32_t point = generateSin((Processor_selected_RFpower_amplitude / 100.0f * TUNE_POWER) / 2.0f, two_signal_gen_position, TRX_SAMPLERATE, 1000);
point += generateSin((Processor_selected_RFpower_amplitude / 100.0f * TUNE_POWER) / 2.0f, two_signal_gen_position, TRX_SAMPLERATE, 2000);
two_signal_gen_position++;
if (two_signal_gen_position >= TRX_SAMPLERATE)
two_signal_gen_position = 0;
FPGA_Audio_Buffer_TX_I_tmp[i] = point;
FPGA_Audio_Buffer_TX_Q_tmp[i] = point;
}
//hilbert fir
// + 45 deg to Q data
arm_fir_f32(&FIR_TX_Hilbert_Q, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
// - 45 deg to I data
arm_fir_f32(&FIR_TX_Hilbert_I, FPGA_Audio_Buffer_TX_Q_tmp, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
}
//FM tone generator
if (TRX_Tune && (mode == TRX_MODE_NFM || mode == TRX_MODE_WFM))
{
static uint32_t tone_counter = 100;
tone_counter++;
if(tone_counter >= 400)
tone_counter = 0;
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
float32_t point = 0.0f;
if(tone_counter > 300)
point = generateSin(1.0f, two_signal_gen_position, TRX_SAMPLERATE, 3500);
else if(tone_counter > 200)
point = generateSin(1.0f, two_signal_gen_position, TRX_SAMPLERATE, 2000);
else if(tone_counter > 100)
point = generateSin(1.0f, two_signal_gen_position, TRX_SAMPLERATE, 1000);
two_signal_gen_position++;
if (two_signal_gen_position >= TRX_SAMPLERATE)
two_signal_gen_position = 0;
FPGA_Audio_Buffer_TX_I_tmp[i] = point;
FPGA_Audio_Buffer_TX_Q_tmp[i] = point;
}
ModulateFM(AUDIO_BUFFER_HALF_SIZE);
}
if (!TRX_Tune)
{
//Copy and convert buffer
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
FPGA_Audio_Buffer_TX_I_tmp[i] = (float32_t)Processor_AudioBuffer_A[i * 2] / 2147483648.0f;
FPGA_Audio_Buffer_TX_Q_tmp[i] = (float32_t)Processor_AudioBuffer_A[i * 2 + 1] / 2147483648.0f;
}
if (TRX.InputType_MIC)
{
//Mic Gain
arm_scale_f32(FPGA_Audio_Buffer_TX_I_tmp, TRX.MIC_GAIN, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
arm_scale_f32(FPGA_Audio_Buffer_TX_Q_tmp, TRX.MIC_GAIN, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
//Mic Equalizer
if (mode != TRX_MODE_DIGI_L && mode != TRX_MODE_DIGI_U && mode != TRX_MODE_IQ)
doMIC_EQ(AUDIO_BUFFER_HALF_SIZE);
}
//USB Gain (24bit)
if (TRX.InputType_USB)
{
arm_scale_f32(FPGA_Audio_Buffer_TX_I_tmp, 10.0f, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
arm_scale_f32(FPGA_Audio_Buffer_TX_Q_tmp, 10.0f, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
}
//Process DC corrector filter
dc_filter(FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE, DC_FILTER_TX_I);
dc_filter(FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE, DC_FILTER_TX_Q);
}
if (mode != TRX_MODE_IQ && !TRX_Tune)
{
//IIR HPF
if (current_vfo->HPF_Filter_Width > 0)
arm_biquad_cascade_df2T_f32(&IIR_TX_HPF_I, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
//IIR LPF
if (current_vfo->LPF_Filter_Width > 0)
arm_biquad_cascade_df2T_f32(&IIR_TX_LPF_I, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
memcpy(&FPGA_Audio_Buffer_TX_Q_tmp[0], &FPGA_Audio_Buffer_TX_I_tmp[0], AUDIO_BUFFER_HALF_SIZE * 4); //double left and right channel
switch (mode)
{
case TRX_MODE_CW_L:
case TRX_MODE_CW_U:
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
FPGA_Audio_Buffer_TX_I_tmp[i] = TRX_GenerateCWSignal(Processor_selected_RFpower_amplitude);
FPGA_Audio_Buffer_TX_Q_tmp[i] = 0.0f;
}
break;
case TRX_MODE_USB:
case TRX_MODE_DIGI_U:
//hilbert fir
// + 45 deg to Q data
arm_fir_f32(&FIR_TX_Hilbert_Q, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
// - 45 deg to I data
arm_fir_f32(&FIR_TX_Hilbert_I, FPGA_Audio_Buffer_TX_Q_tmp, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
break;
case TRX_MODE_LSB:
case TRX_MODE_DIGI_L:
//hilbert fir
// + 45 deg to I data
arm_fir_f32(&FIR_TX_Hilbert_I, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
// - 45 deg to Q data
arm_fir_f32(&FIR_TX_Hilbert_Q, FPGA_Audio_Buffer_TX_Q_tmp, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
break;
case TRX_MODE_AM:
// + 45 deg to I data
arm_fir_f32(&FIR_TX_Hilbert_I, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
// - 45 deg to Q data
arm_fir_f32(&FIR_TX_Hilbert_Q, FPGA_Audio_Buffer_TX_Q_tmp, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
for (size_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
float32_t i_am = ((FPGA_Audio_Buffer_TX_I_tmp[i] - FPGA_Audio_Buffer_TX_Q_tmp[i]) + (Processor_selected_RFpower_amplitude)) / 2.0f;
float32_t q_am = ((FPGA_Audio_Buffer_TX_Q_tmp[i] - FPGA_Audio_Buffer_TX_I_tmp[i]) - (Processor_selected_RFpower_amplitude)) / 2.0f;
FPGA_Audio_Buffer_TX_I_tmp[i] = i_am;
FPGA_Audio_Buffer_TX_Q_tmp[i] = q_am;
}
break;
case TRX_MODE_NFM:
case TRX_MODE_WFM:
ModulateFM(AUDIO_BUFFER_HALF_SIZE);
break;
case TRX_MODE_LOOPBACK:
break;
default:
break;
}
}
//// RF PowerControl (Audio Level Control) Compressor
// looking for a maximum in amplitude
float32_t ampl_max_i = 0.0f;
float32_t ampl_max_q = 0.0f;
float32_t ampl_min_i = 0.0f;
float32_t ampl_min_q = 0.0f;
uint32_t tmp_index;
arm_max_f32(FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE, &ampl_max_i, &tmp_index);
arm_max_f32(FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE, &ampl_max_q, &tmp_index);
arm_min_f32(FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE, &ampl_min_i, &tmp_index);
arm_min_f32(FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE, &ampl_min_q, &tmp_index);
float32_t Processor_TX_MAX_amplitude_IN = ampl_max_i;
if (ampl_max_q > Processor_TX_MAX_amplitude_IN)
Processor_TX_MAX_amplitude_IN = ampl_max_q;
if ((-ampl_min_i) > Processor_TX_MAX_amplitude_IN)
Processor_TX_MAX_amplitude_IN = -ampl_min_i;
if ((-ampl_min_q) > Processor_TX_MAX_amplitude_IN)
Processor_TX_MAX_amplitude_IN = -ampl_min_q;
// calculate the target gain
if (Processor_TX_MAX_amplitude_IN > 0.0f)
{
ALC_need_gain_target = (Processor_selected_RFpower_amplitude * 0.99f) / Processor_TX_MAX_amplitude_IN;
// move the gain one step
if (fabsf(ALC_need_gain_target - ALC_need_gain) > 0.00001f) // hysteresis
{
if (ALC_need_gain_target > ALC_need_gain)
{
if (mode == TRX_MODE_DIGI_L || mode == TRX_MODE_DIGI_U) // FAST AGC
ALC_need_gain = (ALC_need_gain * (1.0f - (float32_t)TRX.TX_AGC_speed / 30.0f)) + (ALC_need_gain_target * ((float32_t)TRX.TX_AGC_speed / 30.0f));
else // SLOW AGC
ALC_need_gain = (ALC_need_gain * (1.0f - (float32_t)TRX.TX_AGC_speed / 1000.0f)) + (ALC_need_gain_target * ((float32_t)TRX.TX_AGC_speed / 1000.0f));
}
}
//just in case
if (ALC_need_gain < 0.0f)
ALC_need_gain = 0.0f;
// overload (clipping), sharply reduce the gain
if ((ALC_need_gain * Processor_TX_MAX_amplitude_IN) > (Processor_selected_RFpower_amplitude * 1.0f))
{
ALC_need_gain = ALC_need_gain_target;
// sendToDebug_str ("MIC_CLIP");
}
if (ALC_need_gain > TX_AGC_MAXGAIN)
ALC_need_gain = TX_AGC_MAXGAIN;
// noise threshold
if (Processor_TX_MAX_amplitude_IN < TX_AGC_NOISEGATE)
ALC_need_gain = 0.0f;
}
// disable gain for some types of mod
if ((ALC_need_gain > 1.0f) && (mode == TRX_MODE_LOOPBACK))
ALC_need_gain = 1.0f;
if (mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U || mode == TRX_MODE_NFM || mode == TRX_MODE_WFM)
ALC_need_gain = 1.0f;
if (TRX_Tune)
ALC_need_gain = 1.0f;
// apply gain
arm_scale_f32(FPGA_Audio_Buffer_TX_I_tmp, ALC_need_gain, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
arm_scale_f32(FPGA_Audio_Buffer_TX_Q_tmp, ALC_need_gain, FPGA_Audio_Buffer_TX_Q_tmp, AUDIO_BUFFER_HALF_SIZE);
Processor_TX_MAX_amplitude_OUT = Processor_TX_MAX_amplitude_IN * ALC_need_gain;
if (Processor_selected_RFpower_amplitude > 0.0f)
TRX_ALC = Processor_TX_MAX_amplitude_OUT / Processor_selected_RFpower_amplitude;
else
TRX_ALC = 0.0f;
//RF PowerControl (Audio Level Control) Compressor END
//Send TX data to FFT
float32_t* FFTInput_I_current = FFT_buff_current ? (float32_t*)&FFTInput_I_B : (float32_t*)&FFTInput_I_A;
float32_t* FFTInput_Q_current = FFT_buff_current ? (float32_t*)&FFTInput_Q_B : (float32_t*)&FFTInput_Q_A;
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
FFTInput_I_current[FFT_buff_index] = FPGA_Audio_Buffer_TX_I_tmp[i];
FFTInput_Q_current[FFT_buff_index] = FPGA_Audio_Buffer_TX_Q_tmp[i];
FFT_buff_index++;
if (FFT_buff_index >= FFT_SIZE)
{
FFT_buff_index = 0;
FFT_new_buffer_ready = true;
FFT_buff_current = !FFT_buff_current;
}
}
//Loopback mode
if (mode == TRX_MODE_LOOPBACK && !TRX_Tune)
{
//OUT Volume
float32_t volume_gain_tx = volume2rate((float32_t)TRX.Volume / 100.0f);
arm_scale_f32(FPGA_Audio_Buffer_TX_I_tmp, volume_gain_tx, FPGA_Audio_Buffer_TX_I_tmp, AUDIO_BUFFER_HALF_SIZE);
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
arm_float_to_q31(&FPGA_Audio_Buffer_TX_I_tmp[i], &Processor_AudioBuffer_A[i * 2], 1);
Processor_AudioBuffer_A[i * 2] = convertToSPIBigEndian(Processor_AudioBuffer_A[i * 2]); //left channel
Processor_AudioBuffer_A[i * 2 + 1] = Processor_AudioBuffer_A[i * 2]; //right channel
}
if (WM8731_DMA_state) //compleate
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream1, (uint32_t)&Processor_AudioBuffer_A[0], (uint32_t)&CODEC_Audio_Buffer_RX[AUDIO_BUFFER_SIZE], AUDIO_BUFFER_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream1, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
else //half
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream2, (uint32_t)&Processor_AudioBuffer_A[0], (uint32_t)&CODEC_Audio_Buffer_RX[0], AUDIO_BUFFER_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
}
else
{
//CW SelfHear
if (TRX.CW_SelfHear && (TRX.CW_KEYER || TRX_key_serial || TRX_key_dot_hard || TRX_key_dash_hard) && (mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U) && !TRX_Tune)
{
float32_t volume_gain_tx = volume2rate((float32_t)TRX.Volume / 100.0f);
float32_t amplitude = (db2rateV(TRX.AGC_GAIN_TARGET) * volume_gain_tx * CODEC_BITS_FULL_SCALE / 2.0f);
for (uint_fast16_t i = 0; i < AUDIO_BUFFER_HALF_SIZE; i++)
{
int32_t data = convertToSPIBigEndian((int32_t)(amplitude * ( FPGA_Audio_Buffer_TX_I_tmp[i] / Processor_selected_RFpower_amplitude) * arm_sin_f32(((float32_t)i / (float32_t)TRX_SAMPLERATE) * PI * 2.0f * (float32_t)TRX.CW_GENERATOR_SHIFT_HZ)));
if (WM8731_DMA_state)
{
CODEC_Audio_Buffer_RX[AUDIO_BUFFER_SIZE + i * 2] = data;
CODEC_Audio_Buffer_RX[AUDIO_BUFFER_SIZE + i * 2 + 1] = data;
}
else
{
CODEC_Audio_Buffer_RX[i * 2] = data;
CODEC_Audio_Buffer_RX[i * 2 + 1] = data;
}
}
}
else if (TRX.CW_SelfHear)
{
memset(CODEC_Audio_Buffer_RX, 0x00, sizeof CODEC_Audio_Buffer_RX);
}
//
if (FPGA_Audio_Buffer_State) //Send to FPGA DMA
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream1, (uint32_t)&FPGA_Audio_Buffer_TX_I_tmp[0], (uint32_t)&FPGA_Audio_SendBuffer_I[AUDIO_BUFFER_HALF_SIZE], AUDIO_BUFFER_HALF_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream1, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Start(&hdma_memtomem_dma2_stream1, (uint32_t)&FPGA_Audio_Buffer_TX_Q_tmp[0], (uint32_t)&FPGA_Audio_SendBuffer_Q[AUDIO_BUFFER_HALF_SIZE], AUDIO_BUFFER_HALF_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream1, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
else
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream2, (uint32_t)&FPGA_Audio_Buffer_TX_I_tmp[0], (uint32_t)&FPGA_Audio_SendBuffer_I[0], AUDIO_BUFFER_HALF_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
HAL_DMA_Start(&hdma_memtomem_dma2_stream2, (uint32_t)&FPGA_Audio_Buffer_TX_Q_tmp[0], (uint32_t)&FPGA_Audio_SendBuffer_Q[0], AUDIO_BUFFER_HALF_SIZE);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream2, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
}
Processor_NeedTXBuffer = false;
Processor_NeedRXBuffer = false;
USB_AUDIO_need_rx_buffer = false;
}
// Hilbert filter for phase shift of signals
static void doRX_HILBERT(uint16_t size)
{
arm_fir_f32(&FIR_RX_Hilbert_I, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
arm_fir_f32(&FIR_RX_Hilbert_Q, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_Q_tmp, size);
}
// Low-pass filter for I and Q
static void doRX_LPF_IQ(uint16_t size)
{
if (CurrentVFO()->LPF_Filter_Width > 0)
{
arm_biquad_cascade_df2T_f32(&IIR_RX_LPF_I, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
arm_biquad_cascade_df2T_f32(&IIR_RX_LPF_Q, FPGA_Audio_Buffer_RX_Q_tmp, FPGA_Audio_Buffer_RX_Q_tmp, size);
}
}
// LPF filter for I
static void doRX_LPF_I(uint16_t size)
{
if (CurrentVFO()->LPF_Filter_Width > 0)
{
arm_biquad_cascade_df2T_f32(&IIR_RX_LPF_I, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
}
}
// Gauss filter for I
static void doRX_GAUSS_I(uint16_t size)
{
if (!TRX.CW_GaussFilter)
return;
if (CurrentVFO()->Mode == TRX_MODE_CW_L || CurrentVFO()->Mode == TRX_MODE_CW_U)
{
arm_biquad_cascade_df2T_f32(&IIR_RX_GAUSS, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
}
}
// HPF filter for I
static void doRX_HPF_I(uint16_t size)
{
if (CurrentVFO()->HPF_Filter_Width > 0)
{
arm_biquad_cascade_df2T_f32(&IIR_RX_HPF_I, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
}
}
// notch filter
static void doRX_NOTCH(uint16_t size)
{
if (CurrentVFO()->AutoNotchFilter) // automatic filter
{
for (uint32_t block = 0; block < (size / AUTO_NOTCH_BLOCK_SIZE); block++)
processAutoNotchReduction(FPGA_Audio_Buffer_RX_I_tmp + (block * AUTO_NOTCH_BLOCK_SIZE));
}
}
// RX Equalizer
static void doRX_EQ(uint16_t size)
{
if (TRX.RX_EQ_LOW != 0)
arm_biquad_cascade_df2T_f32(&EQ_RX_LOW_FILTER, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
if (TRX.RX_EQ_MID != 0)
arm_biquad_cascade_df2T_f32(&EQ_RX_MID_FILTER, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
if (TRX.RX_EQ_HIG != 0)
arm_biquad_cascade_df2T_f32(&EQ_RX_HIG_FILTER, FPGA_Audio_Buffer_RX_I_tmp, FPGA_Audio_Buffer_RX_I_tmp, size);
}
// Equalizer microphone
static void doMIC_EQ(uint16_t size)
{
if (TRX.MIC_EQ_LOW != 0)
arm_biquad_cascade_df2T_f32(&EQ_MIC_LOW_FILTER, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, size);
if (TRX.MIC_EQ_MID != 0)
arm_biquad_cascade_df2T_f32(&EQ_MIC_MID_FILTER, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, size);
if (TRX.MIC_EQ_HIG != 0)
arm_biquad_cascade_df2T_f32(&EQ_MIC_HIG_FILTER, FPGA_Audio_Buffer_TX_I_tmp, FPGA_Audio_Buffer_TX_I_tmp, size);
}
// automatic gain control
static void doRX_AGC(uint16_t size, uint_fast8_t mode)
{
DoRxAGC(FPGA_Audio_Buffer_RX_I_tmp, size, mode);
}
// s-meter
static void doRX_SMETER(uint16_t size)
{
if(Processor_RX_Power_value != 0)
return;
// Prepare data to calculate s-meter
float32_t i = 0;
arm_rms_f32(FPGA_Audio_Buffer_RX_I_tmp, size, &i);
if(current_if_gain > 0)
i *= 1.0f / current_if_gain;
Processor_RX_Power_value = i;
}
// copy I to Q channel
static void doRX_COPYCHANNEL(uint16_t size)
{
// Double channel I-> Q
dma_memcpy32((uint32_t *)&FPGA_Audio_Buffer_RX_Q_tmp[0], (uint32_t *)&FPGA_Audio_Buffer_RX_I_tmp[0], size);
}
// FM demodulator
static void DemodulateFM(uint16_t size)
{
float32_t *lpf_prev = &DFM_RX_lpf_prev;
float32_t *hpf_prev_a = &DFM_RX_hpf_prev_a;
float32_t *hpf_prev_b = &DFM_RX_hpf_prev_b;
float32_t *i_prev = &DFM_RX_i_prev;
float32_t *q_prev = &DFM_RX_q_prev;
uint_fast8_t *fm_sql_count = &DFM_RX_fm_sql_count;
float32_t *FPGA_Audio_Buffer_I_tmp = &FPGA_Audio_Buffer_RX_I_tmp[0];
float32_t *FPGA_Audio_Buffer_Q_tmp = &FPGA_Audio_Buffer_RX_Q_tmp[0];
float32_t *fm_sql_avg = &DFM_RX_fm_sql_avg;
arm_biquad_cascade_df2T_instance_f32 *iir_filter_inst = &IIR_RX_Squelch_HPF;
bool *squelched = &DFM_RX_Squelched;
float32_t angle, x, y, a, b;
static float32_t squelch_buf[FPGA_RX_IQ_BUFFER_HALF_SIZE];
for (uint_fast16_t i = 0; i < size; i++)
{
// first, calculate "x" and "y" for the arctan2, comparing the vectors of present data with previous data
y = (FPGA_Audio_Buffer_Q_tmp[i] * *i_prev) - (FPGA_Audio_Buffer_I_tmp[i] * *q_prev);
x = (FPGA_Audio_Buffer_I_tmp[i] * *i_prev) + (FPGA_Audio_Buffer_Q_tmp[i] * *q_prev);
angle = atan2f(y, x);
// we now have our audio in "angle"
squelch_buf[i] = angle; // save audio in "d" buffer for squelch noise filtering/detection - done later
a = *lpf_prev + (FM_RX_LPF_ALPHA * (angle - *lpf_prev)); //
*lpf_prev = a; // save "[n-1]" sample for next iteration
*q_prev = FPGA_Audio_Buffer_Q_tmp[i]; // save "previous" value of each channel to allow detection of the change of angle in next go-around
*i_prev = FPGA_Audio_Buffer_I_tmp[i];
if ((!*squelched) || (!TRX.FM_SQL_threshold)) // high-pass audio only if we are un-squelched (to save processor time)
{
if (CurrentVFO()->Mode == TRX_MODE_WFM)
{
FPGA_Audio_Buffer_I_tmp[i] = (float32_t)(angle / PI) * 0.1f; //second way
}
else
{
b = FM_RX_HPF_ALPHA * (*hpf_prev_b + a - *hpf_prev_a); // do differentiation
*hpf_prev_a = a; // save "[n-1]" samples for next iteration
*hpf_prev_b = b;
FPGA_Audio_Buffer_I_tmp[i] = b * 0.1f; // save demodulated and filtered audio in main audio processing buffer
}
}
else if (*squelched) // were we squelched or tone NOT detected?
FPGA_Audio_Buffer_I_tmp[i] = 0; // do not filter receive audio - fill buffer with zeroes to mute it
}
// *** Squelch Processing ***
arm_biquad_cascade_df2T_f32(iir_filter_inst, squelch_buf, squelch_buf, size); // Do IIR high-pass filter on audio so we may detect squelch noise energy
*fm_sql_avg = ((1.0f - FM_RX_SQL_SMOOTHING) * *fm_sql_avg) + (FM_RX_SQL_SMOOTHING * sqrtf(fabsf(squelch_buf[0]))); // IIR filter squelch energy magnitude: We need look at only one representative sample
*fm_sql_count = *fm_sql_count + 1; // bump count that controls how often the squelch threshold is checked
if (*fm_sql_count >= FM_SQUELCH_PROC_DECIMATION)
*fm_sql_count = 0; // enforce the count limit
// Determine if the (averaged) energy in "ads.fm_sql_avg" is above or below the squelch threshold
if (*fm_sql_count == 0) // do the squelch threshold calculation much less often than we are called to process this audio
{
if (*fm_sql_avg > 0.7f) // limit maximum noise value in averaging to keep it from going out into the weeds under no-signal conditions (higher = noisier)
*fm_sql_avg = 0.7f;
b = *fm_sql_avg * 10.0f; // scale noise amplitude to range of squelch setting
// Now evaluate noise power with respect to squelch setting
if (!TRX.FM_SQL_threshold) // is squelch set to zero?
*squelched = false; // yes, the we are un-squelched
else if (*squelched) // are we squelched?
{
if (b <= (float)((10 - TRX.FM_SQL_threshold) - FM_SQUELCH_HYSTERESIS)) // yes - is average above threshold plus hysteresis?
*squelched = false; // yes, open the squelch
}
else // is the squelch open (e.g. passing audio)?
{
if ((10.0f - TRX.FM_SQL_threshold) > FM_SQUELCH_HYSTERESIS) // is setting higher than hysteresis?
{
if (b > (float)((10 - TRX.FM_SQL_threshold) + FM_SQUELCH_HYSTERESIS)) // yes - is average below threshold minus hysteresis?
*squelched = true; // yes, close the squelch
}
else // setting is lower than hysteresis so we can't use it!
{
if (b > (10.0f - (float)TRX.FM_SQL_threshold)) // yes - is average below threshold?
*squelched = true; // yes, close the squelch
}
}
}
}
// FM modulator
static void ModulateFM(uint16_t size)
{
static float32_t modulation = (float32_t)TRX_SAMPLERATE;
static float32_t hpf_prev_a = 0;
static float32_t hpf_prev_b = 0;
static float32_t sin_data = 0;
static float32_t fm_mod_accum = 0;
static float32_t modulation_index = 15000.0f;
if (CurrentVFO()->LPF_Filter_Width == 5000)
modulation_index = 4000.0f;
if (CurrentVFO()->LPF_Filter_Width == 6000)
modulation_index = 6000.0f;
if (CurrentVFO()->LPF_Filter_Width == 7000)
modulation_index = 8000.0f;
if (CurrentVFO()->LPF_Filter_Width == 8000)
modulation_index = 11000.0f;
if (CurrentVFO()->LPF_Filter_Width == 9000)
modulation_index = 13000.0f;
if (CurrentVFO()->LPF_Filter_Width == 10000)
modulation_index = 15000.0f;
if (CurrentVFO()->LPF_Filter_Width == 15000)
modulation_index = 30000.0f;
if (CurrentVFO()->LPF_Filter_Width == 20000)
modulation_index = 40000.0f;
if (CurrentVFO()->LPF_Filter_Width == 0)
modulation_index = 45000.0f;
// Do differentiating high-pass filter to provide 6dB/octave pre-emphasis - which also removes any DC component!
float32_t ampl = (Processor_selected_RFpower_amplitude / 100.0f * TUNE_POWER);
for (uint_fast16_t i = 0; i < size; i++)
{
hpf_prev_b = FM_TX_HPF_ALPHA * (hpf_prev_b +FPGA_Audio_Buffer_TX_I_tmp[i] - hpf_prev_a); // do differentiation
hpf_prev_a = FPGA_Audio_Buffer_TX_I_tmp[i]; // save "[n-1] samples for next iteration
fm_mod_accum = (1.0f - 0.999f) * fm_mod_accum + 0.999f * hpf_prev_b; // save differentiated data in audio buffer // change frequency using scaled audio
while(fm_mod_accum > modulation) fm_mod_accum -= modulation; // limit range
while(fm_mod_accum < -modulation) fm_mod_accum += modulation; // limit range
sin_data = ((fm_mod_accum * modulation_index) / modulation) * PI;
FPGA_Audio_Buffer_TX_I_tmp[i] = ampl * arm_sin_f32(sin_data);
FPGA_Audio_Buffer_TX_Q_tmp[i] = ampl * arm_cos_f32(sin_data);
}
}
// Apply IF Gain IF Gain
static void doRX_IFGain(uint16_t size)
{
float32_t if_gain = db2rateV(TRX.IF_Gain);
//apply gain
arm_scale_f32(FPGA_Audio_Buffer_RX_I_tmp, if_gain, FPGA_Audio_Buffer_RX_I_tmp, size);
arm_scale_f32(FPGA_Audio_Buffer_RX_Q_tmp, if_gain, FPGA_Audio_Buffer_RX_Q_tmp, size);
current_if_gain = if_gain;
}

Wyświetl plik

@ -1,49 +0,0 @@
#ifndef AUDIO_PROCESSOR_h
#define AUDIO_PROCESSOR_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "functions.h"
#include "settings.h"
#define AUDIO_BUFFER_SIZE (192 * 2) // the size of the buffer for working with sound 48kHz
#define AUDIO_BUFFER_HALF_SIZE (AUDIO_BUFFER_SIZE / 2) // buffer size for working with sound 48kHz
#define FPGA_TX_IQ_BUFFER_SIZE AUDIO_BUFFER_SIZE // size of TX data buffer for FPGA
#define FPGA_TX_IQ_BUFFER_HALF_SIZE (FPGA_TX_IQ_BUFFER_SIZE / 2) // half the size of the TX data buffer for FPGA
#define FPGA_RX_IQ_BUFFER_SIZE (FPGA_TX_IQ_BUFFER_SIZE) // size of the RX data buffer from the PGA
#define FPGA_RX_IQ_BUFFER_HALF_SIZE (FPGA_RX_IQ_BUFFER_SIZE / 2) // half the size of the RX data buffer from the PGA
#define FM_RX_LPF_ALPHA 0.05f // For NFM demodulator: "Alpha" (low-pass) factor to result in -6dB "knee" at approx. 270 Hz 0.05f
#define FM_RX_HPF_ALPHA 0.96f // For NFM demodulator: "Alpha" (high-pass) factor to result in -6dB "knee" at approx. 180 Hz 0.96f
#define FM_TX_HPF_ALPHA 0.95f // For FM modulator: "Alpha" (high-pass) factor to pre-emphasis
#define FM_SQUELCH_HYSTERESIS 0.3f // Hysteresis for FM squelch
#define FM_SQUELCH_PROC_DECIMATION 50 // Number of times we go through the FM demod algorithm before we do a squelch calculation
#define FM_RX_SQL_SMOOTHING 0.005f // Smoothing factor for IIR squelch noise averaging
#define AUDIO_RX_NB_DELAY_BUFFER_ITEMS 32 // NoiseBlanker buffer size
#define AUDIO_RX_NB_DELAY_BUFFER_SIZE (AUDIO_RX_NB_DELAY_BUFFER_ITEMS * 2)
#define AUDIO_MAX_REVERBER_TAPS 10
// Public variables
extern volatile uint32_t AUDIOPROC_samples; // audio samples processed in the processor
extern int32_t Processor_AudioBuffer_A[AUDIO_BUFFER_SIZE]; // buffer A of the audio processor
extern int32_t Processor_AudioBuffer_B[AUDIO_BUFFER_SIZE]; // buffer B of the audio processor
extern volatile uint_fast8_t Processor_AudioBuffer_ReadyBuffer; // which buffer is currently in use, A or B
extern volatile bool Processor_NeedRXBuffer; // codec needs data from processor for RX
extern volatile bool Processor_NeedTXBuffer; // codec needs data from processor for TX
extern float32_t FPGA_Audio_Buffer_RX_Q_tmp[FPGA_RX_IQ_BUFFER_HALF_SIZE]; // copy of the working part of the FPGA buffers for processing
extern float32_t FPGA_Audio_Buffer_RX_I_tmp[FPGA_RX_IQ_BUFFER_HALF_SIZE];
extern float32_t FPGA_Audio_Buffer_TX_Q_tmp[FPGA_TX_IQ_BUFFER_HALF_SIZE];
extern float32_t FPGA_Audio_Buffer_TX_I_tmp[FPGA_TX_IQ_BUFFER_HALF_SIZE];
extern volatile float32_t Processor_TX_MAX_amplitude_OUT; // TX uplift after ALC
extern volatile float32_t Processor_RX_Power_value; // RX signal magnitude
extern volatile float32_t Processor_selected_RFpower_amplitude; // target TX signal amplitude
extern bool NeedReinitReverber;
// Public methods
extern void processRxAudio(void); // start audio processor for RX
extern void processTxAudio(void); // start audio processor for TX
extern void initAudioProcessor(void); // initialize audio processor
#endif

Wyświetl plik

@ -1,75 +0,0 @@
#include "auto_notch.h"
#include "trx_manager.h"
// Private variables
static arm_lms_norm_instance_f32 lms2_Norm_instance;
static float32_t lms2_stateF32[AUTO_NOTCH_TAPS + AUTO_NOTCH_BLOCK_SIZE - 1];
static float32_t lms2_normCoeff_f32[AUTO_NOTCH_TAPS];
static float32_t lms2_reference[AUTO_NOTCH_REFERENCE_SIZE];
static float32_t lms2_errsig2[AUTO_NOTCH_BLOCK_SIZE];
static uint_fast16_t reference_index_old;
static uint_fast16_t reference_index_new;
// initialize the automatic notch filter
void InitAutoNotchReduction(void)
{
memset(&lms2_stateF32, 0x00, sizeof(lms2_stateF32));
memset(&lms2_normCoeff_f32, 0x00, sizeof(lms2_normCoeff_f32));
memset(&lms2_reference, 0x00, sizeof(lms2_reference));
memset(&lms2_errsig2, 0x00, sizeof(lms2_errsig2));
reference_index_old = 0;
reference_index_new = 0;
arm_lms_norm_init_f32(&lms2_Norm_instance, AUTO_NOTCH_TAPS, lms2_normCoeff_f32, lms2_stateF32, AUTO_NOTCH_STEP, AUTO_NOTCH_BLOCK_SIZE);
}
// start automatic notch filter
void processAutoNotchReduction(float32_t *buffer)
{
//overflow protect
static uint32_t temporary_stop = 0;
if(temporary_stop > 0)
{
temporary_stop--;
return;
}
memcpy(&lms2_reference[reference_index_new], buffer, sizeof(float32_t) * AUTO_NOTCH_BLOCK_SIZE); // save the data to the reference buffer
arm_lms_norm_f32(&lms2_Norm_instance, buffer, &lms2_reference[reference_index_old], lms2_errsig2, buffer, AUTO_NOTCH_BLOCK_SIZE); // start LMS filter
//overflow protect
float32_t minValOut = 0;
float32_t maxValOut = 0;
uint32_t index = 0;
arm_min_f32(buffer, AUTO_NOTCH_BLOCK_SIZE, &minValOut, &index);
arm_max_no_idx_f32(buffer, AUTO_NOTCH_BLOCK_SIZE, &maxValOut);
if(isnanf(minValOut) || isinff(minValOut) || isnanf(maxValOut) || isinff(maxValOut))
{
if(AUTO_NOTCH_DEBUG)
{
sendToDebug_str("auto notch err ");
sendToDebug_float32(minValOut,true);
sendToDebug_str(" ");
sendToDebug_float32(maxValOut,false);
}
InitAutoNotchReduction();
memset(buffer, 0x00, sizeof(float32_t) * AUTO_NOTCH_BLOCK_SIZE);
temporary_stop = 500;
}
arm_max_no_idx_f32(lms2_Norm_instance.pCoeffs, AUTO_NOTCH_TAPS, &maxValOut);
if(maxValOut > 1.0f)
{
if(AUTO_NOTCH_DEBUG)
{
sendToDebug_strln("auto notch reset");
sendToDebug_float32(maxValOut,false);
}
InitAutoNotchReduction();
temporary_stop = 500;
}
reference_index_old += AUTO_NOTCH_BLOCK_SIZE; // move along the reference buffer
if (reference_index_old >= AUTO_NOTCH_REFERENCE_SIZE)
reference_index_old = 0;
reference_index_new = reference_index_old + AUTO_NOTCH_BLOCK_SIZE;
if (reference_index_new >= AUTO_NOTCH_REFERENCE_SIZE)
reference_index_new = 0;
}

Wyświetl plik

@ -1,20 +0,0 @@
#ifndef AUTO_NOTCH_h
#define AUTO_NOTCH_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "audio_processor.h"
#define AUTO_NOTCH_BLOCK_SIZE (AUDIO_BUFFER_HALF_SIZE / 3) // block size for processing
#define AUTO_NOTCH_TAPS 32 // filter order
#define AUTO_NOTCH_REFERENCE_SIZE (AUTO_NOTCH_BLOCK_SIZE * 2) // size of the reference buffer
#define AUTO_NOTCH_STEP 0.0005f // LMS algorithm step
#define AUTO_NOTCH_DEBUG false
// Public methods
extern void InitAutoNotchReduction(void); // initialize the automatic notch filter
extern void processAutoNotchReduction(float32_t *buffer); // start automatic notch filter
#endif

Wyświetl plik

@ -1,223 +0,0 @@
#include "bands.h"
#include "functions.h"
#include <stdlib.h>
#include "settings.h"
const BAND_MAP BANDS[BANDS_COUNT] =
{
//0-2200METERS
{
.name = "2200m",
.selectable = false,
.startFreq = 135700,
.endFreq = 137800,
.regions = (const REGION_MAP[]){
{.startFreq = 135700, .endFreq = 137800, .mode = TRX_MODE_CW_L},
},
.regionsCount = 1,
},
//1-160METERS
{
.name = "160m",
.selectable = true,
.startFreq = 1810000,
.endFreq = 2000000,
.regions = (const REGION_MAP[]){
{.startFreq = 1810000, .endFreq = 1838000, .mode = TRX_MODE_CW_L},
{.startFreq = 1838000, .endFreq = 1843000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 1843000, .endFreq = 2000000, .mode = TRX_MODE_LSB},
},
.regionsCount = 3,
},
//2-80METERS
{
.name = "80m",
.selectable = true,
.startFreq = 3500000,
.endFreq = 3800000,
.regions = (const REGION_MAP[]){
{.startFreq = 3500000, .endFreq = 3570000, .mode = TRX_MODE_CW_L},
{.startFreq = 3570000, .endFreq = 3600000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 3600000, .endFreq = 3800000, .mode = TRX_MODE_LSB},
},
.regionsCount = 3,
},
//3-60METERS
{
.name = "60m",
.selectable = false,
.startFreq = 5330500,
.endFreq = 5403500,
.regions = (const REGION_MAP[]){
{.startFreq = 5330500, .endFreq = 5403500, .mode = TRX_MODE_USB},
},
.regionsCount = 1,
},
//4-40METERS
{
.name = "40m",
.selectable = true,
.startFreq = 7000000,
.endFreq = 7200000,
.regions = (const REGION_MAP[]){
{.startFreq = 7000000, .endFreq = 7040000, .mode = TRX_MODE_CW_L},
{.startFreq = 7040000, .endFreq = 7060000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 7060000, .endFreq = 7074000, .mode = TRX_MODE_LSB},
{.startFreq = 7074000, .endFreq = 7080000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 7080000, .endFreq = 7200000, .mode = TRX_MODE_LSB},
},
.regionsCount = 5,
},
//5-30METERS
{
.name = "30m",
.selectable = true,
.startFreq = 10100000,
.endFreq = 10150000,
.regions = (const REGION_MAP[]){
{.startFreq = 10100000, .endFreq = 10130000, .mode = TRX_MODE_CW_U},
{.startFreq = 10130000, .endFreq = 10150000, .mode = TRX_MODE_DIGI_U},
},
.regionsCount = 2,
},
//6-20METERS
{
.name = "20m",
.selectable = true,
.startFreq = 14000000,
.endFreq = 14350000,
.regions = (const REGION_MAP[]){
{.startFreq = 14000000, .endFreq = 14070000, .mode = TRX_MODE_CW_U},
{.startFreq = 14070000, .endFreq = 14112000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 14112000, .endFreq = 14350000, .mode = TRX_MODE_USB},
},
.regionsCount = 3,
},
//7-17METERS
{
.name = "17m",
.selectable = true,
.startFreq = 18068000,
.endFreq = 18168000,
.regions = (const REGION_MAP[]){
{.startFreq = 18068000, .endFreq = 18095000, .mode = TRX_MODE_CW_U},
{.startFreq = 18095000, .endFreq = 18120000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 18120000, .endFreq = 18168000, .mode = TRX_MODE_USB},
},
.regionsCount = 3,
},
//8-15METERS
{
.name = "15m",
.selectable = true,
.startFreq = 21000000,
.endFreq = 21450000,
.regions = (const REGION_MAP[]){
{.startFreq = 21000000, .endFreq = 21070000, .mode = TRX_MODE_CW_U},
{.startFreq = 21070000, .endFreq = 21149000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 21149000, .endFreq = 21450000, .mode = TRX_MODE_USB},
},
.regionsCount = 4,
},
//9-12METERS
{
.name = "12m",
.selectable = true,
.startFreq = 24890000,
.endFreq = 24990000,
.regions = (const REGION_MAP[]){
{.startFreq = 24890000, .endFreq = 24915000, .mode = TRX_MODE_CW_U},
{.startFreq = 24915000, .endFreq = 24940000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 24940000, .endFreq = 24990000, .mode = TRX_MODE_USB},
},
.regionsCount = 4,
},
//10-10METERS
{
.name = "10m",
.selectable = true,
.startFreq = 28000000,
.endFreq = 29700000,
.regions = (const REGION_MAP[]){
{.startFreq = 28000000, .endFreq = 28070000, .mode = TRX_MODE_CW_U},
{.startFreq = 28070000, .endFreq = 28190000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 28190000, .endFreq = 28300000, .mode = TRX_MODE_CW_U},
{.startFreq = 28300000, .endFreq = 28320000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 28320000, .endFreq = 29100000, .mode = TRX_MODE_USB},
{.startFreq = 29100000, .endFreq = 29200000, .mode = TRX_MODE_NFM},
{.startFreq = 29200000, .endFreq = 29300000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 29300000, .endFreq = 29520000, .mode = TRX_MODE_USB},
{.startFreq = 29520000, .endFreq = 29700000, .mode = TRX_MODE_NFM},
},
.regionsCount = 9,
},
//11-6METERS
{
.name = "6m",
.selectable = true,
.startFreq = 50000000,
.endFreq = 54000000,
.regions = (const REGION_MAP[]){
{.startFreq = 50000000, .endFreq = 50100000, .mode = TRX_MODE_CW_U},
{.startFreq = 50100000, .endFreq = 50300000, .mode = TRX_MODE_USB},
{.startFreq = 50300000, .endFreq = 50350000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 50350000, .endFreq = 50600000, .mode = TRX_MODE_USB},
{.startFreq = 50600000, .endFreq = 51000000, .mode = TRX_MODE_DIGI_U},
{.startFreq = 51000000, .endFreq = 51100000, .mode = TRX_MODE_USB},
{.startFreq = 51100000, .endFreq = 54000000, .mode = TRX_MODE_NFM},
},
.regionsCount = 7,
},
};
// band number from frequency
int8_t getBandFromFreq(uint32_t freq, bool nearest)
{
for (int8_t b = 0; b < BANDS_COUNT; b++)
if (BANDS[b].startFreq <= freq && freq <= BANDS[b].endFreq)
return b;
if (nearest)
{
int8_t near_band = 0;
int32_t near_diff = 999999999;
for (int8_t b = 0; b < BANDS_COUNT; b++)
{
if (abs((int32_t)BANDS[b].startFreq - (int32_t)freq) < near_diff)
{
near_diff = abs((int32_t)BANDS[b].startFreq - (int32_t)freq);
near_band = b;
}
if (abs((int32_t)BANDS[b].endFreq - (int32_t)freq) < near_diff)
{
near_diff = abs((int32_t)BANDS[b].endFreq - (int32_t)freq);
near_band = b;
}
}
return near_band;
}
return -1;
}
// mod from frequency
uint_fast8_t getModeFromFreq(uint32_t freq)
{
uint_fast8_t ret = 0;
ret = CurrentVFO()->Mode;
for (uint_fast16_t b = 0; b < BANDS_COUNT; b++)
{
if (BANDS[b].startFreq <= freq && freq <= BANDS[b].endFreq)
for (uint_fast16_t r = 0; r < BANDS[b].regionsCount; r++)
{
if (BANDS[b].regions[r].startFreq <= freq && freq < BANDS[b].regions[r].endFreq)
{
ret = BANDS[b].regions[r].mode;
return ret;
}
}
}
return ret;
}

Wyświetl plik

@ -1,33 +0,0 @@
#ifndef BANDS_H
#define BANDS_H
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <stdbool.h>
#define BANDS_COUNT 12 // number of bands in the collection
typedef struct // description of the region in the band
{
const uint32_t startFreq;
const uint32_t endFreq;
const uint_fast8_t mode;
} REGION_MAP;
typedef struct // description of the band
{
const char *name;
const bool selectable;
const uint32_t startFreq;
const uint32_t endFreq;
const REGION_MAP *regions;
const uint_fast8_t regionsCount;
} BAND_MAP;
// Public variables
extern const BAND_MAP BANDS[BANDS_COUNT];
// Public methods
extern uint_fast8_t getModeFromFreq(uint32_t freq); // mod from frequency
extern int8_t getBandFromFreq(uint32_t freq, bool nearest); // band number from frequency
#endif

Wyświetl plik

@ -1,40 +0,0 @@
#include "bootloader.h"
#include "usb_device.h"
#include "main.h"
#include "lcd.h"
#include "functions.h"
// switch to DFU-mode buloder
void JumpToBootloader(void)
{
uint32_t i = 0;
void (*SysMemBootJump)(void);
volatile uint32_t BootAddr = 0x1FF09800;
LCD_busy = true;
TRX_Inited = false;
LCD_showError("Flash DFU mode", false);
MX_USB_DevDisconnect();
HAL_Delay(1000);
//prepare cpu
HAL_MPU_Disable();
HAL_SuspendTick();
__disable_irq(); //Disable all interrupts
SysTick->CTRL = 0; //Disable Systick timer
SysTick->VAL = 0;
SysTick->LOAD = 0;
HAL_RCC_DeInit(); //Set the clock to the default state
for (i = 0; i < 5; i++) //Clear Interrupt Enable Register & Interrupt Pending Register
{
NVIC->ICER[i] = 0xFFFFFFFF;
NVIC->ICPR[i] = 0xFFFFFFFF;
}
__enable_irq(); //Re-enable all interrupts
//go to bootloader
SysMemBootJump = (void (*)(void))(*((uint32_t *)((BootAddr + 4)))); //-V566
__set_MSP(*(uint32_t *)BootAddr); //-V566
SysMemBootJump();
while (true)
{
}
}

Wyświetl plik

@ -1,12 +0,0 @@
#ifndef BOOTLOADER_H
#define BOOTLOADER_H
#include "stm32f4xx.h"
#include "stm32f4xx_hal_conf.h"
#include "stm32f4xx_hal_rcc.h"
#include "stm32f4xx_hal_gpio.h"
//Public methods
extern void JumpToBootloader(void); // switch to DFU-mode buloder
#endif

Wyświetl plik

@ -1,178 +0,0 @@
#ifndef LCD_COLOR_THEMES_h
#define LCD_COLOR_THEMES_h
#include "lcd_driver.h"
typedef const struct
{
const uint16_t BACKGROUND;
const uint16_t FOREGROUND;
const uint16_t BUTTON_TEXT;
const uint16_t BUTTON_INACTIVE_TEXT;
const uint16_t BUTTON_BACKGROUND;
const uint16_t FREQ_MHZ;
const uint16_t FREQ_KHZ;
const uint16_t FREQ_HZ;
const uint16_t STATUS_VFO;
const uint16_t STATUS_VFO_BG;
const uint16_t STATUS_BAR_LEFT;
const uint16_t STATUS_BAR_RIGHT;
const uint16_t STATUS_BAR_LABELS;
const uint16_t STATUS_RX;
const uint16_t STATUS_TX;
const uint16_t STATUS_LABELS_BW;
const uint16_t STATUS_LABELS_TX;
const uint16_t STATUS_LABEL_S_VAL;
const uint16_t STATUS_LABEL_DBM;
const uint16_t STATUS_LABEL_BW;
const uint16_t STATUS_LABEL_RIT;
const uint16_t STATUS_LABEL_VLT;
const uint16_t STATUS_LABEL_THERM;
const uint16_t STATUS_LABEL_NOTCH;
const uint16_t STATUS_SMETER;
const uint16_t STATUS_SMETER_STRIPE;
const uint16_t STATUS_SMETER_PEAK;
const uint16_t STATUS_MODE;
const uint16_t STATUS_ERR;
const uint16_t BANDMAP_CW;
const uint16_t BANDMAP_SSB;
const uint16_t BANDMAP_DIGI;
const uint16_t BANDMAP_AM;
const uint16_t BANDMAP_FM;
const uint16_t GREETINGS;
const uint16_t TOOLTIP_FORE;
const uint16_t TOOLTIP_BACK;
const uint16_t TOOLTIP_BORD;
const uint16_t CLOCK;
const uint16_t FFT_GRADIENT_START_R;
const uint16_t FFT_GRADIENT_START_G;
const uint16_t FFT_GRADIENT_START_B;
const uint16_t FFT_GRADIENT_END_R;
const uint16_t FFT_GRADIENT_END_G;
const uint16_t FFT_GRADIENT_END_B;
const uint16_t BOTTOM_BUTTONS_COLOR;
const bool WTF_BG_WHITE;
const uint16_t BW_TRAPEZ_BORDER;
const uint16_t BW_TRAPEZ_STRIPE;
const uint16_t BW_TRAPEZ_FILL;
} STRUCT_COLOR_THEME;
static const STRUCT_COLOR_THEME COLOR_THEMES[2] = {
//0 - black
{
//3'2 inch
.BACKGROUND = COLOR_BLACK,
.FOREGROUND = COLOR_WHITE,
.BUTTON_TEXT = rgb888torgb565(32, 191, 17),
.BUTTON_INACTIVE_TEXT = rgb888torgb565(130, 130, 130),
.BUTTON_BACKGROUND = rgb888torgb565(50, 50, 50),
.FREQ_MHZ = COLOR_WHITE,
.FREQ_KHZ = COLOR_WHITE,
.FREQ_HZ = rgb888torgb565(150, 150, 150),
.STATUS_VFO = COLOR_BLACK,
.STATUS_VFO_BG = COLOR_WHITE,
.STATUS_BAR_LEFT = rgb888torgb565(100, 100, 255),
.STATUS_BAR_RIGHT = rgb888torgb565(255, 100, 100),
.STATUS_BAR_LABELS = rgb888torgb565(32, 171, 17),
.STATUS_RX = COLOR_WHITE,
.STATUS_TX = COLOR_RED,
.STATUS_LABELS_BW = COLOR_WHITE,
.STATUS_LABELS_TX = rgb888torgb565(32, 171, 17),
.STATUS_LABEL_S_VAL = rgb888torgb565(249, 205, 46),
.STATUS_LABEL_DBM = rgb888torgb565(32, 191, 17),
.STATUS_LABEL_BW = rgb888torgb565(0, 200, 255),
.STATUS_LABEL_RIT = COLOR_WHITE,
.STATUS_LABEL_VLT = rgb888torgb565(249, 205, 46),
.STATUS_LABEL_THERM = rgb888torgb565(249, 205, 46),
.STATUS_LABEL_NOTCH = rgb888torgb565(0, 200, 255),
.STATUS_SMETER = rgb888torgb565(249, 205, 46),
.STATUS_SMETER_STRIPE = COLOR_RED,
.STATUS_SMETER_PEAK = rgb888torgb565(249, 151, 46),
.STATUS_MODE = rgb888torgb565(249, 205, 46),
.STATUS_ERR = COLOR_RED,
.BANDMAP_CW = rgb888torgb565(50, 50, 255),
.BANDMAP_SSB = rgb888torgb565(50, 237, 255),
.BANDMAP_DIGI = rgb888torgb565(255, 50, 50),
.BANDMAP_AM = rgb888torgb565(219, 255, 50),
.BANDMAP_FM = rgb888torgb565(255, 50, 208),
.GREETINGS = rgb888torgb565(0, 92, 86),
.TOOLTIP_FORE = COLOR_WHITE,
.TOOLTIP_BACK = COLOR_BLACK,
.TOOLTIP_BORD = COLOR_WHITE,
.CLOCK = COLOR_WHITE,
.FFT_GRADIENT_START_R = 0,
.FFT_GRADIENT_START_G = 11,
.FFT_GRADIENT_START_B = 40,
.FFT_GRADIENT_END_R = 46,
.FFT_GRADIENT_END_G = 77,
.FFT_GRADIENT_END_B = 158,
.WTF_BG_WHITE = false,
.BOTTOM_BUTTONS_COLOR = rgb888torgb565(249, 205, 46),
.BW_TRAPEZ_BORDER = rgb888torgb565(120, 120, 120),
.BW_TRAPEZ_STRIPE = rgb888torgb565(0, 200, 255),
.BW_TRAPEZ_FILL = rgb888torgb565(140, 140, 140),
},
//1 - white
{
//3'2 inch
.BACKGROUND = COLOR_WHITE,
.FOREGROUND = COLOR_BLACK,
.BUTTON_TEXT = rgb888torgb565(150, 130, 50),
.BUTTON_INACTIVE_TEXT = rgb888torgb565(220, 220, 220),
.BUTTON_BACKGROUND = rgb888torgb565(240, 240, 240),
.FREQ_MHZ = COLOR_BLACK,
.FREQ_KHZ = COLOR_BLACK,
.FREQ_HZ = rgb888torgb565(130, 130, 130),
.STATUS_VFO = COLOR_WHITE,
.STATUS_VFO_BG = rgb888torgb565(150, 150, 150),
.STATUS_BAR_LEFT = rgb888torgb565(100, 100, 255),
.STATUS_BAR_RIGHT = rgb888torgb565(255, 100, 100),
.STATUS_BAR_LABELS = rgb888torgb565(32, 171, 17),
.STATUS_RX = COLOR_BLACK,
.STATUS_TX = COLOR_RED,
.STATUS_LABELS_BW = COLOR_BLACK,
.STATUS_LABELS_TX = rgb888torgb565(32, 171, 17),
.STATUS_LABEL_S_VAL = rgb888torgb565(150, 130, 50),
.STATUS_LABEL_DBM = rgb888torgb565(32, 191, 17),
.STATUS_LABEL_BW = rgb888torgb565(0, 100, 255),
.STATUS_LABEL_RIT = COLOR_BLACK,
.STATUS_LABEL_VLT = rgb888torgb565(249, 205, 46),
.STATUS_LABEL_THERM = rgb888torgb565(249, 205, 46),
.STATUS_LABEL_NOTCH = rgb888torgb565(0, 100, 255),
.STATUS_SMETER = rgb888torgb565(255, 238, 175),
.STATUS_SMETER_STRIPE = COLOR_RED,
.STATUS_SMETER_PEAK = rgb888torgb565(249, 151, 46),
.STATUS_MODE = rgb888torgb565(150, 130, 50),
.STATUS_ERR = COLOR_RED,
.BANDMAP_CW = rgb888torgb565(100, 100, 250),
.BANDMAP_SSB = rgb888torgb565(60, 225, 241),
.BANDMAP_DIGI = rgb888torgb565(255, 50, 50),
.BANDMAP_AM = rgb888torgb565(184, 215, 42),
.BANDMAP_FM = rgb888torgb565(192, 0, 148),
.GREETINGS = rgb888torgb565(0, 92, 86),
.TOOLTIP_FORE = COLOR_BLACK,
.TOOLTIP_BACK = COLOR_WHITE,
.TOOLTIP_BORD = COLOR_BLACK,
.CLOCK = COLOR_BLACK,
.FFT_GRADIENT_START_R = 220,
.FFT_GRADIENT_START_G = 220,
.FFT_GRADIENT_START_B = 250,
.FFT_GRADIENT_END_R = 255,
.FFT_GRADIENT_END_G = 255,
.FFT_GRADIENT_END_B = 255,
.WTF_BG_WHITE = true,
.BOTTOM_BUTTONS_COLOR = rgb888torgb565(249, 205, 46),
.BW_TRAPEZ_BORDER = rgb888torgb565(120, 120, 120),
.BW_TRAPEZ_STRIPE = rgb888torgb565(0, 200, 255),
.BW_TRAPEZ_FILL = rgb888torgb565(140, 140, 140),
},
};
#define COLOR_THEMES_COUNT 2
#define BG_COLOR COLOR->BACKGROUND
#define FG_COLOR COLOR->FOREGROUND
//LCD dimensions defines
#include "screen_layout.h"
#endif

1072
Src/fft.c

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,49 +0,0 @@
#ifndef FFT_h
#define FFT_h
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#include <math.h>
#include "functions.h"
#include "wm8731.h"
#include "screen_layout.h"
#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_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_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
#define FFT_SCALE_LINES_BRIGHTNESS 0.4f // pixel brightness on scale lines
#define FFT_MAX_GRID_NUMBER 13
#define ZOOMFFT_DECIM_STAGES 5
#define FFT_DMA_MAX_BLOCK 65000
// Public variables
extern uint32_t FFT_buff_index;
extern bool FFT_buff_current;
extern bool FFT_need_fft;
extern bool FFT_new_buffer_ready;
extern float32_t FFTInput_I_A[FFT_SIZE];
extern float32_t FFTInput_Q_A[FFT_SIZE];
extern float32_t FFTInput_I_B[FFT_SIZE];
extern float32_t FFTInput_Q_B[FFT_SIZE];
extern uint16_t FFT_FPS;
extern uint16_t FFT_FPS_Last;
// Public methods
extern void FFT_Init(void); // FFT initialization
extern void FFT_PreInit(void); // FFT precalculation
extern void FFT_bufferPrepare(void); // FFT Buffer process
extern void FFT_Reset(void); // reset FFT
extern void FFT_doFFT(void); // FFT calculation
extern bool FFT_printFFT(void); // FFT output
extern void FFT_afterPrintFFT(void); // FFT output after callback
extern void FFT_printWaterfallDMA(void); // waterfall output
extern uint32_t getFreqOnFFTPosition(uint16_t position); //get frequency from pixel X position
#endif

10242
Src/fonts.h

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,609 +0,0 @@
#include "fpga.h"
#include "main.h"
#include "trx_manager.h"
#include "rf_unit.h"
// Public variables
volatile uint32_t FPGA_samples = 0; // counter of the number of samples when exchanging with FPGA
volatile bool FPGA_NeedSendParams = false; // flag of the need to send parameters to FPGA
volatile bool FPGA_NeedGetParams = false; // flag of the need to get parameters from FPGA
volatile bool FPGA_NeedRestart = true; // flag of necessity to restart FPGA modules
volatile bool FPGA_Buffer_underrun = false; // flag of lack of data from FPGA
uint_fast16_t FPGA_Audio_RXBuffer_Index = 0; // current index in FPGA buffers
uint_fast16_t FPGA_Audio_TXBuffer_Index = 0; // current index in FPGA buffers
bool FPGA_Audio_Buffer_State = true; // buffer state, half or full full true - compleate; false - half
IRAM1 volatile float32_t FPGA_Audio_Buffer_RX_Q[FPGA_RX_IQ_BUFFER_SIZE] = {0}; // FPGA buffers
IRAM1 volatile float32_t FPGA_Audio_Buffer_RX_I[FPGA_RX_IQ_BUFFER_SIZE] = {0};
IRAM1 volatile float32_t FPGA_Audio_SendBuffer_Q[FPGA_TX_IQ_BUFFER_SIZE] = {0};
IRAM1 volatile float32_t FPGA_Audio_SendBuffer_I[FPGA_TX_IQ_BUFFER_SIZE] = {0};
// Private variables
static GPIO_InitTypeDef FPGA_GPIO_InitStruct; // structure of GPIO ports
static bool FPGA_bus_stop = false; // suspend the FPGA bus
// Prototypes
static inline void FPGA_clockFall(void); // remove CLK signal
static inline void FPGA_clockRise(void); // raise the CLK signal
static inline void FPGA_syncAndClockRiseFall(void); // raise CLK and SYNC signals, then release
static void FPGA_fpgadata_sendiq(void); // send IQ data
static void FPGA_fpgadata_getiq(void); // get IQ data
static void FPGA_fpgadata_getparam(void); // get parameters
static void FPGA_fpgadata_sendparam(void); // send parameters
static void FPGA_setBusInput(void); // switch the bus to input
static void FPGA_setBusOutput(void); // switch bus to pin
// initialize exchange with FPGA
void FPGA_Init(void)
{
FPGA_GPIO_InitStruct.Pin = FPGA_BUS_D0_Pin | FPGA_BUS_D1_Pin | FPGA_BUS_D2_Pin | FPGA_BUS_D3_Pin | FPGA_BUS_D4_Pin | FPGA_BUS_D5_Pin | FPGA_BUS_D6_Pin | FPGA_BUS_D7_Pin;
FPGA_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
FPGA_GPIO_InitStruct.Pull = GPIO_PULLUP;
FPGA_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(FPGA_BUS_D0_GPIO_Port, &FPGA_GPIO_InitStruct);
FPGA_GPIO_InitStruct.Pin = FPGA_CLK_Pin | FPGA_SYNC_Pin;
FPGA_GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_PP;
FPGA_GPIO_InitStruct.Pull = GPIO_PULLUP;
FPGA_GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
HAL_GPIO_Init(FPGA_CLK_GPIO_Port, &FPGA_GPIO_InitStruct);
FPGA_bus_stop = true;
FPGA_setBusOutput();
FPGA_writePacket(5); // RESET ON
FPGA_syncAndClockRiseFall();
HAL_Delay(100);
FPGA_writePacket(6); // RESET OFF
FPGA_syncAndClockRiseFall();
FPGA_NeedRestart = false;
FPGA_bus_stop = false;
//test bus
/*FPGA_setBusOutput();
FPGA_writePacket(0);
FPGA_syncAndClockRiseFall();
for(uint8_t i = 0; i<8; i++)
{
FPGA_writePacket(1 << i);
FPGA_clockRise();
FPGA_writePacket(0);
FPGA_clockFall();
sendToDebug_uint8(FPGA_readPacket,false);
}*/
}
// restart FPGA modules
void FPGA_restart(void) // restart FPGA modules
{
static bool FPGA_restart_state = false;
if(!FPGA_restart_state)
{
FPGA_setBusOutput();
FPGA_writePacket(5); // RESET ON
FPGA_syncAndClockRiseFall();
}
else
{
FPGA_writePacket(6); // RESET OFF
FPGA_syncAndClockRiseFall();
FPGA_NeedRestart = false;
}
FPGA_restart_state = !FPGA_restart_state;
}
// exchange parameters with FPGA
void FPGA_fpgadata_stuffclock(void)
{
if (!FPGA_NeedSendParams && !FPGA_NeedGetParams && !FPGA_NeedRestart)
return;
if (FPGA_bus_stop)
return;
uint8_t FPGA_fpgadata_out_tmp8 = 0;
//data exchange
//STAGE 1
//out
if (FPGA_NeedSendParams) //send params
FPGA_fpgadata_out_tmp8 = 1;
else //get params
FPGA_fpgadata_out_tmp8 = 2;
FPGA_setBusOutput();
FPGA_writePacket(FPGA_fpgadata_out_tmp8);
FPGA_syncAndClockRiseFall();
if (FPGA_NeedSendParams)
{
FPGA_fpgadata_sendparam();
FPGA_NeedSendParams = false;
}
else if (FPGA_NeedGetParams)
{
FPGA_fpgadata_getparam();
FPGA_NeedGetParams = false;
}
else if (FPGA_NeedRestart)
{
FPGA_restart();
}
}
// exchange IQ data with FPGA
void FPGA_fpgadata_iqclock(void)
{
if (FPGA_bus_stop)
return;
uint8_t FPGA_fpgadata_out_tmp8 = 4; //RX
VFO *current_vfo = CurrentVFO();
if (current_vfo->Mode == TRX_MODE_LOOPBACK)
return;
//data exchange
//STAGE 1
//out
if (TRX_on_TX())
FPGA_fpgadata_out_tmp8 = 3; //TX
FPGA_setBusOutput();
FPGA_writePacket(FPGA_fpgadata_out_tmp8);
FPGA_syncAndClockRiseFall();
if (TRX_on_TX())
FPGA_fpgadata_sendiq();
else
FPGA_fpgadata_getiq();
}
// send parameters
static inline void FPGA_fpgadata_sendparam(void)
{
uint8_t FPGA_fpgadata_out_tmp8 = 0;
VFO *current_vfo = CurrentVFO();
//STAGE 2
//out PTT+PREAMP
uint8_t att_val = (uint8_t)TRX.ATT_DB;
bitWrite(FPGA_fpgadata_out_tmp8, 0, (!TRX_on_TX() && current_vfo->Mode != TRX_MODE_LOOPBACK)); //RX
bitWrite(FPGA_fpgadata_out_tmp8, 1, TRX.ADC_Driver);
if(TRX.ATT)
{
bitWrite(FPGA_fpgadata_out_tmp8, 2, 0); //att0.5
bitWrite(FPGA_fpgadata_out_tmp8, 3, (att_val >> 0) & 0x1); //att1
bitWrite(FPGA_fpgadata_out_tmp8, 4, (att_val >> 1) & 0x1); //att2
bitWrite(FPGA_fpgadata_out_tmp8, 5, (att_val >> 2) & 0x1); //att4
bitWrite(FPGA_fpgadata_out_tmp8, 6, (att_val >> 3) & 0x1); //att8
bitWrite(FPGA_fpgadata_out_tmp8, 7, (att_val >> 4) & 0x1); //att16
}
FPGA_writePacket(FPGA_fpgadata_out_tmp8);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 3
//out RX1-FREQ
FPGA_writePacket(((TRX_freq_phrase & (0XFF << 16)) >> 16));
FPGA_clockRise();
FPGA_clockFall();
//STAGE 4
//OUT RX1-FREQ
FPGA_writePacket(((TRX_freq_phrase & (0XFF << 8)) >> 8));
FPGA_clockRise();
FPGA_clockFall();
//STAGE 5
//OUT RX1-FREQ
FPGA_writePacket(TRX_freq_phrase & 0XFF);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 9
//OUT CIC-GAIN
FPGA_writePacket(CALIBRATE.CIC_GAINER_val);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 10
//OUT CICCOMP-GAIN
FPGA_writePacket(CALIBRATE.CICFIR_GAINER_val);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 11
//OUT TX-CICCOMP-GAIN
FPGA_writePacket(CALIBRATE.TXCICFIR_GAINER_val);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 12
//OUT DAC-GAIN
FPGA_writePacket(CALIBRATE.DAC_GAINER_val);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 13
//out TX-FREQ
FPGA_writePacket(((TRX_freq_phrase_tx & (0XFF << 16)) >> 16));
FPGA_clockRise();
FPGA_clockFall();
//STAGE 14
//OUT TX-FREQ
FPGA_writePacket(((TRX_freq_phrase_tx & (0XFF << 8)) >> 8));
FPGA_clockRise();
FPGA_clockFall();
//STAGE 15
//OUT TX-FREQ
FPGA_writePacket(TRX_freq_phrase_tx & 0XFF);
FPGA_clockRise();
FPGA_clockFall();
//STAGE 16
//out BPF
FPGA_fpgadata_out_tmp8 = 0;
if(CurrentVFO()->Freq >= 1500000 && CurrentVFO()->Freq <= 2400000) //160m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 0); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 0); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 1); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 0); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 0); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 0); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 0); //LPF3
}
else if(CurrentVFO()->Freq >= 2400000 && CurrentVFO()->Freq <= 4500000) //80m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 1); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 0); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 1); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 0); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 1); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 0); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 0); //LPF3
}
else if(CurrentVFO()->Freq >= 4500000 && CurrentVFO()->Freq <= 7500000) //40m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 0); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 1); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 1); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 0); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 0); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 1); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 0); //LPF3
}
else if(CurrentVFO()->Freq >= 7500000 && CurrentVFO()->Freq <= 12000000) //30m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 1); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 1); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 1); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 0); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 1); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 1); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 0); //LPF3
}
else if(CurrentVFO()->Freq >= 12000000 && CurrentVFO()->Freq <= 14800000) //20m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 0); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 0); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 0); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 1); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 0); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 0); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 1); //LPF3
}
else if(CurrentVFO()->Freq >= 14800000 && CurrentVFO()->Freq <= 22000000) //17,15m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 1); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 0); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 0); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 1); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 1); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 0); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 1); //LPF3
}
else if(CurrentVFO()->Freq >= 22000000 && CurrentVFO()->Freq <= 32000000) //12,10m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 0); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 1); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 0); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 1); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 0); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 1); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 1); //LPF3
}
else //if(CurrentVFO()->Freq >= 0 && CurrentVFO()->Freq <= 53000000) //6m
{
bitWrite(FPGA_fpgadata_out_tmp8, 0, 1); //BPF_A
bitWrite(FPGA_fpgadata_out_tmp8, 1, 1); //BPF_B
bitWrite(FPGA_fpgadata_out_tmp8, 3, 0); //BPF_OE1
bitWrite(FPGA_fpgadata_out_tmp8, 2, 1); //BPF_OE2
bitWrite(FPGA_fpgadata_out_tmp8, 4, 1); //LPF1
bitWrite(FPGA_fpgadata_out_tmp8, 5, 1); //LPF2
bitWrite(FPGA_fpgadata_out_tmp8, 6, 1); //LPF3
}
//bitWrite(FPGA_fpgadata_out_tmp8, 7, 0); //unused
FPGA_writePacket(FPGA_fpgadata_out_tmp8);
FPGA_clockRise();
FPGA_clockFall();
}
// get parameters
static inline void FPGA_fpgadata_getparam(void)
{
register uint8_t FPGA_fpgadata_in_tmp8 = 0;
register int32_t FPGA_fpgadata_in_tmp32 = 0;
FPGA_setBusInput();
//STAGE 2
FPGA_clockRise();
FPGA_fpgadata_in_tmp8 = FPGA_readPacket;
TRX_ADC_OTR = bitRead(FPGA_fpgadata_in_tmp8, 0);
TRX_DAC_OTR = bitRead(FPGA_fpgadata_in_tmp8, 1);
FPGA_clockFall();
//STAGE 3
FPGA_clockRise();
FPGA_fpgadata_in_tmp8 = FPGA_readPacket;
FPGA_clockFall();
//STAGE 4
FPGA_clockRise();
TRX_ADC_MINAMPLITUDE = (int16_t)(((FPGA_fpgadata_in_tmp8 << 8) & 0xFF00) | FPGA_readPacket);
bitWrite(TRX_ADC_MINAMPLITUDE, 15, bitRead(TRX_ADC_MINAMPLITUDE, 11)); //EXTEND 12 To 16 BITS
bitWrite(TRX_ADC_MINAMPLITUDE, 14, bitRead(TRX_ADC_MINAMPLITUDE, 11));
bitWrite(TRX_ADC_MINAMPLITUDE, 13, bitRead(TRX_ADC_MINAMPLITUDE, 11));
bitWrite(TRX_ADC_MINAMPLITUDE, 12, bitRead(TRX_ADC_MINAMPLITUDE, 11));
FPGA_clockFall();
//STAGE 5
FPGA_clockRise();
FPGA_fpgadata_in_tmp8 = FPGA_readPacket;
FPGA_clockFall();
//STAGE 6
FPGA_clockRise();
TRX_ADC_MAXAMPLITUDE = (int16_t)(((FPGA_fpgadata_in_tmp8 << 8) & 0xFF00) | FPGA_readPacket);
bitWrite(TRX_ADC_MAXAMPLITUDE, 15, bitRead(TRX_ADC_MAXAMPLITUDE, 11)); //EXTEND 12 To 16 BITS
bitWrite(TRX_ADC_MAXAMPLITUDE, 14, bitRead(TRX_ADC_MAXAMPLITUDE, 11));
bitWrite(TRX_ADC_MAXAMPLITUDE, 13, bitRead(TRX_ADC_MAXAMPLITUDE, 11));
bitWrite(TRX_ADC_MAXAMPLITUDE, 12, bitRead(TRX_ADC_MAXAMPLITUDE, 11));
FPGA_clockFall();
}
// get IQ data
static inline void FPGA_fpgadata_getiq(void)
{
register int16_t FPGA_fpgadata_in_tmp16 = 0;
float32_t* FFTInput_I_current = FFT_buff_current ? (float32_t*)&FFTInput_I_B : (float32_t*)&FFTInput_I_A;
float32_t* FFTInput_Q_current = FFT_buff_current ? (float32_t*)&FFTInput_Q_B : (float32_t*)&FFTInput_Q_A;
float32_t FPGA_fpgadata_in_float32 = 0;
FPGA_samples++;
FPGA_setBusInput();
//Q RX
//STAGE 2
FPGA_clockRise();
FPGA_fpgadata_in_tmp16 = (FPGA_readPacket << 8);
FPGA_clockFall();
//STAGE 3
FPGA_clockRise();
FPGA_fpgadata_in_tmp16 |= (FPGA_readPacket);
/*static float32_t min = 0;
static float32_t max = 0;
if((float32_t)FPGA_fpgadata_in_tmp16 < min)
min = (float32_t)FPGA_fpgadata_in_tmp16;
if((float32_t)FPGA_fpgadata_in_tmp16 > max)
max = (float32_t)FPGA_fpgadata_in_tmp16;
if(FPGA_samples == 100)
{
sendToDebug_float32(min, false);
sendToDebug_float32(max, false);
sendToDebug_newline();
min = 0;
max = 0;
}*/
FPGA_fpgadata_in_float32 = (float32_t)FPGA_fpgadata_in_tmp16 / 32768.0f;
if (TRX_RX_IQ_swap)
{
FFTInput_I_current[FFT_buff_index] = FPGA_fpgadata_in_float32;
FPGA_Audio_Buffer_RX_I[FPGA_Audio_RXBuffer_Index] = FPGA_fpgadata_in_float32;
}
else
{
FFTInput_Q_current[FFT_buff_index] = FPGA_fpgadata_in_float32;
FPGA_Audio_Buffer_RX_Q[FPGA_Audio_RXBuffer_Index] = FPGA_fpgadata_in_float32;
}
FPGA_clockFall();
//I RX1
//STAGE 4
FPGA_clockRise();
FPGA_fpgadata_in_tmp16 = (FPGA_readPacket << 8);
FPGA_clockFall();
//STAGE 5
FPGA_clockRise();
FPGA_fpgadata_in_tmp16 |= (FPGA_readPacket);
FPGA_fpgadata_in_float32 = (float32_t)FPGA_fpgadata_in_tmp16 / 32768.0f;
if (TRX_RX_IQ_swap)
{
FFTInput_Q_current[FFT_buff_index] = FPGA_fpgadata_in_float32;
FPGA_Audio_Buffer_RX_Q[FPGA_Audio_RXBuffer_Index] = FPGA_fpgadata_in_float32;
}
else
{
FFTInput_I_current[FFT_buff_index] = FPGA_fpgadata_in_float32;
FPGA_Audio_Buffer_RX_I[FPGA_Audio_RXBuffer_Index] = FPGA_fpgadata_in_float32;
}
FPGA_clockFall();
FPGA_Audio_RXBuffer_Index++;
if (FPGA_Audio_RXBuffer_Index == FPGA_RX_IQ_BUFFER_SIZE)
FPGA_Audio_RXBuffer_Index = 0;
FFT_buff_index++;
if (FFT_buff_index >= FFT_SIZE)
{
FFT_buff_index = 0;
FFT_new_buffer_ready = true;
FFT_buff_current = !FFT_buff_current;
}
FPGA_clockFall();
}
// send IQ data
static inline void FPGA_fpgadata_sendiq(void)
{
q15_t FPGA_fpgadata_out_q_tmp16 = 0;
q15_t FPGA_fpgadata_out_i_tmp16 = 0;
q15_t FPGA_fpgadata_out_tmp_tmp16 = 0;
arm_float_to_q15((float32_t *)&FPGA_Audio_SendBuffer_Q[FPGA_Audio_TXBuffer_Index], &FPGA_fpgadata_out_q_tmp16, 1);
arm_float_to_q15((float32_t *)&FPGA_Audio_SendBuffer_I[FPGA_Audio_TXBuffer_Index], &FPGA_fpgadata_out_i_tmp16, 1);
FPGA_samples++;
if (TRX_TX_IQ_swap)
{
FPGA_fpgadata_out_tmp_tmp16 = FPGA_fpgadata_out_i_tmp16;
FPGA_fpgadata_out_i_tmp16 = FPGA_fpgadata_out_q_tmp16;
FPGA_fpgadata_out_q_tmp16 = FPGA_fpgadata_out_tmp_tmp16;
}
//out Q
//STAGE 2
FPGA_writePacket((FPGA_fpgadata_out_q_tmp16 >> 8) & 0xFF);
//clock
FPGA_clockRise();
//clock
FPGA_clockFall();
//STAGE 3
FPGA_writePacket((FPGA_fpgadata_out_q_tmp16 >> 0) & 0xFF);
//clock
FPGA_clockRise();
//clock
FPGA_clockFall();
//out I
//STAGE 4
FPGA_writePacket((FPGA_fpgadata_out_i_tmp16 >> 8) & 0xFF);
//clock
FPGA_clockRise();
//clock
FPGA_clockFall();
//STAGE 5
FPGA_writePacket((FPGA_fpgadata_out_i_tmp16 >> 0) & 0xFF);
//clock
FPGA_clockRise();
//clock
FPGA_clockFall();
FPGA_Audio_TXBuffer_Index++;
if (FPGA_Audio_TXBuffer_Index == FPGA_TX_IQ_BUFFER_SIZE)
{
if (Processor_NeedTXBuffer)
{
FPGA_Buffer_underrun = true;
FPGA_Audio_TXBuffer_Index--;
}
else
{
FPGA_Audio_TXBuffer_Index = 0;
FPGA_Audio_Buffer_State = true;
Processor_NeedTXBuffer = true;
}
}
else if (FPGA_Audio_TXBuffer_Index == FPGA_TX_IQ_BUFFER_HALF_SIZE)
{
if (Processor_NeedTXBuffer)
{
FPGA_Buffer_underrun = true;
FPGA_Audio_TXBuffer_Index--;
}
else
{
FPGA_Audio_Buffer_State = false;
Processor_NeedTXBuffer = true;
}
}
}
// switch the bus to input
static inline void FPGA_setBusInput(void)
{
// Configure IO Direction mode (Input)
/*register uint32_t temp = GPIOA->MODER;
temp &= ~(GPIO_MODER_MODE0 << (0 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (0 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (1 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (1 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (2 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (2 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (3 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (3 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (4 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (4 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (5 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (5 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (6 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (6 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (7 * 2U));
temp |= ((GPIO_MODE_INPUT & 0x00000003U) << (7 * 2U));
sendToDebug_uint32(temp,false);
GPIOA->MODER = temp;*/
GPIOA->MODER = -1431764992;
__asm("nop");__asm("nop");__asm("nop");
}
// switch bus to pin
static inline void FPGA_setBusOutput(void)
{
// Configure IO Direction mode (Output)
/*uint32_t temp = GPIOA->MODER;
temp &= ~(GPIO_MODER_MODE0 << (0 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (0 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (1 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (1 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (2 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (2 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (3 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (3 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (4 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (4 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (5 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (5 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (6 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (6 * 2U));
temp &= ~(GPIO_MODER_MODE0 << (7 * 2U));
temp |= ((GPIO_MODE_OUTPUT_PP & 0x00000003U) << (7 * 2U));
sendToDebug_uint32(temp,false);
GPIOA->MODER = temp;*/
GPIOA->MODER = -1431743147;
__asm("nop");__asm("nop");__asm("nop");
}
// raise the CLK signal
static inline void FPGA_clockRise(void)
{
FPGA_CLK_GPIO_Port->BSRR = FPGA_CLK_Pin;
__asm("nop");__asm("nop");__asm("nop");
}
// remove CLK signal
static inline void FPGA_clockFall(void)
{
FPGA_CLK_GPIO_Port->BSRR = (FPGA_CLK_Pin << 16U);
__asm("nop");__asm("nop");__asm("nop");
}
// raise CLK and SYNC signal, then lower
static inline void FPGA_syncAndClockRiseFall(void)
{
FPGA_CLK_GPIO_Port->BSRR = FPGA_SYNC_Pin;
FPGA_CLK_GPIO_Port->BSRR = FPGA_CLK_Pin;
FPGA_CLK_GPIO_Port->BSRR = (FPGA_SYNC_Pin << 16U) | (FPGA_CLK_Pin << 16U);
__asm("nop");__asm("nop");__asm("nop");
}

Wyświetl plik

@ -1,62 +0,0 @@
#ifndef FPGA_h
#define FPGA_h
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#include "fft.h"
#include "audio_processor.h"
#include "settings.h"
#define FPGA_flash_size 0x200000
#define FPGA_flash_file_offset (0xA0 - 1)
#define FPGA_sector_size (64 * 1024)
#define FPGA_page_size 256
#define FPGA_FLASH_COMMAND_DELAY \
for (uint32_t wait = 0; wait < 50; wait++) \
__asm("nop"); //50
#define FPGA_FLASH_WRITE_DELAY \
for (uint32_t wait = 0; wait < 500; wait++) \
__asm("nop"); //500
#define FPGA_FLASH_READ_DELAY \
for (uint32_t wait = 0; wait < 50; wait++) \
__asm("nop"); //50
#define FPGA_writePacket(value) (FPGA_BUS_D0_GPIO_Port->BSRR = (value) | 0xFF0000)
#define FPGA_readPacket (FPGA_BUS_D0_GPIO_Port->IDR & 0xFF)
//Micron M25P80 Serial Flash COMMANDS:
#define M25P80_WRITE_ENABLE 0x06
#define M25P80_WRITE_DISABLE 0x04
#define M25P80_READ_IDENTIFICATION 0x9F
#define M25P80_READ_IDENTIFICATION2 0x9E
#define M25P80_READ_STATUS_REGISTER 0x05
#define M25P80_WRITE_STATUS_REGISTER 0x01
#define M25P80_READ_DATA_BYTES 0x03
#define M25P80_READ_DATA_BYTES_at_HIGHER_SPEED 0x0B
#define M25P80_PAGE_PROGRAM 0x02
#define M25P80_SECTOR_ERASE 0xD8
#define M25P80_BULK_ERASE 0xC7
#define M25P80_DEEP_POWER_DOWN 0xB9
#define M25P80_RELEASE_from_DEEP_POWER_DOWN 0xAB
//Public variables
extern volatile uint32_t FPGA_samples; // counter of the number of samples when exchanging with FPGA
extern volatile bool FPGA_Buffer_underrun; // flag of lack of data from FPGA
extern volatile bool FPGA_NeedSendParams; // flag of the need to send parameters to FPGA
extern volatile bool FPGA_NeedGetParams; // flag of the need to get parameters from FPGA
extern volatile bool FPGA_NeedRestart; // flag of necessity to restart FPGA modules
extern volatile float32_t FPGA_Audio_Buffer_RX_Q[FPGA_RX_IQ_BUFFER_SIZE]; // FPGA buffers
extern volatile float32_t FPGA_Audio_Buffer_RX_I[FPGA_RX_IQ_BUFFER_SIZE];
extern volatile float32_t FPGA_Audio_SendBuffer_Q[FPGA_TX_IQ_BUFFER_SIZE];
extern volatile float32_t FPGA_Audio_SendBuffer_I[FPGA_TX_IQ_BUFFER_SIZE];
extern uint_fast16_t FPGA_Audio_RXBuffer_Index; // current index in FPGA buffers
extern uint_fast16_t FPGA_Audio_TXBuffer_Index; // current index in FPGA buffers
extern bool FPGA_Audio_Buffer_State; // buffer state, half or full full true - compleate; false - half
//Public methods
extern void FPGA_Init(void); // initialize exchange with FPGA
extern void FPGA_fpgadata_iqclock(void); // exchange IQ data with FPGA
extern void FPGA_fpgadata_stuffclock(void); // exchange parameters with FPGA
extern void FPGA_restart(void); // restart FPGA modules
#endif

Wyświetl plik

@ -1,817 +0,0 @@
#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_MODE_P(void);
static void FRONTPANEL_BUTTONHANDLER_MODE_N(void);
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_PRE(void);
static void FRONTPANEL_BUTTONHANDLER_ATT(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_RF_POWER(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_VOLUME(void);
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 = 7, .name = "", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used
{.port = 1, .channel = 6, .name = "", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = NULL, .holdHandler = NULL}, //not used
{.port = 1, .channel = 5, .name = "MODE", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_MODE_N, .holdHandler = FRONTPANEL_BUTTONHANDLER_MODE_P}, //SB6
{.port = 1, .channel = 0, .name = "BAND", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BAND_P, .holdHandler = FRONTPANEL_BUTTONHANDLER_BAND_N}, //SB1
};
static PERIPH_FrontPanel_Button PERIPH_FrontPanel_BottomScroll_Buttons[BOTTOM_SCROLLBUTTONS_GROUPS_COUNT][4] = {
{
{.port = 1, .channel = 1, .name = "PRE", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_PRE, .holdHandler = FRONTPANEL_BUTTONHANDLER_PRE}, //SB2
{.port = 1, .channel = 2, .name = "ATT", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_ATT, .holdHandler = FRONTPANEL_BUTTONHANDLER_ATTHOLD}, //SB3
{.port = 1, .channel = 3, .name = "BW", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_BW, .holdHandler = FRONTPANEL_BUTTONHANDLER_HPF}, //SB4
{.port = 1, .channel = 4, .name = "A/B", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_AsB, .holdHandler = FRONTPANEL_BUTTONHANDLER_ArB}, //SB5
},
{
{.port = 1, .channel = 1, .name = "POWER", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER, .holdHandler = FRONTPANEL_BUTTONHANDLER_RF_POWER}, //SB2
{.port = 1, .channel = 2, .name = "TUNE", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_TUNE, .holdHandler = FRONTPANEL_BUTTONHANDLER_TUNE}, //SB3
{.port = 1, .channel = 3, .name = "NOTCH", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_NOTCH, .holdHandler = FRONTPANEL_BUTTONHANDLER_NOTCH}, //SB4
{.port = 1, .channel = 4, .name = "FAST", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_FAST, .holdHandler = FRONTPANEL_BUTTONHANDLER_FAST}, //SB5
},
{
{.port = 1, .channel = 1, .name = "AGC", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_AGC, .holdHandler = FRONTPANEL_BUTTONHANDLER_AGC_SPEED}, //SB2
{.port = 1, .channel = 2, .name = "CLAR", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_CLAR, .holdHandler = FRONTPANEL_BUTTONHANDLER_CLAR}, //SB3
{.port = 1, .channel = 3, .name = "MUTE", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_MUTE, .holdHandler = FRONTPANEL_BUTTONHANDLER_MUTE}, //SB4
{.port = 1, .channel = 4, .name = "LOCK", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_LOCK, .holdHandler = FRONTPANEL_BUTTONHANDLER_LOCK}, //SB5
},
{
{.port = 1, .channel = 1, .name = "VOLUME", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_VOLUME, .holdHandler = FRONTPANEL_BUTTONHANDLER_VOLUME}, //SB2
{.port = 1, .channel = 2, .name = "BANDMAP", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP, .holdHandler = FRONTPANEL_BUTTONHANDLER_BANDMAP}, //SB3
{.port = 1, .channel = 3, .name = "WPM", .state = false, .prev_state = false, .work_in_menu = true, .clickHandler = FRONTPANEL_BUTTONHANDLER_WPM, .holdHandler = FRONTPANEL_BUTTONHANDLER_WPM}, //SB4
{.port = 1, .channel = 4, .name = "KEYER", .state = false, .prev_state = false, .work_in_menu = false, .clickHandler = FRONTPANEL_BUTTONHANDLER_KEYER, .holdHandler = FRONTPANEL_BUTTONHANDLER_KEYER}, //SB5
},
};
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)
{
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
FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? 1 : -1);
}
else
{ // otherwise B changed its state first - counterclockwise rotation
FRONTPANEL_ENCODER2_Rotated(CALIBRATE.ENCODER2_INVERT ? -1 : 1);
}
}
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
{
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;
}
}
void FRONTPANEL_check_ENC2SW(void)
{
static bool ENC2SW_Last = true;
if (TRX.Locked)
return;
bool ENC2SW_Now = HAL_GPIO_ReadPin(ENC2_SW_GPIO_Port, ENC2_SW_Pin);
if (ENC2SW_Last != ENC2SW_Now)
{
ENC2SW_Last = ENC2SW_Now;
if (!ENC2SW_Now)
{
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);*/
//set state
if (mcp3008_value < MCP3008_THRESHOLD)
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;
}
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.StatusInfoGUI = 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;
}
static 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;
}
static 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()->LPF_Filter_Width)
{
CurrentVFO()->NotchFC = CurrentVFO()->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()->LPF_Filter_Width)
CurrentVFO()->NotchFC = CurrentVFO()->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;
}

Wyświetl plik

@ -1,32 +0,0 @@
#ifndef FRONT_UNIT_h
#define FRONT_UNIT_h
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#define MCP3008_THRESHOLD 100
#define BOTTOM_SCROLLBUTTONS_GROUPS_COUNT 4
typedef struct
{
uint8_t port;
uint8_t channel;
bool state;
bool prev_state;
uint32_t start_hold_time;
bool afterhold;
bool work_in_menu;
char name[16];
void (*clickHandler)(void);
void (*holdHandler)(void);
} PERIPH_FrontPanel_Button;
extern PERIPH_FrontPanel_Button* PERIPH_FrontPanel_BottomScroll_Buttons_Active;
extern void FRONTPANEL_ENCODER_checkRotate(void);
extern void FRONTPANEL_ENCODER2_checkRotate(void);
extern void FRONTPANEL_check_ENC2SW(void);
extern void FRONTPANEL_Init(void);
extern void FRONTPANEL_Process(void);
#endif

Wyświetl plik

@ -1,447 +0,0 @@
#include "functions.h"
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdlib.h>
#include <math.h>
#include "arm_math.h"
#include "fpga.h"
#include "trx_manager.h"
#include "usbd_debug_if.h"
#include "usbd_cat_if.h"
#include "lcd.h"
CPULOAD_t CPU_LOAD = {0};
static bool SPI_busy = false;
volatile bool SPI_process = false;
void dma_memcpy32(uint32_t *dest, uint32_t *src, uint32_t len)
{
if (len == 0)
return;
HAL_DMA_Start(&hdma_memtomem_dma2_stream0, (uint32_t)src, (uint32_t)dest, len);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream0, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
}
void readFromCircleBuffer32(uint32_t *source, uint32_t *dest, uint32_t index, uint32_t length, uint32_t words_to_read)
{
if (index >= words_to_read)
{
dma_memcpy32(&dest[0], &source[index - words_to_read], words_to_read);
}
else
{
uint_fast16_t prev_part = words_to_read - index;
dma_memcpy32(&dest[0], &source[length - prev_part], prev_part);
dma_memcpy32(&dest[prev_part], &source[0], (words_to_read - prev_part));
}
}
void readHalfFromCircleUSBBuffer24Bit(uint8_t *source, int32_t *dest, uint32_t index, uint32_t length)
{
uint_fast16_t halflen = length / 2;
uint_fast16_t readed_index = 0;
if (index >= halflen)
{
for (uint_fast16_t i = (index - halflen); i < index; i++)
{
dest[readed_index] = (source[i * 3 + 0] << 8) | (source[i * 3 + 1] << 16) | (source[i * 3 + 2] << 24);
readed_index++;
}
}
else
{
uint_fast16_t prev_part = halflen - index;
for (uint_fast16_t i = (length - prev_part); i < length; i++)
{
dest[readed_index] = (source[i * 3 + 0] << 8) | (source[i * 3 + 1] << 16) | (source[i * 3 + 2] << 24);
readed_index++;
}
for (uint_fast16_t i = 0; i < (halflen - prev_part); i++)
{
dest[readed_index] = (source[i * 3 + 0] << 8) | (source[i * 3 + 1] << 16) | (source[i * 3 + 2] << 24);
readed_index++;
}
}
}
void sendToDebug_str(char *data)
{
if (SWD_DEBUG_ENABLED)
printf("%s", data);
if (USB_DEBUG_ENABLED)
DEBUG_Transmit_FIFO((uint8_t *)data, (uint16_t)strlen(data));
if (LCD_DEBUG_ENABLED)
{
static uint16_t dbg_lcd_y = 10;
LCDDriver_printText(data, 0, dbg_lcd_y, COLOR_RED, BG_COLOR, 1);
dbg_lcd_y += 9;
if(dbg_lcd_y >= LCD_HEIGHT)
dbg_lcd_y = 0;
}
}
void sendToDebug_strln(char *data)
{
sendToDebug_str(data);
sendToDebug_newline();
}
void sendToDebug_str2(char *data1, char *data2)
{
sendToDebug_str(data1);
sendToDebug_str(data2);
}
void sendToDebug_str3(char *data1, char *data2, char *data3)
{
sendToDebug_str(data1);
sendToDebug_str(data2);
sendToDebug_str(data3);
}
void sendToDebug_newline(void)
{
sendToDebug_str("\n");
}
void sendToDebug_flush(void)
{
uint_fast16_t tryes = 0;
while (DEBUG_Transmit_FIFO_Events() == USBD_BUSY && tryes < 512)
tryes++;
}
void sendToDebug_uint8(uint8_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%d", data);
else
sprintf(tmp, "%d\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_hex(uint8_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%02X", data);
else
sprintf(tmp, "%02X\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_uint16(uint16_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%d", data);
else
sprintf(tmp, "%d\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_uint32(uint32_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%u", data);
else
sprintf(tmp, "%u\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_int8(int8_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%d", data);
else
sprintf(tmp, "%d\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_int16(int16_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%d", data);
else
sprintf(tmp, "%d\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_int32(int32_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%d", data);
else
sprintf(tmp, "%d\n", data);
sendToDebug_str(tmp);
}
void sendToDebug_float32(float32_t data, bool _inline)
{
char tmp[50] = ""; //-V808
if (_inline)
sprintf(tmp, "%f", (double)data);
else
sprintf(tmp, "%f\n", (double)data);
sendToDebug_str(tmp);
}
uint32_t getRXPhraseFromFrequency(int32_t freq) // calculate the frequency from the phrase for FPGA (RX1 / RX2)
{
if (freq < 0)
return 0;
bool inverted = false;
int32_t _freq = freq;
if (_freq > ADC_CLOCK / 2) //Go Nyquist
{
while (_freq > (ADC_CLOCK / 2))
{
_freq -= (ADC_CLOCK / 2);
inverted = !inverted;
}
if (inverted)
{
_freq = (ADC_CLOCK / 2) - _freq;
}
}
TRX_RX_IQ_swap = inverted;
double res = round(((double)_freq / ADC_CLOCK) * 4194304); //freq in hz/oscil in hz*2^bits;
return (uint32_t)res;
}
uint32_t getTXPhraseFromFrequency(int32_t freq) // calculate the frequency from the phrase for FPGA (TX)
{
if (freq < 0)
return 0;
bool inverted = false;
TRX_TX_IQ_swap = false;
double res = round(((double)freq / DAC_CLOCK) * 4194304); //freq in hz/oscil in hz*2^bits = (freq/48000000)*4194304;
return (uint32_t)res;
}
void addSymbols(char *dest, char *str, uint_fast8_t length, char *symbol, bool toEnd) // add zeroes
{
char res[50] = "";
strcpy(res, str);
while (strlen(res) < length)
{
if (toEnd)
strcat(res, symbol);
else
{
char tmp[50] = "";
strcat(tmp, symbol);
strcat(tmp, res);
strcpy(res, tmp);
}
}
strcpy(dest, res);
}
float32_t log10f_fast(float32_t X)
{
float32_t Y, F;
int32_t E;
F = frexpf(fabsf(X), &E);
Y = 1.23149591368684f;
Y *= F;
Y += -4.11852516267426f;
Y *= F;
Y += 6.02197014179219f;
Y *= F;
Y += -3.13396450166353f;
Y += E;
return (Y * 0.3010299956639812f);
}
float32_t db2rateV(float32_t i) // from decibels to times (for voltage)
{
return powf(10.0f, (i / 20.0f));
}
float32_t db2rateP(float32_t i) // from decibels to times (for power)
{
return powf(10.0f, (i / 10.0f));
}
float32_t rate2dbV(float32_t i) // times to decibels (for voltage)
{
return 20 * log10f_fast(i);
}
float32_t rate2dbP(float32_t i) // from times to decibels (for power)
{
return 10 * log10f_fast(i);
}
#define VOLUME_LOW_DB (-40.0f)
#define VOLUME_EPSILON powf(10.0f, (VOLUME_LOW_DB / 20.0f))
float32_t volume2rate(float32_t i) // from the position of the volume knob to the gain
{
if (i < (2.0f / 100.f)) //mute zone
return 0.0f;
return powf(VOLUME_EPSILON, (1.0f - i));
}
void shiftTextLeft(char *string, uint_fast16_t shiftLength)
{
uint_fast16_t size = strlen(string);
if (shiftLength >= size)
{
memset(string, '\0', size);
return;
}
for (uint_fast16_t i = 0; i < size - shiftLength; i++)
{
string[i] = string[i + shiftLength];
string[i + shiftLength] = '\0';
}
}
float32_t getMaxTXAmplitudeOnFreq(uint32_t freq)
{
if (freq > MAX_TX_FREQ_HZ)
return 0.0f;
uint8_t nyquist = freq / (DAC_CLOCK / 2);
if (nyquist == 0)
{
if(freq < 2000000)
return (float32_t)CALIBRATE.rf_out_power_lf / 100.0f * (float32_t)MAX_TX_AMPLITUDE;
if(freq < 5000000)
return (float32_t)CALIBRATE.rf_out_power_hf_low / 100.0f * (float32_t)MAX_TX_AMPLITUDE;
if(freq < 30000000)
return (float32_t)CALIBRATE.rf_out_power_hf / 100.0f * (float32_t)MAX_TX_AMPLITUDE;
return (float32_t)CALIBRATE.rf_out_power_hf_high / 100.0f * (float32_t)MAX_TX_AMPLITUDE;
}
if (nyquist == 1)
return (float32_t)CALIBRATE.rf_out_power_vhf / 100.0f * (float32_t)MAX_TX_AMPLITUDE;
return 0.0f;
}
float32_t generateSin(float32_t amplitude, uint32_t index, uint32_t samplerate, uint32_t freq)
{
float32_t ret = amplitude * arm_sin_f32(((float32_t)index / (float32_t)samplerate) * PI * 2.0f * (float32_t)freq);
return ret;
}
static uint32_t CPULOAD_startWorkTime = 0;
static uint32_t CPULOAD_startSleepTime = 0;
static uint32_t CPULOAD_WorkingTime = 0;
static uint32_t CPULOAD_SleepingTime = 0;
static uint32_t CPULOAD_SleepCounter = 0;
static bool CPULOAD_status = true; // true - wake up ; false - sleep
void CPULOAD_Init(void)
{
//DBGMCU->CR |= (DBGMCU_CR_DBG_SLEEPD1_Msk | DBGMCU_CR_DBG_STOPD1_Msk | DBGMCU_CR_DBG_STANDBYD1_Msk);
// allow using the counter
CoreDebug->DEMCR |= CoreDebug_DEMCR_TRCENA_Msk;
// start the counter
DWT->CTRL |= DWT_CTRL_CYCCNTENA_Msk;
// zero the value of the counting register
DWT->CYCCNT = 0;
CPULOAD_status = true;
}
void CPULOAD_GoToSleepMode(void)
{
// Add to working time
CPULOAD_WorkingTime += DWT->CYCCNT - CPULOAD_startWorkTime;
// Save count cycle time
CPULOAD_SleepCounter++;
CPULOAD_startSleepTime = DWT->CYCCNT;
CPULOAD_status = false;
// Go to sleep mode Wait for wake up interrupt
__WFI();
}
void CPULOAD_WakeUp(void)
{
if (CPULOAD_status)
return;
CPULOAD_status = true;
// Increase number of sleeping time in CPU cycles
CPULOAD_SleepingTime += DWT->CYCCNT - CPULOAD_startSleepTime;
// Save current time to get number of working CPU cycles
CPULOAD_startWorkTime = DWT->CYCCNT;
}
void CPULOAD_Calc(void)
{
// Save values
CPU_LOAD.SCNT = CPULOAD_SleepingTime;
CPU_LOAD.WCNT = CPULOAD_WorkingTime;
CPU_LOAD.SINC = CPULOAD_SleepCounter;
CPU_LOAD.Load = ((float)CPULOAD_WorkingTime / (float)(CPULOAD_SleepingTime + CPULOAD_WorkingTime) * 100);
if (CPU_LOAD.SCNT == 0)
{
CPU_LOAD.Load = 100;
}
if (CPU_LOAD.SCNT == 0 && CPU_LOAD.WCNT == 0)
{
CPU_LOAD.Load = 255;
//CPULOAD_Init();
}
// Reset time
CPULOAD_SleepingTime = 0;
CPULOAD_WorkingTime = 0;
CPULOAD_SleepCounter = 0;
}
inline int32_t convertToSPIBigEndian(int32_t in)
{
return (int32_t)(0xFFFF0000 & (uint32_t)(in << 16)) | (int32_t)(0x0000FFFF & (uint32_t)(in >> 16));
}
inline uint8_t rev8(uint8_t data)
{
uint32_t tmp = data;
return (uint8_t)(__RBIT(tmp) >> 24);
}
bool SPI_Transmit(uint8_t *out_data, uint8_t *in_data, uint16_t count, GPIO_TypeDef *CS_PORT, uint16_t CS_PIN, bool hold_cs, uint32_t prescaler)
{
if (SPI_busy)
{
sendToDebug_strln("SPI Busy");
return false;
}
//SPI speed
if(hspi2.Init.BaudRatePrescaler != prescaler)
{
hspi2.Init.BaudRatePrescaler = prescaler;
HAL_SPI_Init(&hspi2);
}
const int32_t timeout = 0x200; //HAL_MAX_DELAY
SPI_busy = true;
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_RESET);
HAL_StatusTypeDef res = 0;
if (in_data == NULL)
{
res = HAL_SPI_Transmit(&hspi2, out_data, count, timeout);
}
else if (out_data == NULL)
{
memset(in_data, 0x00, count);
res = HAL_SPI_Receive(&hspi2, in_data, count, timeout);
}
else
{
memset(in_data, 0x00, count);
res = HAL_SPI_TransmitReceive(&hspi2, out_data, in_data, count, timeout);
}
if (!hold_cs)
HAL_GPIO_WritePin(CS_PORT, CS_PIN, GPIO_PIN_SET);
SPI_busy = false;
if (res == HAL_TIMEOUT || res == HAL_ERROR)
return false;
else
return true;
}

Wyświetl plik

@ -1,141 +0,0 @@
#ifndef Functions_h
#define Functions_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <string.h>
#include <stdbool.h>
#include "profiler.h"
#pragma GCC diagnostic push
#pragma GCC diagnostic ignored "-Wimplicit-int-conversion"
#pragma GCC diagnostic ignored "-Wsign-conversion"
#include "arm_math.h"
#pragma GCC diagnostic pop
#define TRX_MODE_LSB 0
#define TRX_MODE_USB 1
#define TRX_MODE_CW_L 2
#define TRX_MODE_CW_U 3
#define TRX_MODE_NFM 4
#define TRX_MODE_WFM 5
#define TRX_MODE_AM 6
#define TRX_MODE_DIGI_L 7
#define TRX_MODE_DIGI_U 8
#define TRX_MODE_IQ 9
#define TRX_MODE_LOOPBACK 10
#define TRX_MODE_NO_TX 11
#define TRX_MODE_COUNT 12
#define IRAM1 __attribute__((section(".IRAM1"))) // 128kb IRAM1
#define IRAM2 __attribute__((section(".IRAM2"))) // 64kb IRAM2
#define BACKUP_SRAM_BANK1_ADDR (uint32_t *)(BKPSRAM_BASE)
#define BACKUP_SRAM_BANK2_ADDR (uint32_t *)(BKPSRAM_BASE+0x800) // 4kb Backup SRAM
//UINT from BINARY STRING
#define HEX__(n) 0x##n##LU
#define B8__(x) ((x & 0x0000000FLU) ? 1 : 0) + ((x & 0x000000F0LU) ? 2 : 0) + ((x & 0x00000F00LU) ? 4 : 0) + ((x & 0x0000F000LU) ? 8 : 0) + ((x & 0x000F0000LU) ? 16 : 0) + ((x & 0x00F00000LU) ? 32 : 0) + ((x & 0x0F000000LU) ? 64 : 0) + ((x & 0xF0000000LU) ? 128 : 0)
#define B8(d) ((unsigned char)B8__(HEX__(d)))
#define bitRead(value, bit) (((value) >> (bit)) & 0x01)
#define bitSet(value, bit) ((value) |= (1UL << (bit)))
#define bitClear(value, bit) ((value) &= ~(1UL << (bit)))
#define bitWrite(value, bit, bitvalue) (bitvalue ? bitSet(value, bit) : bitClear(value, bit))
#ifdef __clang__
#define isnanf __ARM_isnanf
#define isinff __ARM_isinff
#endif
#define F_PI 3.141592653589793238463f
#define SQRT2 1.41421356237f
#define ARRLENTH(x) (sizeof(x) / sizeof((x)[0]))
#define MINI_DELAY \
for (uint_fast16_t wait_i = 0; wait_i < 100; wait_i++) \
__asm("nop");
// Example of __DATE__ string: "Jul 27 2012"
// 01234567890
#define BUILD_YEAR_CH0 (__DATE__[7])
#define BUILD_YEAR_CH1 (__DATE__[8])
#define BUILD_YEAR_CH2 (__DATE__[9])
#define BUILD_YEAR_CH3 (__DATE__[10])
#define BUILD_MONTH_IS_JAN (__DATE__[0] == 'J' && __DATE__[1] == 'a' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_FEB (__DATE__[0] == 'F')
#define BUILD_MONTH_IS_MAR (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'r')
#define BUILD_MONTH_IS_APR (__DATE__[0] == 'A' && __DATE__[1] == 'p')
#define BUILD_MONTH_IS_MAY (__DATE__[0] == 'M' && __DATE__[1] == 'a' && __DATE__[2] == 'y')
#define BUILD_MONTH_IS_JUN (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'n')
#define BUILD_MONTH_IS_JUL (__DATE__[0] == 'J' && __DATE__[1] == 'u' && __DATE__[2] == 'l')
#define BUILD_MONTH_IS_AUG (__DATE__[0] == 'A' && __DATE__[1] == 'u')
#define BUILD_MONTH_IS_SEP (__DATE__[0] == 'S')
#define BUILD_MONTH_IS_OCT (__DATE__[0] == 'O')
#define BUILD_MONTH_IS_NOV (__DATE__[0] == 'N')
#define BUILD_MONTH_IS_DEC (__DATE__[0] == 'D')
#define BUILD_MONTH_CH0 \
((BUILD_MONTH_IS_OCT || BUILD_MONTH_IS_NOV || BUILD_MONTH_IS_DEC) ? '1' : '0')
#define BUILD_MONTH_CH1 \
( \
(BUILD_MONTH_IS_JAN) ? '1' : (BUILD_MONTH_IS_FEB) ? '2' : (BUILD_MONTH_IS_MAR) ? '3' : (BUILD_MONTH_IS_APR) ? '4' : (BUILD_MONTH_IS_MAY) ? '5' : (BUILD_MONTH_IS_JUN) ? '6' : (BUILD_MONTH_IS_JUL) ? '7' : (BUILD_MONTH_IS_AUG) ? '8' : (BUILD_MONTH_IS_SEP) ? '9' : (BUILD_MONTH_IS_OCT) ? '0' : (BUILD_MONTH_IS_NOV) ? '1' : (BUILD_MONTH_IS_DEC) ? '2' : /* error default */ '?')
#define BUILD_DAY_CH0 (__DATE__[4] == ' ' ? '0' : __DATE__[4] )
#define BUILD_DAY_CH1 (__DATE__[5])
// Example of __TIME__ string: "21:06:19"
// 01234567
#define BUILD_HOUR_CH0 (__TIME__[0])
#define BUILD_HOUR_CH1 (__TIME__[1])
#define BUILD_MIN_CH0 (__TIME__[3])
#define BUILD_MIN_CH1 (__TIME__[4])
#define BUILD_SEC_CH0 (__TIME__[6])
#define BUILD_SEC_CH1 (__TIME__[7])
typedef struct
{
float32_t Load; /*!< CPU load percentage */
uint32_t WCNT; /*!< Number of working cycles in one period. Meant for private use */
uint32_t SCNT; /*!< Number of sleeping cycles in one period. Meant for private use */
uint32_t SINC;
} CPULOAD_t;
extern CPULOAD_t CPU_LOAD;
volatile extern bool SPI_process;
extern void CPULOAD_Init(void);
extern void CPULOAD_GoToSleepMode(void);
extern void CPULOAD_WakeUp(void);
extern void CPULOAD_Calc(void);
extern uint32_t getRXPhraseFromFrequency(int32_t freq);
extern uint32_t getTXPhraseFromFrequency(int32_t freq);
extern void addSymbols(char *dest, char *str, uint_fast8_t length, char *symbol, bool toEnd);
extern void sendToDebug_str(char *str);
extern void sendToDebug_strln(char *data);
extern void sendToDebug_str2(char *data1, char *data2);
extern void sendToDebug_str3(char *data1, char *data2, char *data3);
extern void sendToDebug_newline(void);
extern void sendToDebug_flush(void);
extern void sendToDebug_uint8(uint8_t data, bool _inline);
extern void sendToDebug_uint16(uint16_t data, bool _inline);
extern void sendToDebug_uint32(uint32_t data, bool _inline);
extern void sendToDebug_int8(int8_t data, bool _inline);
extern void sendToDebug_int16(int16_t data, bool _inline);
extern void sendToDebug_int32(int32_t data, bool _inline);
extern void sendToDebug_float32(float32_t data, bool _inline);
extern void sendToDebug_hex(uint8_t data, bool _inline);
//extern void delay_us(uint32_t us);
extern float32_t log10f_fast(float32_t X);
extern void readFromCircleBuffer32(uint32_t *source, uint32_t *dest, uint32_t index, uint32_t length, uint32_t words_to_read);
extern void readHalfFromCircleUSBBuffer24Bit(uint8_t *source, int32_t *dest, uint32_t index, uint32_t length);
extern void dma_memcpy32(uint32_t *dest, uint32_t *src, uint32_t len);
extern float32_t db2rateV(float32_t i);
extern float32_t db2rateP(float32_t i);
extern float32_t rate2dbV(float32_t i);
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 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);
extern bool SPI_Transmit(uint8_t *out_data, uint8_t *in_data, uint16_t count, GPIO_TypeDef *CS_PORT, uint16_t CS_PIN, bool hold_cs, uint32_t prescaler);
#endif

270
Src/i2c.c
Wyświetl plik

@ -1,270 +0,0 @@
#include "stm32f4xx_hal.h"
#include "main.h"
#include "functions.h"
#include "i2c.h"
/* low level conventions:
* - SDA/SCL idle high (expected high)
* - always start with i2c_delay rather than end
*/
I2C_DEVICE I2C_WM8731 = {
.SDA_PORT = WM8731_SDA_GPIO_Port,
.SDA_PIN = WM8731_SDA_Pin,
.SCK_PORT = WM8731_SCK_GPIO_Port,
.SCK_PIN = WM8731_SCK_Pin,
.i2c_tx_addr = 0,
.i2c_tx_buf = {0},
.i2c_tx_buf_idx = 0,
.i2c_tx_buf_overflow = false,
};
#ifdef HAS_TOUCHPAD
I2C_DEVICE I2C_TOUCHPAD = {
.SDA_PORT = ENC2_CLK_GPIO_Port,
.SDA_PIN = ENC2_CLK_Pin,
.SCK_PORT = ENC2_DT_GPIO_Port,
.SCK_PIN = ENC2_DT_Pin,
.i2c_tx_addr = 0,
.i2c_tx_buf = {0},
.i2c_tx_buf_idx = 0,
.i2c_tx_buf_overflow = false,
};
#endif
static uint8_t i2c_writeOneByte(I2C_DEVICE *dev, uint8_t);
static void SDA_OUT(I2C_DEVICE *dev)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = dev->SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(dev->SDA_PORT, &GPIO_InitStruct);
}
static void SDA_IN(I2C_DEVICE *dev)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = dev->SDA_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_INPUT;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(dev->SDA_PORT, &GPIO_InitStruct);
}
static void SCK_OUT(I2C_DEVICE *dev)
{
GPIO_InitTypeDef GPIO_InitStruct;
GPIO_InitStruct.Pin = dev->SCK_PIN;
GPIO_InitStruct.Mode = GPIO_MODE_OUTPUT_OD;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
HAL_GPIO_Init(dev->SCK_PORT, &GPIO_InitStruct);
}
void i2c_start(I2C_DEVICE *dev)
{
SDA_SET;
SCK_SET;
I2C_DELAY
SDA_CLR;
I2C_DELAY
SCK_CLR;
}
void i2c_stop(I2C_DEVICE *dev)
{
SDA_OUT(dev);
SDA_CLR;
SCK_SET;
I2C_DELAY
I2C_DELAY
I2C_DELAY
I2C_DELAY
SDA_SET;
I2C_DELAY
}
bool i2c_get_ack(I2C_DEVICE *dev)
{
uint32_t time = 0;
SDA_IN(dev);
I2C_DELAY
I2C_DELAY
SCK_SET;
I2C_DELAY
I2C_DELAY
while (HAL_GPIO_ReadPin(dev->SDA_PORT, dev->SDA_PIN))
{
time++;
if (time > 50)
{
i2c_stop(dev);
return false;
}
I2C_DELAY
I2C_DELAY
}
SCK_CLR;
return true;
}
void i2c_shift_out(I2C_DEVICE *dev, uint8_t val)
{
SDA_OUT(dev);
int i;
for (i = 0; i < 8; i++)
{
I2C_DELAY
HAL_GPIO_WritePin(dev->SDA_PORT, dev->SDA_PIN, (GPIO_PinState) !!(val & (1 << (7 - i))));
SDA_OUT(dev);
I2C_DELAY
SCK_SET;
I2C_DELAY
I2C_DELAY
SCK_CLR;
}
}
/*
* Joins I2C bus as master on given SDA and SCL pins.
*/
void i2c_begin(I2C_DEVICE *dev)
{
SCK_SET;
SDA_SET;
SCK_OUT(dev);
SDA_OUT(dev);
}
void i2c_beginTransmission_u8(I2C_DEVICE *dev, uint8_t slave_address)
{
i2c_begin(dev);
dev->i2c_tx_addr = slave_address;
dev->i2c_tx_buf_idx = 0;
dev->i2c_tx_buf_overflow = false;
}
bool i2c_beginReceive_u8(I2C_DEVICE *dev, uint8_t slave_address)
{
i2c_begin(dev);
dev->i2c_tx_addr = slave_address;
dev->i2c_tx_buf_idx = 0;
dev->i2c_tx_buf_overflow = false;
i2c_start(dev);
i2c_shift_out(dev, (uint8_t)((dev->i2c_tx_addr << 1) | I2C_READ));
if (!i2c_get_ack(dev))
{
//sendToDebug_strln("no ack");
return false;
}
return true;
}
uint8_t i2c_endTransmission(I2C_DEVICE *dev)
{
if (dev->i2c_tx_buf_overflow)
return EDATA;
i2c_start(dev);
//I2C_DELAY;
i2c_shift_out(dev, (uint8_t)((dev->i2c_tx_addr << 1) | I2C_WRITE));
if (!i2c_get_ack(dev))
return ENACKADDR;
// shift out the address we're transmitting to
for (uint8_t i = 0; i < dev->i2c_tx_buf_idx; i++)
{
uint8_t ret = i2c_writeOneByte(dev, dev->i2c_tx_buf[i]);
if (ret)
return ret; // SUCCESS is 0
}
I2C_DELAY
I2C_DELAY
i2c_stop(dev);
dev->i2c_tx_buf_idx = 0;
dev->i2c_tx_buf_overflow = false;
return SUCCESS;
}
void i2c_write_u8(I2C_DEVICE *dev, uint8_t value)
{
if (dev->i2c_tx_buf_idx == WIRE_BUFSIZ)
{
dev->i2c_tx_buf_overflow = true;
return;
}
dev->i2c_tx_buf[dev->i2c_tx_buf_idx++] = value;
}
// private methods
static uint8_t i2c_writeOneByte(I2C_DEVICE *dev, uint8_t byte)
{
i2c_shift_out(dev, byte);
if (!i2c_get_ack(dev))
return ENACKTRNS;
return SUCCESS;
}
uint8_t i2c_Read_Byte(I2C_DEVICE *dev, uint8_t ack)
{
unsigned char i,receive=0;
SDA_IN(dev);
I2C_DELAY
I2C_DELAY
for(i=0;i<8;i++ )
{
SCK_CLR;
I2C_DELAY
I2C_DELAY
SCK_SET;
receive<<=1;
I2C_DELAY
I2C_DELAY
if(HAL_GPIO_ReadPin(dev->SDA_PORT,dev->SDA_PIN))
receive++;
}
if (!ack)
{
//NAck
SCK_CLR;
SDA_OUT(dev);
SDA_SET;
I2C_DELAY
I2C_DELAY
SCK_SET;
I2C_DELAY
I2C_DELAY
SCK_CLR;
SDA_IN(dev);
}
else
{
//Ack
SCK_CLR;
SDA_OUT(dev);
SDA_CLR;
I2C_DELAY
I2C_DELAY
SCK_SET;
I2C_DELAY
I2C_DELAY
SCK_CLR;
SDA_IN(dev);
}
return receive;
}

Wyświetl plik

@ -1,60 +0,0 @@
#ifndef WIRE_h
#define WIRE_h
#include "main.h"
#include "stm32f4xx_hal.h"
#include "stm32f4xx_hal_gpio.h"
#include <stdbool.h>
#define WIRE_BUFSIZ 101
/* return codes from endTransmission() */
#define SUCCESS 0 /* transmission was successful */
#define EDATA 1 /* too much data */
#define ENACKADDR 2 /* received nack on transmit of address */
#define ENACKTRNS 3 /* received nack on transmit of data */
#define EOTHER 4 /* other error */
#define I2C_WRITE 0
#define I2C_READ 1
#define I2C_DELAY \
for (uint32_t wait_i = 0; wait_i < 300; wait_i++) \
{ \
__asm("nop"); \
};
typedef struct
{
GPIO_TypeDef *SDA_PORT;
uint16_t SDA_PIN;
GPIO_TypeDef *SCK_PORT;
uint16_t SCK_PIN;
uint8_t i2c_tx_addr; /* address transmitting to */
uint8_t i2c_tx_buf[WIRE_BUFSIZ]; /* transmit buffer */
uint8_t i2c_tx_buf_idx; /* next idx available in tx_buf, -1 overflow */
bool i2c_tx_buf_overflow;
} I2C_DEVICE;
extern I2C_DEVICE I2C_WM8731;
#ifdef HAS_TOUCHPAD
extern I2C_DEVICE I2C_TOUCHPAD;
#endif
#define SDA_SET HAL_GPIO_WritePin(dev->SDA_PORT, dev->SDA_PIN, GPIO_PIN_SET)
#define SCK_SET HAL_GPIO_WritePin(dev->SCK_PORT, dev->SCK_PIN, GPIO_PIN_SET)
#define SDA_CLR HAL_GPIO_WritePin(dev->SDA_PORT, dev->SDA_PIN, GPIO_PIN_RESET)
#define SCK_CLR HAL_GPIO_WritePin(dev->SCK_PORT, dev->SCK_PIN, GPIO_PIN_RESET)
extern void i2c_begin(I2C_DEVICE *dev);
extern void i2c_beginTransmission_u8(I2C_DEVICE *dev, uint8_t);
extern void i2c_write_u8(I2C_DEVICE *dev, uint8_t);
extern void i2c_shift_out(I2C_DEVICE *dev, uint8_t val);
extern void i2c_start(I2C_DEVICE *dev);
extern void i2c_stop(I2C_DEVICE *dev);
extern bool i2c_get_ack(I2C_DEVICE *dev);
extern bool i2c_beginReceive_u8(I2C_DEVICE *dev, uint8_t slave_address);
extern uint8_t i2c_Read_Byte(I2C_DEVICE *dev, uint8_t ack);
extern uint8_t i2c_endTransmission(I2C_DEVICE *dev);
#endif

File diff suppressed because one or more lines are too long

824
Src/lcd.c
Wyświetl plik

@ -1,824 +0,0 @@
#include "main.h"
#include "lcd.h"
#include "functions.h"
#include "arm_math.h"
#include "agc.h"
#include "settings.h"
#include "system_menu.h"
#include "wm8731.h"
#include "audio_filters.h"
#include "fonts.h"
#include "wm8731.h"
#include "usbd_ua3reo.h"
#include "front_unit.h"
#include "screen_layout.h"
#include "images.h"
#include "fft.h"
volatile bool LCD_busy = false;
volatile bool LCD_inited = false;
volatile DEF_LCD_UpdateQuery LCD_UpdateQuery = {false};
volatile bool LCD_systemMenuOpened = false;
uint16_t LCD_bw_trapez_stripe_pos = 0;
STRUCT_COLOR_THEME* COLOR = &COLOR_THEMES[0];
static char LCD_freq_string_hz[6] = {0};
static char LCD_freq_string_khz[6] = {0};
static char LCD_freq_string_mhz[6] = {0};
static uint32_t LCD_last_showed_freq = 0;
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;
static float32_t LCD_last_s_meter = 1.0f;
static uint32_t Time;
static uint8_t Hours;
static uint8_t Last_showed_Hours = 255;
static uint8_t Minutes;
static uint8_t Last_showed_Minutes = 255;
static uint8_t Seconds;
static uint8_t Last_showed_Seconds = 255;
static uint32_t Tooltip_DiplayStartTime = 0;
static bool Tooltip_first_draw = true;
static char Tooltip_string[64] = {0};
static void printInfoSmall(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *text, uint16_t back_color, uint16_t text_color, uint16_t in_active_color, bool active);
static void printInfo(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *text, uint16_t back_color, uint16_t text_color, uint16_t in_active_color, bool active);
static void LCD_displayFreqInfo(bool redraw);
static void LCD_displayTopButtons(bool redraw);
static void LCD_displayStatusInfoBar(bool redraw);
static void LCD_displayStatusInfoGUI(bool redraw);
static void LCD_displayTextBar(void);
static void LCD_printTooltip(void);
void LCD_Init(void)
{
COLOR = &COLOR_THEMES[TRX.ColorThemeId];
LCDDriver_Init();
LCDDriver_setRotation(4);
LCDDriver_Fill(BG_COLOR);
LCD_inited = true;
}
static void LCD_displayTopButtons(bool redraw)
{ // display the top buttons
if (LCD_systemMenuOpened)
return;
if (LCD_busy)
{
LCD_UpdateQuery.TopButtons = true;
return;
}
LCD_busy = true;
if (redraw)
LCDDriver_Fill_RectWH(LAY_TOPBUTTONS_X1, LAY_TOPBUTTONS_Y1, LAY_TOPBUTTONS_X2, LAY_TOPBUTTONS_Y2, BG_COLOR);
// display information about the operation of the transceiver
printInfo(LAY_TOPBUTTONS_PRE_X, LAY_TOPBUTTONS_PRE_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, "PRE", COLOR->BUTTON_BACKGROUND, COLOR->BUTTON_TEXT, COLOR->BUTTON_INACTIVE_TEXT, TRX.ADC_Driver);
char buff[64] = {0};
sprintf(buff, "ATT%d", (uint8_t)TRX.ATT_DB);
if (TRX.ATT_DB == 0)
sprintf(buff, "ATT");
printInfo(LAY_TOPBUTTONS_ATT_X, LAY_TOPBUTTONS_ATT_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, buff, COLOR->BUTTON_BACKGROUND, COLOR->BUTTON_TEXT, COLOR->BUTTON_INACTIVE_TEXT, TRX.ATT);
printInfo(LAY_TOPBUTTONS_FAST_X, LAY_TOPBUTTONS_FAST_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, "FAST", COLOR->BUTTON_BACKGROUND, COLOR->BUTTON_TEXT, COLOR->BUTTON_INACTIVE_TEXT, TRX.Fast);
printInfo(LAY_TOPBUTTONS_AGC_X, LAY_TOPBUTTONS_AGC_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, "AGC", COLOR->BUTTON_BACKGROUND, COLOR->BUTTON_TEXT, COLOR->BUTTON_INACTIVE_TEXT, CurrentVFO()->AGC);
printInfo(LAY_TOPBUTTONS_MUTE_X, LAY_TOPBUTTONS_MUTE_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, "MUTE", COLOR->BUTTON_BACKGROUND, COLOR->BUTTON_TEXT, COLOR->BUTTON_INACTIVE_TEXT, TRX_Mute);
printInfo(LAY_TOPBUTTONS_LOCK_X, LAY_TOPBUTTONS_LOCK_Y, LAY_TOPBUTTONS_WIDTH, LAY_TOPBUTTONS_HEIGHT, "LOCK", COLOR->BUTTON_BACKGROUND, COLOR_RED, COLOR->BUTTON_INACTIVE_TEXT, TRX.Locked);
//bottom buttons
printInfo(LAY_BOTTOMBUTTONS_X1, LAY_BOTTOMBUTTONS_Y, LAY_BOTTOMBUTTONS_WIDTH, LAY_BOTTOMBUTTONS_HEIGHT, PERIPH_FrontPanel_BottomScroll_Buttons_Active[0].name , COLOR->BUTTON_BACKGROUND, COLOR->BOTTOM_BUTTONS_COLOR, COLOR->BUTTON_INACTIVE_TEXT, true);
printInfo(LAY_BOTTOMBUTTONS_X2, LAY_BOTTOMBUTTONS_Y, LAY_BOTTOMBUTTONS_WIDTH, LAY_BOTTOMBUTTONS_HEIGHT, PERIPH_FrontPanel_BottomScroll_Buttons_Active[1].name, COLOR->BUTTON_BACKGROUND, COLOR->BOTTOM_BUTTONS_COLOR, COLOR->BUTTON_INACTIVE_TEXT, true);
printInfo(LAY_BOTTOMBUTTONS_X3, LAY_BOTTOMBUTTONS_Y, LAY_BOTTOMBUTTONS_WIDTH, LAY_BOTTOMBUTTONS_HEIGHT, PERIPH_FrontPanel_BottomScroll_Buttons_Active[2].name, COLOR->BUTTON_BACKGROUND, COLOR->BOTTOM_BUTTONS_COLOR, COLOR->BUTTON_INACTIVE_TEXT, true);
printInfo(LAY_BOTTOMBUTTONS_X4, LAY_BOTTOMBUTTONS_Y, LAY_BOTTOMBUTTONS_WIDTH, LAY_BOTTOMBUTTONS_HEIGHT, PERIPH_FrontPanel_BottomScroll_Buttons_Active[3].name, COLOR->BUTTON_BACKGROUND, COLOR->BOTTOM_BUTTONS_COLOR, COLOR->BUTTON_INACTIVE_TEXT, true);
LCD_UpdateQuery.TopButtons = false;
if(redraw)
LCD_UpdateQuery.TopButtonsRedraw = false;
LCD_busy = false;
}
static void LCD_displayBottomButtons(bool redraw)
{
// display the bottom buttons
if (LCD_systemMenuOpened)
return;
if (LCD_busy)
{
LCD_UpdateQuery.BottomButtons = true;
return;
}
LCD_busy = true;
LCD_UpdateQuery.BottomButtons = false;
if(redraw)
LCD_UpdateQuery.BottomButtonsRedraw = false;
LCD_busy = false;
}
static void LCD_displayFreqInfo(bool redraw)
{ // display the frequency on the screen
if (LCD_systemMenuOpened)
return;
if (!redraw && (LCD_last_showed_freq == CurrentVFO()->Freq)
)
return;
if (LCD_busy)
{
LCD_UpdateQuery.FreqInfo = true;
if(redraw)
LCD_UpdateQuery.FreqInfoRedraw = true;
return;
}
LCD_busy = true;
uint32_t display_freq = CurrentVFO()->Freq;
if(TRX.Transverter_Enabled)
display_freq += TRX.Transverter_Offset_Mhz * 1000 * 1000;
if(display_freq > 999999999)
display_freq = 999999999;
LCD_last_showed_freq = display_freq;
uint16_t mhz_x_offset = 0;
if (display_freq>= 100000000)
mhz_x_offset = LAY_FREQ_X_OFFSET_100;
else if (display_freq >= 10000000)
mhz_x_offset = LAY_FREQ_X_OFFSET_10;
else
mhz_x_offset = LAY_FREQ_X_OFFSET_1;
if (redraw)
LCDDriver_Fill_RectWH(LAY_FREQ_LEFT_MARGIN, LAY_FREQ_Y_TOP, LCD_WIDTH - LAY_FREQ_LEFT_MARGIN - LAY_FREQ_RIGHT_MARGIN, LAY_FREQ_BLOCK_HEIGHT, BG_COLOR);
if((mhz_x_offset - LAY_FREQ_LEFT_MARGIN) > 0)
LCDDriver_Fill_RectWH(LAY_FREQ_LEFT_MARGIN, LAY_FREQ_Y_BASELINE - LAY_FREQ_HEIGHT, mhz_x_offset - LAY_FREQ_LEFT_MARGIN, LAY_FREQ_HEIGHT, BG_COLOR);
// add spaces to output the frequency
uint16_t hz = (display_freq % 1000);
uint16_t khz = ((display_freq / 1000) % 1000);
uint16_t mhz = ((display_freq / 1000000) % 1000000);
sprintf(LCD_freq_string_hz, "%d", hz);
sprintf(LCD_freq_string_khz, "%d", khz);
sprintf(LCD_freq_string_mhz, "%d", mhz);
if (redraw || (LCD_last_showed_freq_mhz != mhz))
{
LCDDriver_printTextFont(LCD_freq_string_mhz, mhz_x_offset, LAY_FREQ_Y_BASELINE, COLOR->FREQ_MHZ, BG_COLOR, LAY_FREQ_FONT);
LCD_last_showed_freq_mhz = mhz;
}
char buff[50] = "";
if (redraw || (LCD_last_showed_freq_khz != khz))
{
addSymbols(buff, LCD_freq_string_khz, 3, "0", false);
LCDDriver_printTextFont(buff, LAY_FREQ_X_OFFSET_KHZ, LAY_FREQ_Y_BASELINE, COLOR->FREQ_KHZ, BG_COLOR, LAY_FREQ_FONT);
LCD_last_showed_freq_khz = khz;
}
if (redraw || (LCD_last_showed_freq_hz != hz))
{
addSymbols(buff, LCD_freq_string_hz, 3, "0", false);
LCDDriver_printTextFont(buff, LAY_FREQ_X_OFFSET_HZ, LAY_FREQ_Y_BASELINE_SMALL, COLOR->FREQ_HZ, BG_COLOR, LAY_FREQ_SMALL_FONT);
LCD_last_showed_freq_hz = hz;
}
NeedSaveSettings = true;
LCD_UpdateQuery.FreqInfo = false;
if(redraw)
LCD_UpdateQuery.FreqInfoRedraw = false;
LCD_busy = false;
}
static void LCD_drawSMeter(void)
{
// Labels on the scale
const float32_t step = LAY_STATUS_SMETER_WIDTH / 15.0f;
LCDDriver_printText("S", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 0.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("1", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 1.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("3", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 3.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("5", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 5.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("7", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 7.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("9", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("+20", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 11.0f) - 10, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("+40", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 13.0f) - 10, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("+60", LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 15.0f) - 10, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
for (uint8_t i = 0; i <= 15; i ++)
{
uint16_t color = COLOR->STATUS_BAR_LEFT;
if (i >= 9)
color = COLOR->STATUS_BAR_RIGHT;
if ((i % 2) != 0 || i == 0)
{
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i) - 1, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -4, color);
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -6, color);
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i) + 1, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -4, color);
}
else
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -3, color);
}
// S-meter frame
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) - 1, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_SMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 1, COLOR->STATUS_BAR_RIGHT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT, LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) - 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) - 1, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_SMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT + 1, COLOR->STATUS_BAR_RIGHT);
}
static void LCD_displayStatusInfoGUI(bool redraw)
{
// display RX / TX and s-meter
if (LCD_systemMenuOpened)
return;
if (LCD_busy)
{
if (redraw)
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
else
LCD_UpdateQuery.StatusInfoGUI = true;
return;
}
LCD_busy = true;
if (redraw)
LCDDriver_Fill_RectWH(0, LAY_STATUS_Y_OFFSET, LCD_WIDTH, LAY_STATUS_HEIGHT, BG_COLOR);
if (TRX_on_TX())
{
if (TRX_Tune)
LCDDriver_printTextFont("TU", LAY_STATUS_TXRX_X_OFFSET, (LAY_STATUS_Y_OFFSET + LAY_STATUS_TXRX_Y_OFFSET), COLOR->STATUS_TX, BG_COLOR, LAY_STATUS_TXRX_FONT);
else
LCDDriver_printTextFont("TX", LAY_STATUS_TXRX_X_OFFSET + 1, (LAY_STATUS_Y_OFFSET + LAY_STATUS_TXRX_Y_OFFSET), COLOR->STATUS_TX, BG_COLOR, LAY_STATUS_TXRX_FONT);
// frame of the SWR meter
const float32_t step = LAY_STATUS_PMETER_WIDTH / 16.0f;
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f) , LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 1, COLOR->STATUS_BAR_RIGHT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT, LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * 9.0f), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT + 1, COLOR->STATUS_BAR_RIGHT);
for (uint8_t i = 0; i <= 16; i++)
{
uint16_t color = COLOR->STATUS_BAR_LEFT;
if (i > 9)
color = COLOR->STATUS_BAR_RIGHT;
if ((i % 2) == 0)
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -10, color);
else
LCDDriver_drawFastVLine(LAY_STATUS_BAR_X_OFFSET + (uint16_t)(step * i), LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, -5, color);
}
LCDDriver_printText("SWR:", LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_LABELS_TX, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("FWD:", LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_TX_LABELS_MARGIN_X, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_LABELS_TX, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
LCDDriver_printText("REF:", LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_TX_LABELS_MARGIN_X * 2, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_LABELS_TX, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
// frame of the ALC meter
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET + LAY_STATUS_AMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_drawRectXY(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET + LAY_STATUS_AMETER_WIDTH, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + LAY_STATUS_BAR_HEIGHT + 1, COLOR->STATUS_BAR_LEFT);
LCDDriver_printText("ALC:", LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_LABELS_TX, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
}
else
{
LCD_UpdateQuery.StatusInfoBar = true;
LCDDriver_printTextFont("RX", LAY_STATUS_TXRX_X_OFFSET, (LAY_STATUS_Y_OFFSET + LAY_STATUS_TXRX_Y_OFFSET), COLOR->STATUS_RX, BG_COLOR, LAY_STATUS_TXRX_FONT);
//Frequency delimiters
LCDDriver_printTextFont(".", LAY_FREQ_DELIMITER_X1_OFFSET, LAY_FREQ_Y_BASELINE + LAY_FREQ_DELIMITER_Y_OFFSET, COLOR->FREQ_KHZ, BG_COLOR, LAY_FREQ_FONT);
LCDDriver_printTextFont(".", LAY_FREQ_DELIMITER_X2_OFFSET, LAY_FREQ_Y_BASELINE + LAY_FREQ_DELIMITER_Y_OFFSET, COLOR->FREQ_HZ, BG_COLOR, LAY_FREQ_FONT);
}
//VFO indicator
if (!TRX.current_vfo) //VFO-A
{
printInfo(LAY_STATUS_VFO_X_OFFSET, (LAY_STATUS_Y_OFFSET + LAY_STATUS_VFO_Y_OFFSET), LAY_STATUS_VFO_BLOCK_WIDTH, LAY_STATUS_VFO_BLOCK_HEIGHT, "A", COLOR->STATUS_VFO_BG, COLOR->STATUS_VFO, COLOR->STATUS_VFO, true);
}
else //VFO-B
{
printInfo(LAY_STATUS_VFO_X_OFFSET, (LAY_STATUS_Y_OFFSET + LAY_STATUS_VFO_Y_OFFSET), LAY_STATUS_VFO_BLOCK_WIDTH, LAY_STATUS_VFO_BLOCK_HEIGHT, "B", COLOR->STATUS_VFO_BG, COLOR->STATUS_VFO, COLOR->STATUS_VFO, true);
}
//Mode indicator
printInfo(LAY_STATUS_MODE_X_OFFSET, (LAY_STATUS_Y_OFFSET + LAY_STATUS_MODE_Y_OFFSET), LAY_STATUS_MODE_BLOCK_WIDTH, LAY_STATUS_MODE_BLOCK_HEIGHT, (char *)MODE_DESCR[CurrentVFO()->Mode], BG_COLOR, COLOR->STATUS_MODE, COLOR->STATUS_MODE, true);
/////BW trapezoid
LCDDriver_Fill_RectWH(LAY_BW_TRAPEZ_POS_X, LAY_BW_TRAPEZ_POS_Y, LAY_BW_TRAPEZ_WIDTH, LAY_BW_TRAPEZ_HEIGHT, BG_COLOR); //clear back
#define bw_trapez_margin 10
uint16_t bw_trapez_top_line_width = (uint16_t)(LAY_BW_TRAPEZ_WIDTH * 0.9f - bw_trapez_margin * 2);
//border
LCDDriver_drawFastHLine(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_top_line_width / 2, LAY_BW_TRAPEZ_POS_Y, bw_trapez_top_line_width, COLOR->BW_TRAPEZ_BORDER); //top
LCDDriver_drawFastHLine(LAY_BW_TRAPEZ_POS_X, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT, LAY_BW_TRAPEZ_WIDTH, COLOR->BW_TRAPEZ_BORDER); //bottom
LCDDriver_drawLine(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_top_line_width / 2 - bw_trapez_margin, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_top_line_width / 2, LAY_BW_TRAPEZ_POS_Y, COLOR->BW_TRAPEZ_BORDER); //left
LCDDriver_drawLine(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_top_line_width / 2 + bw_trapez_margin, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_top_line_width / 2, LAY_BW_TRAPEZ_POS_Y, COLOR->BW_TRAPEZ_BORDER); //right
//bw fill
float32_t bw_trapez_bw_left_width = 1.0f;
float32_t bw_trapez_bw_right_width = 1.0f;
float32_t bw_trapez_bw_hpf_margin = 0.0f;
switch (CurrentVFO()->Mode)
{
case TRX_MODE_LSB:
bw_trapez_bw_hpf_margin = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.SSB_HPF_Filter;
case TRX_MODE_DIGI_L:
bw_trapez_bw_left_width = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.SSB_LPF_Filter;
bw_trapez_bw_right_width = 0.0f;
break;
case TRX_MODE_CW_L:
bw_trapez_bw_hpf_margin = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.CW_HPF_Filter * 4.0f;
bw_trapez_bw_left_width = 1.0f / (float32_t)MAX_LPF_WIDTH_CW * TRX.CW_LPF_Filter;
bw_trapez_bw_right_width = 0.0f;
break;
case TRX_MODE_USB:
bw_trapez_bw_hpf_margin = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.SSB_HPF_Filter;
case TRX_MODE_DIGI_U:
bw_trapez_bw_left_width = 0.0f;
bw_trapez_bw_right_width = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.SSB_LPF_Filter;
break;
case TRX_MODE_CW_U:
bw_trapez_bw_left_width = 0.0f;
bw_trapez_bw_right_width = 1.0f / (float32_t)MAX_LPF_WIDTH_CW * TRX.CW_LPF_Filter;
bw_trapez_bw_hpf_margin = 1.0f / (float32_t)MAX_LPF_WIDTH_SSB * TRX.CW_HPF_Filter * 4.0f;
break;
case TRX_MODE_NFM:
bw_trapez_bw_left_width = 1.0f / (float32_t)MAX_LPF_WIDTH_NFM * TRX.FM_LPF_Filter;
bw_trapez_bw_right_width = 1.0f / (float32_t)MAX_LPF_WIDTH_NFM * TRX.FM_LPF_Filter;
break;
case TRX_MODE_AM:
bw_trapez_bw_left_width = 1.0f / (float32_t)MAX_LPF_WIDTH_AM * TRX.AM_LPF_Filter;
bw_trapez_bw_right_width = 1.0f / (float32_t)MAX_LPF_WIDTH_AM * TRX.AM_LPF_Filter;
break;
case TRX_MODE_WFM:
bw_trapez_bw_left_width = 1.0f;
bw_trapez_bw_right_width = 1.0f;
break;
}
uint16_t bw_trapez_left_width = (uint16_t)(bw_trapez_top_line_width / 2 * bw_trapez_bw_left_width);
uint16_t bw_trapez_right_width = (uint16_t)(bw_trapez_top_line_width / 2 * bw_trapez_bw_right_width);
uint16_t bw_trapez_bw_hpf_margin_width = (uint16_t)(bw_trapez_top_line_width / 2 * bw_trapez_bw_hpf_margin);
if (bw_trapez_left_width > 0) //left wing
{
LCDDriver_Fill_RectWH(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_left_width, LAY_BW_TRAPEZ_POS_Y + 1, bw_trapez_left_width - bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_HEIGHT - 2, COLOR->BW_TRAPEZ_FILL);
LCDDriver_Fill_Triangle(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_left_width - bw_trapez_margin + 1, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_left_width, LAY_BW_TRAPEZ_POS_Y + 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_left_width, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, COLOR->BW_TRAPEZ_FILL);
if (bw_trapez_bw_hpf_margin_width > 0)
LCDDriver_Fill_Triangle(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_POS_Y + 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 - bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, COLOR->BW_TRAPEZ_FILL);
}
if (bw_trapez_bw_right_width > 0) //right wing
{
LCDDriver_Fill_RectWH(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_POS_Y + 1, bw_trapez_right_width - bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_HEIGHT - 2, COLOR->BW_TRAPEZ_FILL);
LCDDriver_Fill_Triangle(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_right_width + bw_trapez_margin - 1, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_right_width, LAY_BW_TRAPEZ_POS_Y + 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_right_width, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, COLOR->BW_TRAPEZ_FILL);
if (bw_trapez_bw_hpf_margin_width > 0)
LCDDriver_Fill_Triangle(LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_POS_Y + 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2 + bw_trapez_bw_hpf_margin_width, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT - 1, COLOR->BW_TRAPEZ_FILL);
}
//shift stripe
if (!TRX.ShiftEnabled || LCD_bw_trapez_stripe_pos == 0)
LCD_bw_trapez_stripe_pos = LAY_BW_TRAPEZ_POS_X + LAY_BW_TRAPEZ_WIDTH / 2;
LCDDriver_Fill_RectWH(LCD_bw_trapez_stripe_pos - 1, LAY_BW_TRAPEZ_POS_Y + LAY_BW_TRAPEZ_HEIGHT / 2, 3, LAY_BW_TRAPEZ_HEIGHT / 2, COLOR->BW_TRAPEZ_STRIPE);
/////END BW trapezoid
LCD_UpdateQuery.StatusInfoGUI = false;
if (redraw)
LCD_UpdateQuery.StatusInfoGUIRedraw = false;
LCD_busy = false;
}
static void LCD_displayStatusInfoBar(bool redraw)
{
// S-meter and other information
if (LCD_systemMenuOpened)
return;
if (LCD_busy)
{
LCD_UpdateQuery.StatusInfoBar = true;
return;
}
LCD_busy = true;
char ctmp[50];
const int width = LAY_STATUS_SMETER_WIDTH - 2;
if (!TRX_on_TX())
{
float32_t TRX_s_meter = (127.0f + TRX_RX_dBm); // 127dbm - S0, 6dBm - 1S div
if (CurrentVFO()->Freq >= 144000000)
TRX_s_meter = (147.0f + TRX_RX_dBm); // 147dbm - S0 for frequencies above 144mhz
if (TRX_s_meter < 54.01f) // first 9 points of meter is 6 dB each
TRX_s_meter = (width / 15.0f) * (TRX_s_meter / 6.0f);
else // the remaining 6 points, 10 dB each
TRX_s_meter = ((width / 15.0f) * 9.0f) + ((TRX_s_meter - 54.0f) / 10.0f) * (width / 15.0f);
TRX_s_meter += 1.0f;
if (TRX_s_meter > width)
TRX_s_meter = width;
if (TRX_s_meter < 1.0f)
TRX_s_meter = 1.0f;
float32_t s_width = LCD_last_s_meter * 0.75f + TRX_s_meter * 0.25f; // smooth the movement of the S-meter
if (redraw || (LCD_last_s_meter != s_width))
{
//clear old bar and stripe
if ((LCD_last_s_meter - s_width) > 0)
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + (uint16_t)s_width, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, (uint16_t)(LCD_last_s_meter - s_width + 1), LAY_STATUS_BAR_HEIGHT - 3, BG_COLOR);
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + (uint16_t)LCD_last_s_meter, LAY_STATUS_Y_OFFSET + 5, 2, LAY_STATUS_SMETER_MARKER_HEIGHT, BG_COLOR);
// bar
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, (uint16_t)s_width, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_SMETER);
// peak
static uint16_t smeter_peak_x = 0;
static uint32_t smeter_peak_settime = 0;
if(smeter_peak_x > s_width)
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + smeter_peak_x, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, 2, LAY_STATUS_BAR_HEIGHT - 3, BG_COLOR); //clear old peak
if(smeter_peak_x > 0 && ((HAL_GetTick() - smeter_peak_settime) > LAY_STATUS_SMETER_PEAK_HOLDTIME))
smeter_peak_x--;
if(s_width > smeter_peak_x)
{
smeter_peak_x = (uint16_t)s_width;
smeter_peak_settime = HAL_GetTick();
}
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + smeter_peak_x, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, 2, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_SMETER_PEAK);
// stripe
LCD_drawSMeter();
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + (uint16_t)s_width, LAY_STATUS_Y_OFFSET + 5, 2, LAY_STATUS_SMETER_MARKER_HEIGHT, COLOR->STATUS_SMETER_STRIPE);
LCD_last_s_meter = s_width;
}
//print dBm value
sprintf(ctmp, "%ddBm", TRX_RX_dBm);
addSymbols(ctmp, ctmp, 7, " ", true);
LCDDriver_printText(ctmp, LAY_STATUS_LABEL_DBM_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_DBM_Y_OFFSET, COLOR->STATUS_LABEL_DBM, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//print s-meter value
static float32_t TRX_RX_dBm_averaging = -120.0f;
TRX_RX_dBm_averaging = 0.97f * TRX_RX_dBm_averaging + 0.03f * TRX_RX_dBm;
if(TRX_RX_dBm > TRX_RX_dBm_averaging)
TRX_RX_dBm_averaging = TRX_RX_dBm;
if (CurrentVFO()->Freq < 144000000)
{
if (TRX_RX_dBm_averaging <= -118.0f)
sprintf(ctmp, "S1");
else if (TRX_RX_dBm_averaging <= -112.0f)
sprintf(ctmp, "S2");
else if (TRX_RX_dBm_averaging <= -106.0f)
sprintf(ctmp, "S3");
else if (TRX_RX_dBm_averaging <= -100.0f)
sprintf(ctmp, "S4");
else if (TRX_RX_dBm_averaging <= -94.0f)
sprintf(ctmp, "S5");
else if (TRX_RX_dBm_averaging <= -88.0f)
sprintf(ctmp, "S6");
else if (TRX_RX_dBm_averaging <= -82.0f)
sprintf(ctmp, "S7");
else if (TRX_RX_dBm_averaging <= -76.0f)
sprintf(ctmp, "S8");
else if (TRX_RX_dBm_averaging <= -68.0f)
sprintf(ctmp, "S9");
else if (TRX_RX_dBm_averaging <= -58.0f)
sprintf(ctmp, "S9+10");
else if (TRX_RX_dBm_averaging <= -48.0f)
sprintf(ctmp, "S9+20");
else if (TRX_RX_dBm_averaging <= -38.0f)
sprintf(ctmp, "S9+30");
else if (TRX_RX_dBm_averaging <= -28.0f)
sprintf(ctmp, "S9+40");
else
sprintf(ctmp, "S9+60");
}
else
{
if (TRX_RX_dBm_averaging <= -138.0f)
sprintf(ctmp, "S1");
else if (TRX_RX_dBm_averaging <= -132.0f)
sprintf(ctmp, "S2");
else if (TRX_RX_dBm_averaging <= -126.0f)
sprintf(ctmp, "S3");
else if (TRX_RX_dBm_averaging <= -120.0f)
sprintf(ctmp, "S4");
else if (TRX_RX_dBm_averaging <= -114.0f)
sprintf(ctmp, "S5");
else if (TRX_RX_dBm_averaging <= -108.0f)
sprintf(ctmp, "S6");
else if (TRX_RX_dBm_averaging <= -102.0f)
sprintf(ctmp, "S7");
else if (TRX_RX_dBm_averaging <= -96.0f)
sprintf(ctmp, "S8");
else if (TRX_RX_dBm_averaging <= -88.0f)
sprintf(ctmp, "S9");
else if (TRX_RX_dBm_averaging <= -78.0f)
sprintf(ctmp, "S9+10");
else if (TRX_RX_dBm_averaging <= -68.0f)
sprintf(ctmp, "S9+20");
else if (TRX_RX_dBm_averaging <= -58.0f)
sprintf(ctmp, "S9+30");
else if (TRX_RX_dBm_averaging <= -48.0f)
sprintf(ctmp, "S9+40");
else
sprintf(ctmp, "S9+60");
}
addSymbols(ctmp, ctmp, 6, " ", true);
LCDDriver_printTextFont(ctmp, LAY_STATUS_LABEL_S_VAL_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_S_VAL_Y_OFFSET, COLOR->STATUS_LABEL_S_VAL, BG_COLOR, LAY_STATUS_LABEL_S_VAL_FONT);
}
else
{
//SWR
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, LAY_STATUS_TX_LABELS_VAL_WIDTH, LAY_STATUS_TX_LABELS_VAL_HEIGHT, BG_COLOR);
sprintf(ctmp, "%.1f", (double)TRX_SWR);
LCDDriver_printText(ctmp, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR_RED, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//FWD
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_MARGIN + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, LAY_STATUS_TX_LABELS_VAL_WIDTH, LAY_STATUS_TX_LABELS_VAL_HEIGHT, BG_COLOR);
sprintf(ctmp, "%.1fW", (double)TRX_PWR_Forward);
LCDDriver_printText(ctmp, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_MARGIN + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR_RED, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//REF
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_MARGIN * 2 + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, LAY_STATUS_TX_LABELS_VAL_WIDTH, LAY_STATUS_TX_LABELS_VAL_HEIGHT, BG_COLOR);
sprintf(ctmp, "%.1fW", (double)TRX_PWR_Backward);
LCDDriver_printText(ctmp, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_TX_LABELS_OFFSET_X + LAY_STATUS_SMETER_TXLABELS_MARGIN * 2 + LAY_STATUS_SMETER_TXLABELS_PADDING, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR_RED, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//SWR Meter
float32_t fwd_power = TRX_PWR_Forward;
if (fwd_power > MAX_RF_POWER)
fwd_power = MAX_RF_POWER;
uint16_t ref_width = (uint16_t)(TRX_PWR_Backward * (LAY_STATUS_PMETER_WIDTH - 2) / MAX_RF_POWER);
uint16_t fwd_width = (uint16_t)(fwd_power * (LAY_STATUS_PMETER_WIDTH - 2) / MAX_RF_POWER);
uint16_t est_width = (uint16_t)((MAX_RF_POWER - fwd_power) * (LAY_STATUS_PMETER_WIDTH - 2) / MAX_RF_POWER);
if (ref_width > fwd_width)
ref_width = fwd_width;
fwd_width -= ref_width;
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + 1, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, fwd_width, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_SMETER);
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + 1 + fwd_width, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, ref_width, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_BAR_RIGHT);
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + 1 + fwd_width + ref_width, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, est_width, LAY_STATUS_BAR_HEIGHT - 3, BG_COLOR);
//ALC
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_TX_ALC_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, LAY_STATUS_TX_LABELS_VAL_WIDTH, LAY_STATUS_TX_LABELS_VAL_HEIGHT, BG_COLOR);
uint8_t alc_level = (uint8_t)(TRX_ALC * 100.0f);
sprintf(ctmp, "%d%%", alc_level);
LCDDriver_printText(ctmp, LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_TX_ALC_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABELS_OFFSET_Y, COLOR->STATUS_BAR_LABELS, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
uint16_t alc_level_width = LAY_STATUS_AMETER_WIDTH * alc_level / 100;
if (alc_level_width > LAY_STATUS_AMETER_WIDTH)
alc_level_width = LAY_STATUS_AMETER_WIDTH;
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, alc_level_width, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_SMETER);
if (alc_level < 100)
LCDDriver_Fill_RectWH(LAY_STATUS_BAR_X_OFFSET + LAY_STATUS_PMETER_WIDTH + LAY_STATUS_ALC_BAR_X_OFFSET + alc_level_width, LAY_STATUS_Y_OFFSET + LAY_STATUS_BAR_Y_OFFSET + 2, LAY_STATUS_AMETER_WIDTH - alc_level_width, LAY_STATUS_BAR_HEIGHT - 3, COLOR->STATUS_LABEL_NOTCH);
}
//Info labels
char buff[32] = "";
//BW HPF-LPF
if ((CurrentVFO()->Mode == TRX_MODE_CW_L || CurrentVFO()->Mode == TRX_MODE_CW_U))
sprintf(buff, "BW:%d-%d", TRX.CW_HPF_Filter, TRX.CW_LPF_Filter);
else if ((CurrentVFO()->Mode == TRX_MODE_DIGI_L || CurrentVFO()->Mode == TRX_MODE_DIGI_U))
sprintf(buff, "BW:%d", TRX.SSB_LPF_Filter);
else if ((CurrentVFO()->Mode == TRX_MODE_LSB || CurrentVFO()->Mode == TRX_MODE_USB))
sprintf(buff, "BW:%d-%d", TRX.SSB_HPF_Filter, TRX.SSB_LPF_Filter);
else if ((CurrentVFO()->Mode == TRX_MODE_AM))
sprintf(buff, "BW:%d", TRX.AM_LPF_Filter);
else if ((CurrentVFO()->Mode == TRX_MODE_NFM) || (CurrentVFO()->Mode == TRX_MODE_WFM))
sprintf(buff, "BW:%d", TRX.FM_LPF_Filter);
else
sprintf(buff, "BW:FULL");
addSymbols(buff, buff, 12, " ", true);
LCDDriver_printText(buff, LAY_STATUS_LABEL_BW_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_BW_Y_OFFSET, COLOR->STATUS_LABEL_BW, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//RIT
if (TRX.CLAR)
sprintf(buff, "RIT:CLAR");
else if (TRX.ShiftEnabled)
sprintf(buff, "SHIFT:%d", TRX_SHIFT);
else
sprintf(buff, "RIT:OFF");
addSymbols(buff, buff, 12, " ", true);
LCDDriver_printText(buff, LAY_STATUS_LABEL_RIT_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_RIT_Y_OFFSET, COLOR->STATUS_LABEL_RIT, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//VOLTAGE
sprintf(buff, "VLT:%.1f ", TRX_InVoltage);
LCDDriver_printText(buff, LAY_STATUS_LABEL_VLT_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_VLT_Y_OFFSET, COLOR->STATUS_LABEL_VLT, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//NOTCH
if (CurrentVFO()->AutoNotchFilter)
sprintf(buff, "NOTCH:AUTO");
else
sprintf(buff, "NOTCH:OFF");
addSymbols(buff, buff, 12, " ", true);
LCDDriver_printText(buff, LAY_STATUS_LABEL_NOTCH_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_NOTCH_Y_OFFSET, COLOR->STATUS_LABEL_NOTCH, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//FFT BW
if (TRX.FFT_Zoom == 1)
sprintf(buff, "FFT:48kHz");
else if (TRX.FFT_Zoom == 2)
sprintf(buff, "FFT:24kHz");
else if (TRX.FFT_Zoom == 4)
sprintf(buff, "FFT:12kHz");
else if (TRX.FFT_Zoom == 8)
sprintf(buff, "FFT:6kHz ");
else if (TRX.FFT_Zoom == 16)
sprintf(buff, "FFT:3kHz ");
LCDDriver_printText(buff, LAY_STATUS_LABEL_FFT_BW_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_FFT_BW_Y_OFFSET, COLOR->STATUS_LABELS_BW, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
#if (defined(LAY_800x480))
//LOCK
LCDDriver_printText("LOCK", LAY_STATUS_LABEL_LOCK_X_OFFSET, LAY_STATUS_Y_OFFSET + LAY_STATUS_LABEL_LOCK_Y_OFFSET, TRX.Locked ? COLOR->STATUS_LABEL_ACTIVE : COLOR->STATUS_LABEL_INACTIVE, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
#endif
//ERRORS LABELS
LCDDriver_Fill_RectWH(LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, LAY_STATUS_ERR_WIDTH, LAY_STATUS_ERR_HEIGHT, BG_COLOR);
if (TRX_ADC_OTR && !TRX_on_TX())
LCDDriver_printText("OVR", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, COLOR->STATUS_ERR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
if (TRX_DAC_OTR)
LCDDriver_printText("OVR", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, COLOR->STATUS_ERR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
//else if (TRX_ADC_MAXAMPLITUDE > (ADC_FULL_SCALE * 0.49f) || TRX_ADC_MINAMPLITUDE < -(ADC_FULL_SCALE * 0.49f))
//LCDDriver_printText("MVR", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, LAY_STATUS_ERR_COLOR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
if (WM8731_Buffer_underrun && !TRX_on_TX())
LCDDriver_printText("WBF", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, COLOR->STATUS_ERR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
if (FPGA_Buffer_underrun && TRX_on_TX())
LCDDriver_printText("FBF", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, COLOR->STATUS_ERR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
if (RX_USB_AUDIO_underrun)
LCDDriver_printText("UBF", LAY_STATUS_ERR_OFFSET_X, LAY_STATUS_ERR_OFFSET_Y, COLOR->STATUS_ERR, BG_COLOR, LAY_STATUS_LABELS_FONT_SIZE);
Time = RTC->TR;
Hours = ((Time >> 20) & 0x03) * 10 + ((Time >> 16) & 0x0f);
Minutes = ((Time >> 12) & 0x07) * 10 + ((Time >> 8) & 0x0f);
Seconds = ((Time >> 4) & 0x07) * 10 + ((Time >> 0) & 0x0f);
if (redraw || (Hours != Last_showed_Hours))
{
sprintf(ctmp, "%d", Hours);
addSymbols(ctmp, ctmp, 2, "0", false);
LCDDriver_printTextFont(ctmp, LAY_CLOCK_POS_HRS_X, LAY_CLOCK_POS_Y, COLOR->CLOCK, BG_COLOR, LAY_CLOCK_FONT);
LCDDriver_printTextFont(":", LCDDriver_GetCurrentXOffset(), LAY_CLOCK_POS_Y, COLOR->CLOCK, BG_COLOR, LAY_CLOCK_FONT);
Last_showed_Hours = Hours;
}
if (redraw || (Minutes != Last_showed_Minutes))
{
sprintf(ctmp, "%d", Minutes);
addSymbols(ctmp, ctmp, 2, "0", false);
LCDDriver_printTextFont(ctmp, LAY_CLOCK_POS_MIN_X, LAY_CLOCK_POS_Y, COLOR->CLOCK, BG_COLOR, LAY_CLOCK_FONT);
LCDDriver_printTextFont(":", LCDDriver_GetCurrentXOffset(), LAY_CLOCK_POS_Y, COLOR->CLOCK, BG_COLOR, LAY_CLOCK_FONT);
Last_showed_Minutes = Minutes;
}
if (redraw || (Seconds != Last_showed_Seconds))
{
sprintf(ctmp, "%d", Seconds);
addSymbols(ctmp, ctmp, 2, "0", false);
LCDDriver_printTextFont(ctmp, LAY_CLOCK_POS_SEC_X, LAY_CLOCK_POS_Y, COLOR->CLOCK, BG_COLOR, LAY_CLOCK_FONT);
Last_showed_Seconds = Seconds;
}
LCD_UpdateQuery.StatusInfoBar = false;
if(redraw)
LCD_UpdateQuery.StatusInfoBarRedraw = false;
LCD_busy = false;
}
void LCD_redraw(bool do_now)
{
LCD_UpdateQuery.Background = true;
LCD_UpdateQuery.FreqInfoRedraw = true;
LCD_UpdateQuery.StatusInfoBarRedraw = true;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
LCD_UpdateQuery.TopButtonsRedraw = true;
LCD_UpdateQuery.BottomButtonsRedraw = true;
LCD_UpdateQuery.SystemMenu = true;
LCD_last_s_meter = 0;
LCD_last_showed_freq = 0;
Last_showed_Hours = 255;
Last_showed_Minutes = 255;
Last_showed_Seconds = 255;
LCD_last_showed_freq_mhz = 9999;
LCD_last_showed_freq_khz = 9999;
LCD_last_showed_freq_hz = 9999;
if(do_now)
LCD_doEvents();
}
void LCD_doEvents(void)
{
if (LCD_busy)
return;
if (LCD_UpdateQuery.Background)
{
LCD_busy = true;
LCDDriver_Fill(BG_COLOR);
LCD_UpdateQuery.Background = false;
LCD_busy = false;
}
if (LCD_UpdateQuery.TopButtons)
LCD_displayTopButtons(false);
if (LCD_UpdateQuery.TopButtonsRedraw)
LCD_displayTopButtons(true);
if (LCD_UpdateQuery.BottomButtons)
LCD_displayBottomButtons(false);
if (LCD_UpdateQuery.BottomButtonsRedraw)
LCD_displayBottomButtons(true);
if (LCD_UpdateQuery.FreqInfo)
LCD_displayFreqInfo(false);
if (LCD_UpdateQuery.FreqInfoRedraw)
LCD_displayFreqInfo(true);
if (LCD_UpdateQuery.StatusInfoGUI)
LCD_displayStatusInfoGUI(false);
if (LCD_UpdateQuery.StatusInfoGUIRedraw)
LCD_displayStatusInfoGUI(true);
if (LCD_UpdateQuery.StatusInfoBar)
LCD_displayStatusInfoBar(false);
if (LCD_UpdateQuery.StatusInfoBarRedraw)
LCD_displayStatusInfoBar(true);
if (LCD_UpdateQuery.SystemMenu)
SYSMENU_drawSystemMenu(false);
if (LCD_UpdateQuery.SystemMenuRedraw)
SYSMENU_drawSystemMenu(true);
if (LCD_UpdateQuery.SystemMenuCurrent)
{
SYSMENU_redrawCurrentItem();
LCD_UpdateQuery.SystemMenuCurrent = false;
}
if (LCD_UpdateQuery.Tooltip)
LCD_printTooltip();
}
static void printInfoSmall(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *text, uint16_t back_color, uint16_t text_color, uint16_t inactive_color, bool active)
{
uint16_t x1, y1, w, h;
LCDDriver_Fill_RectWH(x, y, width, height, back_color);
LCDDriver_getTextBounds(text, x, y, &x1, &y1, &w, &h, (GFXfont *)&FreeSans7pt7b);
//sendToDebug_str(text); sendToDebug_str(" "); sendToDebug_uint16(w, false);
LCDDriver_printTextFont(text, x + (width - w) / 2, y + (height / 2) + h / 2 - 1, active ? text_color : inactive_color, back_color, (GFXfont *)&FreeSans7pt7b);
}
static void printInfo(uint16_t x, uint16_t y, uint16_t width, uint16_t height, char *text, uint16_t back_color, uint16_t text_color, uint16_t inactive_color, bool active)
{
uint16_t x1, y1, w, h;
LCDDriver_Fill_RectWH(x, y, width, height, back_color);
LCDDriver_getTextBounds(text, x, y, &x1, &y1, &w, &h, (GFXfont *)&FreeSans9pt7b);
//sendToDebug_str(text); sendToDebug_str(" "); sendToDebug_uint16(w, false);
LCDDriver_printTextFont(text, x + (width - w) / 2, y + (height / 2) + h / 2 - 1, active ? text_color : inactive_color, back_color, (GFXfont *)&FreeSans9pt7b);
}
void LCD_showError(char text[], bool redraw)
{
if(!LCD_inited)
LCD_Init();
LCD_busy = true;
LCDDriver_Fill(COLOR_RED);
uint16_t x1, y1, w, h;
LCDDriver_getTextBounds(text, 0, 0, &x1, &y1, &w, &h, (GFXfont *)&FreeSans12pt7b);
LCDDriver_printTextFont(text, LCD_WIDTH / 2 - w / 2, LCD_HEIGHT / 2 - h / 2, COLOR_WHITE, COLOR_RED, (GFXfont *)&FreeSans12pt7b);
if (redraw)
HAL_Delay(2000);
LCD_busy = false;
if (redraw)
LCD_redraw(true);
}
void LCD_showInfo(char text[], bool autohide)
{
LCD_busy = true;
LCDDriver_Fill(BG_COLOR);
uint16_t x1, y1, w, h;
LCDDriver_getTextBounds(text, 0, 0, &x1, &y1, &w, &h, (GFXfont *)&FreeSans12pt7b);
LCDDriver_printTextFont(text, LCD_WIDTH / 2 - w / 2, LCD_HEIGHT / 2 - h / 2, COLOR->CLOCK, BG_COLOR, (GFXfont *)&FreeSans12pt7b);
if(autohide)
{
HAL_Delay(2000);
LCD_busy = false;
LCD_redraw(true);
}
}
void LCD_showTooltip(char text[])
{
Tooltip_DiplayStartTime = HAL_GetTick();
strcpy(Tooltip_string, text);
Tooltip_first_draw = true;
if(LCD_UpdateQuery.Tooltip) //redraw old tooltip
LCD_UpdateQuery.FreqInfoRedraw = true;
LCD_UpdateQuery.Tooltip = true;
}
static void LCD_printTooltip(void)
{
LCD_UpdateQuery.Tooltip = true;
if(LCD_busy)
return;
if (LCD_systemMenuOpened)
{
LCD_UpdateQuery.Tooltip = false;
return;
}
LCD_busy = true;
uint16_t x1, y1, w, h;
LCDDriver_getTextBounds(Tooltip_string, LAY_TOOLTIP_POS_X, LAY_TOOLTIP_POS_Y, &x1, &y1, &w, &h, (GFXfont *)&FreeSans12pt7b);
if(Tooltip_first_draw)
{
LCDDriver_Fill_RectWH(LAY_TOOLTIP_POS_X - w / 2, LAY_TOOLTIP_POS_Y, w + LAY_TOOLTIP_MARGIN * 2, h + LAY_TOOLTIP_MARGIN * 2, COLOR->TOOLTIP_BACK);
LCDDriver_drawRectXY(LAY_TOOLTIP_POS_X - w / 2, LAY_TOOLTIP_POS_Y, LAY_TOOLTIP_POS_X - w / 2 + w + LAY_TOOLTIP_MARGIN * 2, LAY_TOOLTIP_POS_Y + h + LAY_TOOLTIP_MARGIN * 2, COLOR->TOOLTIP_BORD);
Tooltip_first_draw = false;
}
LCDDriver_printTextFont(Tooltip_string, LAY_TOOLTIP_POS_X - w / 2 + LAY_TOOLTIP_MARGIN, LAY_TOOLTIP_POS_Y + LAY_TOOLTIP_MARGIN + h, COLOR->TOOLTIP_FORE, COLOR->TOOLTIP_BACK, (GFXfont *)&FreeSans12pt7b);
LCD_busy = false;
if((HAL_GetTick() - Tooltip_DiplayStartTime) > LAY_TOOLTIP_TIMEOUT)
{
LCD_UpdateQuery.Tooltip = false;
LCD_UpdateQuery.FreqInfoRedraw = true;
}
}

Wyświetl plik

@ -1,40 +0,0 @@
#ifndef LCD_h
#define LCD_h
#include "stm32f4xx_hal.h"
#include "trx_manager.h"
#include "lcd_driver.h"
#include "screen_layout.h"
typedef struct
{
bool Background;
bool TopButtons;
bool TopButtonsRedraw;
bool BottomButtons;
bool BottomButtonsRedraw;
bool FreqInfo;
bool FreqInfoRedraw;
bool StatusInfoGUI;
bool StatusInfoGUIRedraw;
bool StatusInfoBar;
bool StatusInfoBarRedraw;
bool SystemMenu;
bool SystemMenuRedraw;
bool SystemMenuCurrent;
bool Tooltip;
} DEF_LCD_UpdateQuery;
extern void LCD_Init(void);
extern void LCD_doEvents(void);
extern void LCD_showError(char text[], bool redraw);
extern void LCD_showInfo(char text[], bool autohide);
extern void LCD_redraw(bool do_now);
extern void LCD_showTooltip(char text[]);
volatile extern DEF_LCD_UpdateQuery LCD_UpdateQuery;
volatile extern bool LCD_busy;
volatile extern bool LCD_systemMenuOpened;
extern STRUCT_COLOR_THEME* COLOR;
#endif

Wyświetl plik

@ -1,5 +0,0 @@
#include "lcd_driver.h"
#if (defined(LAY_480x320))
#include "lcd.h"
#endif

Wyświetl plik

@ -1,403 +0,0 @@
#include "settings.h"
//Header files
#include "lcd_driver.h"
#include "main.h"
#include "fonts.h"
#include "functions.h"
static bool _cp437 = false;
static uint16_t text_cursor_y = 0;
static uint16_t text_cursor_x = 0;
static bool wrap = false;
uint16_t LCDDriver_GetCurrentXOffset(void)
{
return text_cursor_x;
}
void LCDDriver_SetCurrentXOffset(uint16_t x)
{
text_cursor_x = x;
}
//Text printing functions
void LCDDriver_drawChar(uint16_t x, uint16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size)
{
if(c < 32) //non-printable
return;
uint8_t line = 0;
if ((x >= LCD_WIDTH) || // Clip right
(y >= LCD_HEIGHT) || // Clip bottom
((x + 6 * size - 1) < 0) || // Clip left
((y + 8 * size - 1) < 0)) // Clip top
return;
if (!_cp437 && (c >= 176))
c++; // Handle 'classic' charset behavior
LCDDriver_SetCursorAreaPosition(x, y, x + 6 * size - 1, y + 8 * size - 1); //char area
for (int8_t j = 0; j < 8; j++)
{ //y line out
for (int8_t s_y = 0; s_y < size; s_y++) //y size scale
for (int8_t i = 0; i < 6; i++)
{ //x line out
{
if (i == 5)
line = 0x0;
else
line = rastr_font[(c * 5) + i]; //read font
line >>= j;
for (int8_t s_x = 0; s_x < size; s_x++) //x size scale
{
if (line & 0x1)
LCDDriver_SendData(color); //font pixel
else
LCDDriver_SendData(bg); //background pixel
}
}
}
}
}
void LCDDriver_printText(char text[], uint16_t x, uint16_t y, uint16_t color, uint16_t bg, uint8_t size)
{
uint16_t offset = size * 6;
uint16_t skipped = 0;
for (uint16_t i = 0; i < 128 && text[i] != 0; i++)
{
if (text[i] == '^' && text[i + 1] == 'o') //celsius
{
i++;
skipped++;
LCDDriver_drawChar(x + (offset * (i - skipped)), y - 3, text[i], color, bg, size);
text_cursor_x = x + (offset * (i + 1 - skipped));
}
else
{
LCDDriver_drawChar(x + (offset * (i - skipped)), y, text[i], color, bg, size);
text_cursor_x = x + (offset * (i + 1 - skipped));
}
}
}
void LCDDriver_drawCharFont(uint16_t x, uint16_t y, unsigned char c, uint16_t color, uint16_t bg, const GFXfont *gfxFont)
{
c -= gfxFont->first;
GFXglyph *glyph = (GFXglyph *)&gfxFont->glyph[c];
uint16_t bo = glyph->bitmapOffset;
uint8_t bits = 0;
uint8_t bit = 0;
int16_t ys1 = y + glyph->yOffset;
int16_t ys2 = y + glyph->yOffset + glyph->height - 1;
if (ys1 < 0)
ys1 = 0;
if (ys2 < 0)
ys2 = 0;
LCDDriver_SetCursorAreaPosition(x, (uint16_t)ys1, x + glyph->xAdvance - 1, (uint16_t)ys2); //char area
for (uint8_t yy = 0; yy < glyph->height; yy++)
{
for (uint8_t xx = 0; xx < glyph->xAdvance; xx++)
{
if (xx < glyph->xOffset || xx >= (glyph->xOffset + glyph->width))
{
LCDDriver_SendData(bg); //background pixel
continue;
}
if (!(bit++ & 7))
{
bits = gfxFont->bitmap[bo++];
}
if (bits & 0x80)
{
LCDDriver_SendData(color); //font pixel
}
else
{
LCDDriver_SendData(bg); //background pixel
}
bits <<= 1;
}
}
}
void LCDDriver_printTextFont(char text[], uint16_t x, uint16_t y, uint16_t color, uint16_t bg, const GFXfont *gfxFont)
{
uint8_t c = 0;
text_cursor_x = x;
text_cursor_y = y;
for (uint16_t i = 0; i < 256 && text[i] != NULL; i++)
{
c = text[i];
if (c == '\n')
{
text_cursor_x = 0;
text_cursor_y += gfxFont->yAdvance;
}
else if (c != '\r')
{
if ((c >= gfxFont->first) && (c <= gfxFont->last))
{
GFXglyph *glyph = (GFXglyph *)&gfxFont->glyph[c - gfxFont->first];
if ((glyph->width > 0) && (glyph->height > 0))
{
if (wrap && ((text_cursor_x + (glyph->xOffset + glyph->width)) > LCD_WIDTH))
{
text_cursor_x = 0;
text_cursor_y += gfxFont->yAdvance;
}
LCDDriver_drawCharFont(text_cursor_x, text_cursor_y, c, color, bg, gfxFont);
}
text_cursor_x += glyph->xAdvance;
}
}
}
}
/**************************************************************************/
/*!
@brief Helper to determine size of a character with current font/size.
Broke this out as it's used by both the PROGMEM- and RAM-resident getTextBounds() functions.
@param c The ascii character in question
@param x Pointer to x location of character
@param y Pointer to y location of character
@param minx Minimum clipping value for X
@param miny Minimum clipping value for Y
@param maxx Maximum clipping value for X
@param maxy Maximum clipping value for Y
*/
/**************************************************************************/
static void LCDDriver_charBounds(char c, uint16_t *x, uint16_t *y, int16_t *minx, int16_t *miny, int16_t *maxx, int16_t *maxy, const GFXfont *gfxFont)
{
if (c == '\n')
{ // Newline?
*x = 0; // Reset x to zero, advance y by one line
*y += gfxFont->yAdvance;
}
else if (c != '\r')
{
if ((c >= gfxFont->first) && (c <= gfxFont->last))
{ // Char present in this font?
GFXglyph *glyph = (GFXglyph *)&gfxFont->glyph[c - gfxFont->first];
if (wrap && ((*x + (((int16_t)glyph->xOffset + glyph->width))) > LCD_WIDTH))
{
*x = 0; // Reset x to zero, advance y by one line
*y += gfxFont->yAdvance;
}
int16_t x1 = *x + glyph->xOffset,
y1 = *y + glyph->yOffset,
x2 = x1 + glyph->width - 1,
y2 = y1 + glyph->height - 1;
if (x1 < *minx)
*minx = x1;
if (y1 < *miny)
*miny = y1;
if (x2 > *maxx)
*maxx = x2;
if (y2 > *maxy)
*maxy = y2;
*x += glyph->xAdvance;
}
}
}
/**************************************************************************/
/*!
@brief Helper to determine size of a string with current font/size. Pass string and a cursor position, returns UL corner and W,H.
@param str The ascii string to measure
@param x The current cursor X
@param y The current cursor Y
@param x1 The boundary X coordinate, set by function
@param y1 The boundary Y coordinate, set by function
@param w The boundary width, set by function
@param h The boundary height, set by function
*/
/**************************************************************************/
void LCDDriver_getTextBounds(char text[], uint16_t x, uint16_t y, uint16_t *x1, uint16_t *y1, uint16_t *w, uint16_t *h, const GFXfont *gfxFont)
{
uint8_t c; // Current character
*x1 = x;
*y1 = y;
*w = *h = 0;
int16_t minx = LCD_WIDTH, miny = LCD_HEIGHT, maxx = 0, maxy = 0;
for (uint16_t i = 0; i < 40 && text[i] != NULL; i++)
{
c = text[i];
LCDDriver_charBounds(c, &x, &y, &minx, &miny, &maxx, &maxy, gfxFont);
}
if (maxx >= minx)
{
*x1 = (uint16_t)minx;
*w = (uint16_t)(maxx - minx + 1);
}
if (maxy >= miny)
{
*y1 = (uint16_t)miny;
*h = (uint16_t)(maxy - miny + 1);
}
}
//Image print (RGB 565, 2 bytes per pixel)
void LCDDriver_printImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data)
{
uint32_t n = w * h * 2;
LCDDriver_SetCursorAreaPosition(x, y, w + x - 1, h + y - 1);
for (uint32_t i = 0; i < n; i += 2)
{
LCDDriver_SendData((uint16_t)((data[i] << 8) | data[i + 1]));
}
}
void LCDDriver_printImage_RLECompressed(uint16_t x, uint16_t y, const tIMAGE *image, uint16_t transparent_color, uint16_t bg_color)
{
uint32_t pixels = image->width * image->height;
uint32_t i = 0;
uint32_t decoded = 0;
LCDDriver_SetCursorAreaPosition(x, y, image->width + x - 1, image->height + y - 1);
while (true)
{
if ((int16_t)image->data[i] < 0) // no repeats
{
uint16_t count = (-(int16_t)image->data[i]);
i++;
for (uint16_t p = 0; p < count; p++)
{
if(image->data[i] == transparent_color)
LCDDriver_SendData(bg_color);
else
LCDDriver_SendData(image->data[i]);
decoded++;
i++;
if (pixels <= decoded)
return;
}
}
else //repeats
{
uint16_t count = ((int16_t)image->data[i]);
i++;
for (uint16_t p = 0; p < count; p++)
{
if(image->data[i] == transparent_color)
LCDDriver_SendData(bg_color);
else
LCDDriver_SendData(image->data[i]);
decoded++;
if (pixels <= decoded)
return;
}
i++;
}
}
}
static uint32_t RLEStream_pixels = 0;
static uint32_t RLEStream_decoded = 0;
static uint8_t RLEStream_state = 0;
void LCDDriver_printImage_RLECompressed_StartStream(uint16_t x, uint16_t y, uint16_t width, uint16_t height)
{
RLEStream_pixels = width * height;
RLEStream_decoded = 0;
RLEStream_state = 0;
LCDDriver_SetCursorAreaPosition(x, y, width + x - 1, height + y - 1);
}
void LCDDriver_printImage_RLECompressed_ContinueStream(int16_t *data, uint16_t len)
{
static uint16_t nr_count = 0;
static uint16_t nr_count_p = 0;
static uint16_t r_count = 0;
static uint16_t r_count_p = 0;
uint32_t processed = 0;
while (processed < len)
{
if ((((int16_t)data[processed] < 0) && (RLEStream_state == 0)) || (RLEStream_state == 1)) // no repeats
{
if(RLEStream_state == 0)
{
nr_count = (-(int16_t)data[processed]);
nr_count_p = 0;
processed++;
}
RLEStream_state = 1;
if(processed >= len)
return;
for (; nr_count_p < nr_count;)
{
LCDDriver_SendData(data[processed]);
RLEStream_decoded++;
nr_count_p++;
processed++;
if (RLEStream_pixels <= RLEStream_decoded)
return;
if(processed >= len && nr_count_p < nr_count)
return;
}
RLEStream_state = 0;
}
else if ((((int16_t)data[processed] > 0) && (RLEStream_state == 0)) || (RLEStream_state == 2)) //repeats
{
if(RLEStream_state == 0)
{
r_count = ((int16_t)data[processed]);
r_count_p = 0;
processed++;
}
RLEStream_state = 2;
if(processed >= len)
return;
for (; r_count_p < r_count;)
{
LCDDriver_SendData(data[processed]);
r_count_p++;
RLEStream_decoded++;
if (RLEStream_pixels <= RLEStream_decoded)
return;
}
processed++;
RLEStream_state = 0;
}
else
processed++;
}
}
inline uint16_t addColor(uint16_t color, uint8_t add_r, uint8_t add_g, uint8_t add_b)
{
uint8_t r = ((color >> 11) & 0x1F) + add_r;
uint8_t g = ((color >> 5) & 0x3F) + (uint8_t)(add_g << 1);
uint8_t b = ((color >> 0) & 0x1F) + add_b;
if (r > 31)
r = 31;
if (g > 63)
g = 63;
if (b > 31)
b = 31;
return (uint16_t)((r << 11) | (g << 5) | b);
}
inline uint16_t mixColors(uint16_t color1, uint16_t color2, float32_t opacity)
{
uint8_t r = (uint8_t)((float32_t)((color1 >> 11) & 0x1F) * (1.0f - opacity) + (float32_t)((color2 >> 11) & 0x1F) * opacity);
uint8_t g = (uint8_t)((float32_t)((color1 >> 5) & 0x3F) * (1.0f - opacity) + (float32_t)((color2 >> 5) & 0x3F) * opacity);
uint8_t b = (uint8_t)((float32_t)((color1 >> 0) & 0x1F) * (1.0f - opacity) + (float32_t)((color2 >> 0) & 0x1F) * opacity);
if (r > 31)
r = 31;
if (g > 63)
g = 63;
if (b > 31)
b = 31;
return (uint16_t)(r << 11) | (uint16_t)(g << 5) | (uint16_t)b;
}

Wyświetl plik

@ -1,107 +0,0 @@
#ifndef _LCDDRIVER_H_
#define _LCDDRIVER_H_
//List of includes
#include "settings.h"
#include <stdbool.h>
#include "stm32f4xx_hal.h"
#include <stdlib.h>
#include <stdio.h>
#include "images.h"
#define LCD_FSMC_COMM_ADDR 0x60000000
#define LCD_FSMC_DATA_ADDR 0x60080000
//LCD dimensions defines
#if (defined(LCD_ILI9481) || defined(LCD_HX8357B) || defined(LCD_HX8357C) || defined(LCD_ILI9486) || defined (LCD_SSD1963) || defined(LCD_R61581))
#include "lcd_driver_ILI9481.h"
#endif
#if (LCD_WIDTH == 480 && LCD_HEIGHT == 320)
#define LAY_480x320
#endif
#define LCD_PIXEL_COUNT (LCD_WIDTH * LCD_HEIGHT)
//List of colors
#define COLOR_BLACK 0x0000
#define COLOR_NAVY 0x000F
#define COLOR_DGREEN 0x03E0
#define COLOR_DCYAN 0x03EF
#define COLOR_MAROON 0x7800
#define COLOR_PURPLE 0x780F
#define COLOR_OLIVE 0x7BE0
#define COLOR_LGRAY 0xC618
#define COLOR_DGRAY 0x7BEF
#define COLOR_BLUE 0x001F
#define COLOR_BLUE2 0x051D
#define COLOR_GREEN 0x07E0
#define COLOR_GREEN2 0xB723
#define COLOR_GREEN3 0x8000
#define COLOR_CYAN 0x07FF
#define COLOR_RED 0xF800
#define COLOR_MAGENTA 0xF81F
#define COLOR_YELLOW 0xFFE0
#define COLOR_WHITE 0xFFFF
#define COLOR_ORANGE 0xFD20
#define COLOR_GREENYELLOW 0xAFE5
#define COLOR_BROWN 0XBC40
/// Font data stored PER GLYPH
typedef struct
{
uint16_t bitmapOffset; ///< Pointer into GFXfont->bitmap
uint8_t width; ///< Bitmap dimensions in pixels
uint8_t height; ///< Bitmap dimensions in pixels
uint8_t xAdvance; ///< Distance to advance cursor (x axis)
int8_t xOffset; ///< X dist from cursor pos to UL corner
int8_t yOffset; ///< Y dist from cursor pos to UL corner
} GFXglyph;
/// Data stored for FONT AS A WHOLE
typedef struct
{
const uint8_t *bitmap; ///< Glyph bitmaps, concatenated
const GFXglyph *glyph; ///< Glyph array
const uint8_t first; ///< ASCII extents (first char)
const uint8_t last; ///< ASCII extents (last char)
const uint8_t yAdvance; ///< Newline distance (y axis)
} GFXfont;
//Functions defines Macros
#define uswap(a, b) \
{ \
uint16_t t = a; \
a = b; \
b = t; \
}
#define rgb888torgb565(r, g, b) ((uint16_t)(((r & 0xF8) << 8) | ((g & 0xFC) << 3) | ((b & 0xFF) >> 3)))
extern void LCDDriver_SendData(uint16_t data);
extern uint16_t LCDDriver_readReg(uint16_t reg);
extern void LCDDriver_SetCursorAreaPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
extern uint16_t LCDDriver_GetCurrentXOffset(void);
extern void LCDDriver_Init(void);
extern void LCDDriver_Fill(uint16_t color);
extern void LCDDriver_Fill_RectXY(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
extern void LCDDriver_Fill_RectWH(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color);
extern void LCDDriver_Fill_Triangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color);
extern void LCDDriver_drawPixel(uint16_t x, uint16_t y, uint16_t color);
extern void LCDDriver_drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
extern void LCDDriver_drawFastHLine(uint16_t x, uint16_t y, int16_t w, uint16_t color);
extern void LCDDriver_drawFastVLine(uint16_t x, uint16_t y, int16_t h, uint16_t color);
extern void LCDDriver_drawRectXY(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color);
extern void LCDDriver_drawChar(uint16_t x, uint16_t y, unsigned char c, uint16_t color, uint16_t bg, uint8_t size);
extern void LCDDriver_drawCharFont(uint16_t x, uint16_t y, unsigned char c, uint16_t color, uint16_t bg, const GFXfont *gfxFont);
extern void LCDDriver_printText(char text[], uint16_t x, uint16_t y, uint16_t color, uint16_t bg, uint8_t size);
extern void LCDDriver_printTextFont(char text[], uint16_t x, uint16_t y, uint16_t color, uint16_t bg, const GFXfont *gfxFont);
extern void LCDDriver_getTextBounds(char text[], uint16_t x, uint16_t y, uint16_t *x1, uint16_t *y1, uint16_t *w, uint16_t *h, const GFXfont *gfxFont);
extern void LCDDriver_printImage(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint8_t *data);
extern void LCDDriver_printImage_RLECompressed(uint16_t x, uint16_t y, const tIMAGE *image, uint16_t transparent_color, uint16_t bg_color);
extern void LCDDriver_setRotation(uint8_t rotate);
extern void LCDDriver_setBrightness(uint8_t percent);
extern void LCDDriver_printImage_RLECompressed_StartStream(uint16_t x, uint16_t y, uint16_t width, uint16_t height);
extern void LCDDriver_printImage_RLECompressed_ContinueStream(int16_t *data, uint16_t len);
extern uint16_t addColor(uint16_t color, uint8_t add_r, uint8_t add_g, uint8_t add_b); //add opacity or mix colors
extern uint16_t mixColors(uint16_t color1, uint16_t color2, float32_t opacity); //mix two colors with opacity
#endif

Wyświetl plik

@ -1,724 +0,0 @@
#include "settings.h"
#if (defined(LCD_ILI9481) || defined(LCD_HX8357B) || defined(LCD_HX8357C) || defined(LCD_ILI9486) || defined(LCD_R61581))
//Header files
#include "lcd_driver.h"
#include "main.h"
#include "fonts.h"
#include "functions.h"
#include "lcd_driver_ILI9481.h"
//***** Functions prototypes *****//
static inline void LCDDriver_SetCursorPosition(uint16_t x, uint16_t y);
inline void LCDDriver_SetCursorAreaPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2);
//Write command to LCD
inline void LCDDriver_SendCommand(uint16_t com)
{
*(__IO uint16_t *)((uint32_t)(LCD_FSMC_COMM_ADDR)) = com;
}
//Write data to LCD
inline void LCDDriver_SendData(uint16_t data)
{
*(__IO uint16_t *)((uint32_t)(LCD_FSMC_DATA_ADDR)) = data;
}
//Write pair command-data
inline void LCDDriver_writeReg(uint16_t reg, uint16_t val) {
LCDDriver_SendCommand(reg);
LCDDriver_SendData(val);
}
//Read command from LCD
inline uint16_t LCDDriver_ReadStatus(void)
{
return *(__IO uint16_t *)((uint32_t)(LCD_FSMC_COMM_ADDR));
}
//Read data from LCD
inline uint16_t LCDDriver_ReadData(void)
{
return *(__IO uint16_t *)((uint32_t)(LCD_FSMC_DATA_ADDR));
}
//Read Register
inline uint16_t LCDDriver_readReg(uint16_t reg)
{
LCDDriver_SendCommand(reg);
return LCDDriver_ReadData();
}
//Initialise function
void LCDDriver_Init(void)
{
#if (defined(LCD_ILI9481) || defined(LCD_HX8357B))
#define ILI9481_COMM_DELAY 20
LCDDriver_SendCommand(LCD_COMMAND_SOFT_RESET); //0x01
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_EXIT_SLEEP_MODE); //0x11
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_NORMAL_MODE_ON); //0x13
LCDDriver_SendCommand(LCD_COMMAND_POWER_SETTING); //(0xD0);
LCDDriver_SendData(0x07);
LCDDriver_SendData(0x42);
LCDDriver_SendData(0x18);
LCDDriver_SendCommand(LCD_COMMAND_VCOM); //(0xD1);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x07);
LCDDriver_SendData(0x10);
LCDDriver_SendCommand(LCD_COMMAND_NORMAL_PWR_WR); //(0xD2);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x02);
HAL_Delay(ILI9481_COMM_DELAY);
#if defined(LCD_HX8357B)
LCDDriver_SendCommand(LCD_COMMAND_PANEL_DRV_CTL); //(0xC0);
LCDDriver_SendData(0x10);
LCDDriver_SendData(0x3B);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x02);
LCDDriver_SendData(0x11);
HAL_Delay(ILI9481_COMM_DELAY);
#endif
LCDDriver_SendCommand(LCD_COMMAND_FR_SET); //(0xC5);
LCDDriver_SendData(0x03);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_GAMMAWR); //(0xC8);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x32);
LCDDriver_SendData(0x36);
LCDDriver_SendData(0x45);
LCDDriver_SendData(0x06);
LCDDriver_SendData(0x16);
LCDDriver_SendData(0x37);
LCDDriver_SendData(0x75);
LCDDriver_SendData(0x77);
LCDDriver_SendData(0x54);
LCDDriver_SendData(0x0C);
LCDDriver_SendData(0x00);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_MADCTL); //(0x36);
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_PIXEL_FORMAT); //(0x3A);
LCDDriver_SendData(0x55);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_COLUMN_ADDR); //(0x2A);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x3F);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_PAGE_ADDR); //(0x2B);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0xDF);
HAL_Delay(ILI9481_COMM_DELAY);
#if defined(LCD_HX8357B)
LCDDriver_SendCommand(LCD_COMMAND_COLOR_INVERSION_ON); //(0x21);
HAL_Delay(ILI9481_COMM_DELAY);
#endif
LCDDriver_SendCommand(LCD_COMMAND_IDLE_OFF); //(0x38);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(LCD_COMMAND_DISPLAY_ON); //(0x29);
HAL_Delay(ILI9481_COMM_DELAY);
#endif
#if defined(LCD_HX8357C)
LCDDriver_SendCommand(0x11);
HAL_Delay(20);
LCDDriver_SendCommand(0xD0);
LCDDriver_SendData(0x07);
LCDDriver_SendData(0x42);
LCDDriver_SendData(0x18);
LCDDriver_SendCommand(0xD1);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x07);
LCDDriver_SendData(0x10);
LCDDriver_SendCommand(0xD2);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x02);
LCDDriver_SendCommand(0xC0);
LCDDriver_SendData(0x10);
LCDDriver_SendData(0x3B);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x02);
LCDDriver_SendData(0x11);
LCDDriver_SendCommand(0xC5);
LCDDriver_SendData(0x03);
LCDDriver_SendCommand(0xC8);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x32);
LCDDriver_SendData(0x36);
LCDDriver_SendData(0x45);
LCDDriver_SendData(0x06);
LCDDriver_SendData(0x16);
LCDDriver_SendData(0x37);
LCDDriver_SendData(0x75);
LCDDriver_SendData(0x77);
LCDDriver_SendData(0x54);
LCDDriver_SendData(0x0C);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0x36);
LCDDriver_SendData(0x8A);
LCDDriver_SendCommand(0x35); // Tearing effect on
LCDDriver_SendData(0x00); // Added parameter
LCDDriver_SendCommand(0x3A);
LCDDriver_SendData(0x55);
LCDDriver_SendCommand(0x2A);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x3F);
LCDDriver_SendCommand(0x2B);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0xE0);
HAL_Delay(120);
LCDDriver_SendCommand(0x29);
#endif
#if defined(LCD_ILI9486)
#define ILI9481_COMM_DELAY 100
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(0XF1);
LCDDriver_SendData(0x36);
LCDDriver_SendData(0x04);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x3C);
LCDDriver_SendData(0X0F);
LCDDriver_SendData(0x8F);
LCDDriver_SendCommand(0XF2);
LCDDriver_SendData(0x18);
LCDDriver_SendData(0xA3);
LCDDriver_SendData(0x12);
LCDDriver_SendData(0x02);
LCDDriver_SendData(0XB2);
LCDDriver_SendData(0x12);
LCDDriver_SendData(0xFF);
LCDDriver_SendData(0x10);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0XF8);
LCDDriver_SendData(0x21);
LCDDriver_SendData(0x04);
LCDDriver_SendCommand(0XF9);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x08);
LCDDriver_SendCommand(0x36);
LCDDriver_SendData(0x08);
LCDDriver_SendCommand(0xB4);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0xC1);
LCDDriver_SendData(0x47); //0x41
LCDDriver_SendCommand(0xC5);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0xAF); //0x91
LCDDriver_SendData(0x80);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0xE0);
LCDDriver_SendData(0x0F);
LCDDriver_SendData(0x1F);
LCDDriver_SendData(0x1C);
LCDDriver_SendData(0x0C);
LCDDriver_SendData(0x0F);
LCDDriver_SendData(0x08);
LCDDriver_SendData(0x48);
LCDDriver_SendData(0x98);
LCDDriver_SendData(0x37);
LCDDriver_SendData(0x0A);
LCDDriver_SendData(0x13);
LCDDriver_SendData(0x04);
LCDDriver_SendData(0x11);
LCDDriver_SendData(0x0D);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0xE1);
LCDDriver_SendData(0x0F);
LCDDriver_SendData(0x32);
LCDDriver_SendData(0x2E);
LCDDriver_SendData(0x0B);
LCDDriver_SendData(0x0D);
LCDDriver_SendData(0x05);
LCDDriver_SendData(0x47);
LCDDriver_SendData(0x75);
LCDDriver_SendData(0x37);
LCDDriver_SendData(0x06);
LCDDriver_SendData(0x10);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x24);
LCDDriver_SendData(0x20);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0x3A);
LCDDriver_SendData(0x55);
LCDDriver_SendCommand(0x11);
LCDDriver_SendCommand(0x36);
LCDDriver_SendData(0x28);
HAL_Delay(ILI9481_COMM_DELAY);
LCDDriver_SendCommand(0x29);
#endif
#if defined(LCD_R61581)
LCDDriver_SendCommand(0xB0);
LCDDriver_SendData(0x1E);
LCDDriver_SendCommand(0xB0);
LCDDriver_SendData(0x00);
LCDDriver_SendCommand(0xB3);
LCDDriver_SendData(0x02);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x10);
LCDDriver_SendCommand(0xB4);
LCDDriver_SendData(0x00);//0X10
// LCDDriver_SendCommand(0xB9); //PWM Settings for Brightness Control
// LCDDriver_SendData(0x01);// Disabled by default.
// LCDDriver_SendData(0xFF); //0xFF = Max brightness
// LCDDriver_SendData(0xFF);
// LCDDriver_SendData(0x18);
LCDDriver_SendCommand(0xC0);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x3B);//
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x00);//NW
LCDDriver_SendData(0x43);
LCDDriver_SendCommand(0xC1);
LCDDriver_SendData(0x08);
LCDDriver_SendData(0x15);//CLOCK
LCDDriver_SendData(0x08);
LCDDriver_SendData(0x08);
LCDDriver_SendCommand(0xC4);
LCDDriver_SendData(0x15);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x01);
LCDDriver_SendCommand(0xC6);
LCDDriver_SendData(0x02);
LCDDriver_SendCommand(0xC8);
LCDDriver_SendData(0x0c);
LCDDriver_SendData(0x05);
LCDDriver_SendData(0x0A);//0X12
LCDDriver_SendData(0x6B);//0x7D
LCDDriver_SendData(0x04);
LCDDriver_SendData(0x06);//0x08
LCDDriver_SendData(0x15);//0x0A
LCDDriver_SendData(0x10);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x60);//0x23
LCDDriver_SendCommand(0x36);
LCDDriver_SendData(0x0A);
LCDDriver_SendCommand(0x0C);
LCDDriver_SendData(0x55);
LCDDriver_SendCommand(0x3A);
LCDDriver_SendData(0x55);
LCDDriver_SendCommand(0x38);
LCDDriver_SendCommand(0xD0);
LCDDriver_SendData(0x07);
LCDDriver_SendData(0x07);//VCI1
LCDDriver_SendData(0x14);//VRH 0x1D
LCDDriver_SendData(0xA2);//BT 0x06
LCDDriver_SendCommand(0xD1);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x5A);//VCM 0x5A
LCDDriver_SendData(0x10);//VDV
LCDDriver_SendCommand(0xD2);
LCDDriver_SendData(0x03);
LCDDriver_SendData(0x04);//0x24
LCDDriver_SendData(0x04);
LCDDriver_SendCommand(0x11);
HAL_Delay(150);
LCDDriver_SendCommand(0x2A);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0xDF);//320
LCDDriver_SendCommand(0x2B);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x00);
LCDDriver_SendData(0x01);
LCDDriver_SendData(0x3F);//480
HAL_Delay(100);
LCDDriver_SendCommand(0x29);
HAL_Delay(30);
LCDDriver_SendCommand(0x2C);
HAL_Delay(30);
#endif
}
//Set screen rotation
void LCDDriver_setRotation(uint8_t rotate)
{
#if defined(LCD_ILI9481) || defined(LCD_HX8357B) || defined(LCD_ILI9486)
LCDDriver_SendCommand(LCD_COMMAND_MADCTL);
switch (rotate)
{
case 1: // Portrait
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MX);
break;
case 2: // Landscape (Portrait + 90)
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MV);
break;
case 3: // Inverter portrait
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MY);
break;
case 4: // Inverted landscape
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MV | LCD_PARAM_MADCTL_MX | LCD_PARAM_MADCTL_MY);
//LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MV | LCD_PARAM_MADCTL_SS | LCD_PARAM_MADCTL_GS);
break;
}
HAL_Delay(120);
#endif
#if defined(LCD_HX8357C)
LCDDriver_SendCommand(LCD_COMMAND_MADCTL);
switch (rotate)
{
case 1: // Portrait
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MX);
break;
case 2: // Landscape (Portrait + 90)
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MV);
break;
case 3: // Inverter portrait
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MY);
break;
case 4: // Inverted landscape
LCDDriver_SendData(LCD_PARAM_MADCTL_BGR | LCD_PARAM_MADCTL_MV | LCD_PARAM_MADCTL_GS | LCD_PARAM_MADCTL_ML | LCD_PARAM_MADCTL_SS);
break;
}
HAL_Delay(120);
#endif
}
//Set cursor position
inline void LCDDriver_SetCursorAreaPosition(uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2)
{
LCDDriver_SendCommand(LCD_COMMAND_COLUMN_ADDR);
LCDDriver_SendData(x1 >> 8);
LCDDriver_SendData(x1 & 0xFF);
LCDDriver_SendData(x2 >> 8);
LCDDriver_SendData(x2 & 0xFF);
LCDDriver_SendCommand(LCD_COMMAND_PAGE_ADDR);
LCDDriver_SendData(y1 >> 8);
LCDDriver_SendData(y1 & 0xFF);
LCDDriver_SendData(y2 >> 8);
LCDDriver_SendData(y2 & 0xFF);
LCDDriver_SendCommand(LCD_COMMAND_GRAM);
}
static inline void LCDDriver_SetCursorPosition(uint16_t x, uint16_t y)
{
LCDDriver_SendCommand(LCD_COMMAND_COLUMN_ADDR);
LCDDriver_SendData(x >> 8); //-V760
LCDDriver_SendData(x & 0xFF);
LCDDriver_SendData(x >> 8);
LCDDriver_SendData(x & 0xFF);
LCDDriver_SendCommand(LCD_COMMAND_PAGE_ADDR);
LCDDriver_SendData(y >> 8); //-V760
LCDDriver_SendData(y & 0xFF);
LCDDriver_SendData(y >> 8);
LCDDriver_SendData(y & 0xFF);
LCDDriver_SendCommand(LCD_COMMAND_GRAM);
}
//Write data to a single pixel
void LCDDriver_drawPixel(uint16_t x, uint16_t y, uint16_t color)
{
LCDDriver_SetCursorPosition(x, y);
LCDDriver_SendData(color);
}
//Fill the entire screen with a background color
void LCDDriver_Fill(uint16_t color)
{
LCDDriver_Fill_RectXY(0, 0, LCD_WIDTH, LCD_HEIGHT, color);
}
//Rectangle drawing functions
IRAM1 static uint16_t fillxy_color = 0;
void LCDDriver_Fill_RectXY(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
{
if (x1 > (LCD_WIDTH - 1))
x1 = LCD_WIDTH - 1;
if (y1 > (LCD_HEIGHT - 1))
y1 = LCD_HEIGHT - 1;
uint32_t n = ((x1 + 1) - x0) * ((y1 + 1) - y0);
if (n > LCD_PIXEL_COUNT)
n = LCD_PIXEL_COUNT;
LCDDriver_SetCursorAreaPosition(x0, y0, x1, y1);
fillxy_color = color;
if (n > 50)
{
const uint32_t part_size = 30000;
uint32_t estamated = n;
while (estamated > 0)
{
if (estamated >= part_size)
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream3, (uint32_t)&fillxy_color, LCD_FSMC_DATA_ADDR, part_size);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream3, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
estamated -= part_size;
}
else
{
HAL_DMA_Start(&hdma_memtomem_dma2_stream3, (uint32_t)&fillxy_color, LCD_FSMC_DATA_ADDR, estamated);
HAL_DMA_PollForTransfer(&hdma_memtomem_dma2_stream3, HAL_DMA_FULL_TRANSFER, HAL_MAX_DELAY);
estamated = 0;
}
}
}
else
{
while (n--)
{
LCDDriver_SendData(color);
}
}
}
void LCDDriver_Fill_RectWH(uint16_t x, uint16_t y, uint16_t w, uint16_t h, uint16_t color)
{
LCDDriver_Fill_RectXY(x, y, x + w, y + h, color);
}
//Line drawing functions
void LCDDriver_drawLine(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
{
int16_t steep = abs(y1 - y0) > abs(x1 - x0);
if (steep)
{
uswap(x0, y0)
uswap(x1, y1)
}
if (x0 > x1)
{
uswap(x0, x1)
uswap(y0, y1)
}
int16_t dx, dy;
dx = (int16_t)(x1 - x0);
dy = (int16_t)abs(y1 - y0);
int16_t err = dx / 2;
int16_t ystep;
if (y0 < y1)
{
ystep = 1;
}
else
{
ystep = -1;
}
for (; x0 <= x1; x0++)
{
if (steep)
{
LCDDriver_drawPixel(y0, x0, color);
}
else
{
LCDDriver_drawPixel(x0, y0, color);
}
err -= dy;
if (err < 0)
{
y0 += ystep;
err += dx;
}
}
}
void LCDDriver_drawFastHLine(uint16_t x, uint16_t y, int16_t w, uint16_t color)
{
int16_t x2 = x + w;
if (x2 < 0)
x2 = 0;
if (x2 > (LCD_WIDTH - 1))
x2 = LCD_WIDTH - 1;
if (x2 < x)
LCDDriver_Fill_RectXY((uint16_t)x2, y, x, y, color);
else
LCDDriver_Fill_RectXY(x, y, (uint16_t)x2, y, color);
}
void LCDDriver_drawFastVLine(uint16_t x, uint16_t y, int16_t h, uint16_t color)
{
int16_t y2 = y + h - 1;
if (y2 < 0)
y2 = 0;
if (y2 > (LCD_HEIGHT - 1))
y2 = LCD_HEIGHT - 1;
if (y2 < y)
LCDDriver_Fill_RectXY(x, (uint16_t)y2, x, y, color);
else
LCDDriver_Fill_RectXY(x, y, x, (uint16_t)y2, color);
}
void LCDDriver_drawRectXY(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t color)
{
LCDDriver_drawFastHLine(x0, y0, (int16_t)(x1 - x0), color);
LCDDriver_drawFastHLine(x0, y1, (int16_t)(x1 - x0), color);
LCDDriver_drawFastVLine(x0, y0, (int16_t)(y1 - y0), color);
LCDDriver_drawFastVLine(x1, y0, (int16_t)(y1 - y0), color);
}
void LCDDriver_Fill_Triangle(uint16_t x0, uint16_t y0, uint16_t x1, uint16_t y1, uint16_t x2, uint16_t y2, uint16_t color)
{
int16_t a, b, y, last;
// Sort coordinates by Y order (y2 >= y1 >= y0)
if (y0 > y1)
{
_swap_int16_t(y0, y1)
_swap_int16_t(x0, x1)
}
if (y1 > y2)
{
_swap_int16_t(y2, y1)
_swap_int16_t(x2, x1)
}
if (y0 > y1)
{
_swap_int16_t(y0, y1)
_swap_int16_t(x0, x1)
}
if (y0 == y2)
{ // Handle awkward all-on-same-line case as its own thing
a = b = x0;
if (x1 < a)
a = x1;
else if (x1 > b)
b = x1;
if (x2 < a)
a = x2;
else if (x2 > b)
b = x2;
LCDDriver_drawFastHLine(a, y0, b - a + 1, color);
return;
}
int16_t dx01 = x1 - x0, dy01 = y1 - y0, dx02 = x2 - x0, dy02 = y2 - y0,
dx12 = x2 - x1, dy12 = y2 - y1;
int32_t sa = 0, sb = 0;
// For upper part of triangle, find scanline crossings for segments
// 0-1 and 0-2. If y1=y2 (flat-bottomed triangle), the scanline y1
// is included here (and second loop will be skipped, avoiding a /0
// error there), otherwise scanline y1 is skipped here and handled
// in the second loop...which also avoids a /0 error here if y0=y1
// (flat-topped triangle).
if (y1 == y2)
last = y1; // Include y1 scanline
else
last = y1 - 1; // Skip it
for (y = y0; y <= last; y++)
{
a = x0 + sa / dy01;
b = x0 + sb / dy02;
sa += dx01;
sb += dx02;
/* longhand:
a = x0 + (x1 - x0) * (y - y0) / (y1 - y0);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b)
_swap_int16_t(a, b)
LCDDriver_drawFastHLine(a, y, b - a + 1, color);
}
// For lower part of triangle, find scanline crossings for segments
// 0-2 and 1-2. This loop is skipped if y1=y2.
sa = (int32_t)dx12 * (y - y1);
sb = (int32_t)dx02 * (y - y0);
for (; y <= y2; y++)
{
a = x1 + sa / dy12;
b = x0 + sb / dy02;
sa += dx12;
sb += dx02;
/* longhand:
a = x1 + (x2 - x1) * (y - y1) / (y2 - y1);
b = x0 + (x2 - x0) * (y - y0) / (y2 - y0);
*/
if (a > b)
_swap_int16_t(a, b)
LCDDriver_drawFastHLine(a, y, b - a + 1, color);
}
}
#endif

Wyświetl plik

@ -1,51 +0,0 @@
#ifndef _LCDDRIVER_ILI9481_H_
#include "settings.h"
#if (defined(LCD_ILI9481) || defined(LCD_HX8357B) || defined(LCD_HX8357C) || defined(LCD_ILI9486) || defined(LCD_R61581))
#define _LCDDRIVER_ILI9481_H_
//LCD dimensions defines
#define LCD_WIDTH 480
#define LCD_HEIGHT 320
//ILI9481 LCD commands
#define LCD_COMMAND_COLUMN_ADDR 0x2A
#define LCD_COMMAND_PAGE_ADDR 0x2B
#define LCD_COMMAND_GRAM 0x2C
#define LCD_COMMAND_SOFT_RESET 0x01
#define LCD_COMMAND_NORMAL_MODE_ON 0x13
#define LCD_COMMAND_VCOM 0xD1
#define LCD_COMMAND_NORMAL_PWR_WR 0xD2
#define LCD_COMMAND_PANEL_DRV_CTL 0xC0
#define LCD_COMMAND_FR_SET 0xC5
#define LCD_COMMAND_GAMMAWR 0xC8
#define LCD_COMMAND_PIXEL_FORMAT 0x3A
#define LCD_COMMAND_DISPLAY_ON 0x29
#define LCD_COMMAND_EXIT_SLEEP_MODE 0x11
#define LCD_COMMAND_POWER_SETTING 0xD0
#define LCD_COMMAND_COLOR_INVERSION_OFF 0x20
#define LCD_COMMAND_COLOR_INVERSION_ON 0x21
#define LCD_COMMAND_TEARING_OFF 0x34
#define LCD_COMMAND_TEARING_ON 0x35
#define LCD_COMMAND_MADCTL 0x36
#define LCD_COMMAND_IDLE_OFF 0x38
#define LCD_COMMAND_TIMING_NORMAL 0xC1
#define LCD_PARAM_MADCTL_MY 0x80
#define LCD_PARAM_MADCTL_MX 0x40
#define LCD_PARAM_MADCTL_MV 0x20
#define LCD_PARAM_MADCTL_ML 0x10
#define LCD_PARAM_MADCTL_RGB 0x00
#define LCD_PARAM_MADCTL_BGR 0x08
#define LCD_PARAM_MADCTL_SS 0x02
#define LCD_PARAM_MADCTL_GS 0x01
#ifndef _swap_int16_t
#define _swap_int16_t(a, b) \
{ \
int16_t t = a; \
a = b; \
b = t; \
}
#endif
#endif
#endif

1334
Src/main.c

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,98 +0,0 @@
#include "profiler.h"
#include "functions.h"
//Public variables
static PROFILE_INFO profiles[PROFILES_COUNT] = {0}; // collection of profilers
// initialize the profiler
void InitProfiler()
{
for (uint8_t i = 0; i < PROFILES_COUNT; i++)
{
profiles[i].startTime = 0;
profiles[i].endTime = 0;
profiles[i].diff = 0;
profiles[i].samples = 0;
profiles[i].started = false;
}
}
// start profiler
void StartProfiler(uint8_t pid)
{
if (pid >= PROFILES_COUNT)
return;
if (profiles[pid].started)
return;
profiles[pid].started = true;
profiles[pid].startTime = HAL_GetTick();
}
// run profiler in microseconds
void StartProfilerUs()
{
if (profiles[PROFILES_COUNT - 1].started)
return;
profiles[PROFILES_COUNT - 1].started = true;
profiles[PROFILES_COUNT - 1].startTime = DWT->CYCCNT;
}
// terminate the profiler
void EndProfiler(uint8_t pid, bool summarize)
{
if (pid >= PROFILES_COUNT)
return;
if (!profiles[pid].started)
return;
profiles[pid].endTime = HAL_GetTick();
if (summarize)
profiles[pid].diff += profiles[pid].endTime - profiles[pid].startTime;
else
profiles[pid].diff = profiles[pid].endTime - profiles[pid].startTime;
profiles[pid].samples++;
profiles[pid].started = false;
}
// complete profiler in microseconds
void EndProfilerUs(bool summarize)
{
if (!profiles[PROFILES_COUNT - 1].started)
return;
profiles[PROFILES_COUNT - 1].endTime = DWT->CYCCNT;
uint32_t diff = (profiles[PROFILES_COUNT - 1].endTime - profiles[PROFILES_COUNT - 1].startTime);
if (summarize)
profiles[PROFILES_COUNT - 1].diff += diff;
else
profiles[PROFILES_COUNT - 1].diff = diff;
profiles[PROFILES_COUNT - 1].samples++;
profiles[PROFILES_COUNT - 1].started = false;
}
// output the profiler results
void PrintProfilerResult()
{
bool printed = false;
for (uint8_t i = 0; i < PROFILES_COUNT; i++)
if (profiles[i].samples > 0)
{
sendToDebug_str("Profile #");
sendToDebug_uint8(i, true);
sendToDebug_str(" Samples: ");
sendToDebug_uint32(profiles[i].samples, true);
if (i == PROFILES_COUNT - 1)
{
sendToDebug_str(" Time, us: ");
sendToDebug_uint32(profiles[i].diff / (SystemCoreClock / 1000000), false);
}
else
{
sendToDebug_str(" Time, ms: ");
sendToDebug_uint32(profiles[i].diff, false);
}
profiles[i].diff = 0;
profiles[i].samples = 0;
printed = true;
}
if (printed)
sendToDebug_str("\r\n");
}

Wyświetl plik

@ -1,25 +0,0 @@
#ifndef PROFILER_h
#define PROFILER_h
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#define PROFILES_COUNT 7 // number of profilers
typedef struct // profiler structure
{
uint32_t startTime;
uint32_t endTime;
uint32_t diff;
bool started;
uint32_t samples;
} PROFILE_INFO;
// Public methods
extern void InitProfiler(void); // initialize the profiler
extern void StartProfiler(uint8_t pid); // start profiler
extern void EndProfiler(uint8_t pid, bool summarize); // terminate the profiler
extern void PrintProfilerResult(void); // output the profiler results
extern void StartProfilerUs(void); // run profiler in microseconds
extern void EndProfilerUs(bool summarize); // complete profiler in microseconds
#endif

Wyświetl plik

@ -1,91 +0,0 @@
#include "stm32f4xx_hal.h"
#include "main.h"
#include "rf_unit.h"
#include "lcd.h"
#include "trx_manager.h"
#include "settings.h"
#include "system_menu.h"
#include "functions.h"
#include "audio_filters.h"
#define SENS_TABLE_COUNT 24
static const int16_t KTY81_120_sensTable[SENS_TABLE_COUNT][2] = { // table of sensor characteristics
{-55, 490},
{-50, 515},
{-40, 567},
{-30, 624},
{-20, 684},
{-10, 747},
{0, 815},
{10, 886},
{20, 961},
{25, 1000},
{30, 1040},
{40, 1122},
{50, 1209},
{60, 1299},
{70, 1392},
{80, 1490},
{90, 1591},
{100, 1696},
{110, 1805},
{120, 1915},
{125, 1970},
{130, 2023},
{140, 2124},
{150, 2211}};
void RF_UNIT_ProcessSensors(void)
{
//SWR
float32_t forward = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_2)) * 3.3f / 4096.0f;
float32_t backward = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_1)) * 3.3f / 4096.0f;
float32_t ptt_sw1 = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_3)) * 3.3f / 4096.0f;
float32_t ptt_sw2 = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc1, ADC_INJECTED_RANK_4)) * 3.3f / 4096.0f;
float32_t alc = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc2, ADC_INJECTED_RANK_2)) * 3.3f / 4096.0f;
float32_t power_in = (float32_t)(HAL_ADCEx_InjectedGetValue(&hadc2, ADC_INJECTED_RANK_1)) * 3.3f / 4096.0f;
power_in = power_in * 10.f; //do voltage calibration in future!!!
if(fabsf(TRX_InVoltage - power_in) > 0.2f)
TRX_InVoltage = power_in;
static float32_t TRX_VLT_forward = 0.0f;
static float32_t TRX_VLT_backward = 0.0f;
forward = forward / (1510.0f / (0.1f + 1510.0f)); // adjust the voltage based on the voltage divider (0.1 ohm and 510 ohm)
if (forward < 0.01f) // do not measure less than 10mV
{
TRX_VLT_forward = 0.0f;
TRX_VLT_backward = 0.0f;
TRX_SWR = 1.0f;
}
else
{
forward += 0.21f; // drop on diode
forward = forward * CALIBRATE.swr_trans_rate; // Transformation ratio of the SWR meter
backward = backward / (1510.0f / (0.1f + 1510.0f)); // adjust the voltage based on the voltage divider (0.1 ohm and 510 ohm)
if (backward >= 0.01f) // do not measure less than 10mV
{
backward += 0.21f; // drop on diode
backward = backward * CALIBRATE.swr_trans_rate; // Transformation ratio of the SWR meter
}
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_SWR = (TRX_VLT_forward + TRX_VLT_backward) / (TRX_VLT_forward - TRX_VLT_backward);
if (TRX_VLT_backward > TRX_VLT_forward)
TRX_SWR = 10.0f;
if (TRX_SWR > 10.0f)
TRX_SWR = 10.0f;
TRX_PWR_Forward = (TRX_VLT_forward * TRX_VLT_forward) / 50.0f;
if (TRX_PWR_Forward < 0.0f)
TRX_PWR_Forward = 0.0f;
TRX_PWR_Backward = (TRX_VLT_backward * TRX_VLT_backward) / 50.0f;
if (TRX_PWR_Backward < 0.0f)
TRX_PWR_Backward = 0.0f;
}
}

Wyświetl plik

@ -1,9 +0,0 @@
#ifndef RF_UNIT_h
#define RF_UNIT_h
#include "stm32f4xx_hal.h"
#include <stdbool.h>
extern void RF_UNIT_ProcessSensors(void);
#endif

Wyświetl plik

@ -1,153 +0,0 @@
#ifndef LCD_Layout_h
#define LCD_Layout_h
#include "lcd_driver.h"
#include "color_themes.h"
#include "fonts.h"
//Top row of status buttons
#define LAY_TOPBUTTONS_X1 0
#define LAY_TOPBUTTONS_X2 (LCD_WIDTH - 1)
#define LAY_TOPBUTTONS_Y1 1
#define LAY_TOPBUTTONS_Y2 50
#define LAY_TOPBUTTONS_WIDTH 62
#define LAY_TOPBUTTONS_HEIGHT 40
#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)
#define LAY_TOPBUTTONS_PRE_Y LAY_TOPBUTTONS_Y1
#define LAY_TOPBUTTONS_ATT_X (uint16_t)(LAY_TOPBUTTONS_PRE_X + LAY_TOPBUTTONS_WIDTH + LAY_TOPBUTTONS_LR_MARGIN)
#define LAY_TOPBUTTONS_ATT_Y LAY_TOPBUTTONS_Y1
#define LAY_TOPBUTTONS_AGC_X (uint16_t)(LAY_TOPBUTTONS_ATT_X + LAY_TOPBUTTONS_WIDTH + LAY_TOPBUTTONS_LR_MARGIN)
#define LAY_TOPBUTTONS_AGC_Y LAY_TOPBUTTONS_Y1
#define LAY_TOPBUTTONS_FAST_X (uint16_t)(LAY_TOPBUTTONS_AGC_X + LAY_TOPBUTTONS_WIDTH + LAY_TOPBUTTONS_LR_MARGIN)
#define LAY_TOPBUTTONS_FAST_Y LAY_TOPBUTTONS_Y1
#define LAY_TOPBUTTONS_MUTE_X (uint16_t)(LAY_TOPBUTTONS_FAST_X + LAY_TOPBUTTONS_WIDTH + LAY_TOPBUTTONS_LR_MARGIN)
#define LAY_TOPBUTTONS_MUTE_Y LAY_TOPBUTTONS_Y1
#define LAY_TOPBUTTONS_LOCK_X (uint16_t)(LAY_TOPBUTTONS_MUTE_X + LAY_TOPBUTTONS_WIDTH + LAY_TOPBUTTONS_LR_MARGIN)
#define LAY_TOPBUTTONS_LOCK_Y LAY_TOPBUTTONS_Y1
//Clock
#define LAY_CLOCK_POS_Y 17
#define LAY_CLOCK_POS_HRS_X (LCD_WIDTH - 75)
#define LAY_CLOCK_POS_MIN_X (uint16_t)(LAY_CLOCK_POS_HRS_X + 25)
#define LAY_CLOCK_POS_SEC_X (uint16_t)(LAY_CLOCK_POS_MIN_X + 25)
#define LAY_CLOCK_FONT &FreeSans9pt7b
//Frequency output
#define LAY_FREQ_X_OFFSET_100 37
#define LAY_FREQ_X_OFFSET_10 73
#define LAY_FREQ_X_OFFSET_1 113
#define LAY_FREQ_X_OFFSET_KHZ 170
#define LAY_FREQ_X_OFFSET_HZ 307
#define LAY_FREQ_HEIGHT 51
#define LAY_FREQ_WIDTH 370
#define LAY_FREQ_TOP_OFFSET 15
#define LAY_FREQ_LEFT_MARGIN 37
#define LAY_FREQ_RIGHT_MARGIN (uint16_t)(LCD_WIDTH - LAY_FREQ_LEFT_MARGIN - LAY_FREQ_WIDTH)
#define LAY_FREQ_BOTTOM_OFFSET 8
#define LAY_FREQ_BLOCK_HEIGHT (uint16_t)(LAY_FREQ_HEIGHT + LAY_FREQ_TOP_OFFSET + LAY_FREQ_BOTTOM_OFFSET)
#define LAY_FREQ_Y_TOP LAY_TOPBUTTONS_Y2
#define LAY_FREQ_Y_BASELINE (uint16_t)(LAY_TOPBUTTONS_Y2 + LAY_FREQ_HEIGHT + LAY_FREQ_TOP_OFFSET)
#define LAY_FREQ_Y_BASELINE_SMALL (uint16_t)(LAY_FREQ_Y_BASELINE - 2)
#define LAY_FREQ_FONT &FreeSans36pt7b
#define LAY_FREQ_SMALL_FONT &Quito32pt7b
#define LAY_FREQ_DELIMITER_Y_OFFSET 0
#define LAY_FREQ_DELIMITER_X1_OFFSET 151
#define LAY_FREQ_DELIMITER_X2_OFFSET 285
//Display statuses under frequency
#define LAY_STATUS_Y_OFFSET (uint16_t)(LAY_FREQ_Y_TOP + LAY_FREQ_BLOCK_HEIGHT + 1)
#define LAY_STATUS_HEIGHT 44
#define LAY_STATUS_BAR_X_OFFSET 60
#define LAY_STATUS_BAR_Y_OFFSET 16
#define LAY_STATUS_BAR_HEIGHT 10
#define LAY_STATUS_TXRX_X_OFFSET 3
#define LAY_STATUS_TXRX_Y_OFFSET -50
#define LAY_STATUS_TXRX_FONT &FreeSans9pt7b
#define LAY_STATUS_VFO_X_OFFSET 0
#define LAY_STATUS_VFO_Y_OFFSET -43
#define LAY_STATUS_VFO_BLOCK_WIDTH 37
#define LAY_STATUS_VFO_BLOCK_HEIGHT 22
#define LAY_STATUS_ANT_X_OFFSET 0
#define LAY_STATUS_ANT_Y_OFFSET -23
#define LAY_STATUS_ANT_BLOCK_WIDTH 37
#define LAY_STATUS_ANT_BLOCK_HEIGHT 22
#define LAY_STATUS_TX_LABELS_OFFSET_X 5
#define LAY_STATUS_TX_LABELS_MARGIN_X 55
#define LAY_STATUS_SMETER_WIDTH 400
#define LAY_STATUS_SMETER_MARKER_HEIGHT 30
#define LAY_STATUS_PMETER_WIDTH 300
#define LAY_STATUS_AMETER_WIDTH 90
#define LAY_STATUS_ALC_BAR_X_OFFSET 10
#define LAY_STATUS_LABELS_OFFSET_Y 0
#define LAY_STATUS_LABELS_FONT_SIZE 1
#define LAY_STATUS_LABEL_S_VAL_X_OFFSET 12
#define LAY_STATUS_LABEL_S_VAL_Y_OFFSET 25
#define LAY_STATUS_LABEL_S_VAL_FONT &FreeSans7pt7b
#define LAY_STATUS_LABEL_DBM_X_OFFSET 5
#define LAY_STATUS_LABEL_DBM_Y_OFFSET 36
#define LAY_STATUS_LABEL_BW_X_OFFSET 60
#define LAY_STATUS_LABEL_BW_Y_OFFSET 36
#define LAY_STATUS_LABEL_RIT_X_OFFSET 160
#define LAY_STATUS_LABEL_RIT_Y_OFFSET 36
#define LAY_STATUS_LABEL_VLT_X_OFFSET 250
#define LAY_STATUS_LABEL_VLT_Y_OFFSET 36
#define LAY_STATUS_LABEL_NOTCH_X_OFFSET 335
#define LAY_STATUS_LABEL_NOTCH_Y_OFFSET 36
#define LAY_STATUS_LABEL_FFT_BW_X_OFFSET 420
#define LAY_STATUS_LABEL_FFT_BW_Y_OFFSET 36
#define LAY_STATUS_SMETER_PEAK_HOLDTIME 1000
#define LAY_STATUS_SMETER_TXLABELS_MARGIN 55
#define LAY_STATUS_SMETER_TXLABELS_PADDING 23
#define LAY_STATUS_TX_LABELS_VAL_WIDTH 25
#define LAY_STATUS_TX_LABELS_VAL_HEIGHT 8
#define LAY_STATUS_TX_ALC_X_OFFSET 40
#define LAY_STATUS_MODE_X_OFFSET (uint16_t)(LCD_WIDTH - LAY_FREQ_RIGHT_MARGIN + 10)
#define LAY_STATUS_MODE_Y_OFFSET -42
#define LAY_STATUS_MODE_BLOCK_WIDTH 48
#define LAY_STATUS_MODE_BLOCK_HEIGHT 22
#define LAY_STATUS_ERR_OFFSET_X 435
#define LAY_STATUS_ERR_OFFSET_Y 65
#define LAY_STATUS_ERR_WIDTH 20
#define LAY_STATUS_ERR_HEIGHT 8
#define LAY_TEXTBAR_FONT 2
#define LAY_TEXTBAR_TEXT_T_BOTTOM_OFFESET 30
#define LAY_TEXTBAR_TEXT_X_OFFSET 85
//FFT and waterfall
#define LAY_FFT_HEIGHT 50
#define LAY_WTF_HEIGHT 55
#define LAY_FFT_PRINT_SIZE LCD_WIDTH
#define LAY_FFT_CWDECODER_OFFSET 17
#define LAY_FFT_FFTWTF_POS_Y (uint16_t)(LCD_HEIGHT - LAY_FFT_HEIGHT - LAY_WTF_HEIGHT - LAY_TEXTBAR_TEXT_T_BOTTOM_OFFESET)
#define LAY_FFT_FFTWTF_HEIGHT (uint16_t)(LAY_FFT_FFTWTF_POS_Y + LAY_FFT_HEIGHT + LAY_WTF_HEIGHT)
//System menu
#define LAY_SYSMENU_X1 5
#define LAY_SYSMENU_X2 400
#define LAY_SYSMENU_X2_BIGINT 350
#define LAY_SYSMENU_X2R_BIGINT 400
#define LAY_SYSMENU_W 458
#define LAY_SYSMENU_ITEM_HEIGHT 18
#define LAY_SYSMENU_MAX_ITEMS_ON_PAGE (uint16_t)(LCD_HEIGHT / LAY_SYSMENU_ITEM_HEIGHT)
//Stuff
#define LAY_GREETINGS_X (LCD_WIDTH / 2 - 5)
#define LAY_GREETINGS_Y 25
//Tooltip
#define LAY_TOOLTIP_TIMEOUT 1000
#define LAY_TOOLTIP_MARGIN 5
#define LAY_TOOLTIP_POS_X (LCD_WIDTH / 2)
#define LAY_TOOLTIP_POS_Y 70
//bottom buttons
#define LAY_BOTTOMBUTTONS_X 0
#define LAY_BOTTOMBUTTONS_Y (LAY_FFT_FFTWTF_HEIGHT + 1)
#define LAY_BOTTOMBUTTONS_MARGIN 1
#define LAY_BOTTOMBUTTONS_WIDTH (LCD_WIDTH / 4 - LAY_BOTTOMBUTTONS_MARGIN * 2)
#define LAY_BOTTOMBUTTONS_HEIGHT LAY_TEXTBAR_TEXT_T_BOTTOM_OFFESET
#define LAY_BOTTOMBUTTONS_X1 LAY_BOTTOMBUTTONS_X
#define LAY_BOTTOMBUTTONS_X2 (LAY_BOTTOMBUTTONS_X1 + LAY_BOTTOMBUTTONS_WIDTH + LAY_BOTTOMBUTTONS_MARGIN * 2)
#define LAY_BOTTOMBUTTONS_X3 (LAY_BOTTOMBUTTONS_X2 + LAY_BOTTOMBUTTONS_WIDTH + LAY_BOTTOMBUTTONS_MARGIN * 2)
#define LAY_BOTTOMBUTTONS_X4 (LAY_BOTTOMBUTTONS_X3 + LAY_BOTTOMBUTTONS_WIDTH + LAY_BOTTOMBUTTONS_MARGIN * 2)
//BW Trapezoid
#define LAY_BW_TRAPEZ_POS_X 385
#define LAY_BW_TRAPEZ_POS_Y 25
#define LAY_BW_TRAPEZ_HEIGHT 25
#define LAY_BW_TRAPEZ_WIDTH 90
#endif

Wyświetl plik

@ -1,593 +0,0 @@
#include "settings.h"
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <stdlib.h>
#include "functions.h"
#include "trx_manager.h"
#include "lcd.h"
#include "fpga.h"
#include "main.h"
#include "bands.h"
#include "front_unit.h"
char version_string[19] = "1.0.0"; //1.2.3-yymmdd.hhmm (concatinate)
//W25Q16
static uint8_t Write_Enable = W25Q16_COMMAND_Write_Enable;
static uint8_t Sector_Erase = W25Q16_COMMAND_Sector_Erase;
static uint8_t Page_Program = W25Q16_COMMAND_Page_Program;
static uint8_t Read_Data = W25Q16_COMMAND_Read_Data;
static uint8_t Power_Down = W25Q16_COMMAND_Power_Down;
static uint8_t Get_Status = W25Q16_COMMAND_GetStatus;
static uint8_t Write_Status = W25Q16_COMMAND_WriteStatus;
static uint8_t Write_Status_REG = 0;
static uint8_t Power_Up = W25Q16_COMMAND_Power_Up;
static uint8_t Address[3] = {0x00};
struct TRX_SETTINGS TRX;
struct TRX_CALIBRATE CALIBRATE = {0};
static uint8_t settings_bank = 1;
static uint8_t write_clone[sizeof(TRX)] = {0};
static uint8_t read_clone[sizeof(TRX)] = {0};
static uint8_t verify_clone[sizeof(TRX)] = {0};
volatile bool NeedSaveSettings = false;
volatile bool NeedSaveCalibration = false;
volatile bool EEPROM_Busy = false;
static bool EEPROM_Enabled = true;
static void LoadSettingsFromEEPROM(void);
static bool EEPROM_Sector_Erase(uint8_t sector, bool force);
static bool EEPROM_Write_Data(uint8_t *Buffer, uint16_t size, uint8_t sector, bool verify, bool force);
static bool EEPROM_Read_Data(uint8_t *Buffer, uint16_t size, uint8_t sector, bool verif, bool force);
static void EEPROM_PowerDown(void);
static void EEPROM_PowerUp(void);
static void EEPROM_WaitWrite(void);
static uint8_t calculateCSUM(void);
static uint8_t calculateCSUM_EEPROM(void);
const char *MODE_DESCR[TRX_MODE_COUNT] = {
"LSB",
"USB",
"CW-L",
"CW-U",
"NFM",
"WFM",
"AM",
"DIGL",
"DIGU",
"IQ",
"LOOP",
"NOTX",
};
void InitSettings(void)
{
static bool already_inited = false;
if(already_inited) return;
already_inited = true;
//concat build date to version -yymmdd.hhmm
uint8_t cur_len = (uint8_t)strlen(version_string);
strcat(version_string, "-");
version_string[++cur_len] = BUILD_YEAR_CH2;
version_string[++cur_len] = BUILD_YEAR_CH3;
version_string[++cur_len] = BUILD_MONTH_CH0;
version_string[++cur_len] = BUILD_MONTH_CH1;
version_string[++cur_len] = BUILD_DAY_CH0;
version_string[++cur_len] = BUILD_DAY_CH1;
version_string[++cur_len] = '.';
version_string[++cur_len] = BUILD_HOUR_CH0;
version_string[++cur_len] = BUILD_HOUR_CH1;
version_string[++cur_len] = BUILD_MIN_CH0;
version_string[++cur_len] = BUILD_MIN_CH1;
version_string[++cur_len] = '\0';
sendToDebug_strln(version_string);
}
void LoadSettings(bool clear)
{
BKPSRAM_Enable();
memcpy(&TRX, (uint32_t*) BACKUP_SRAM_BANK1_ADDR, sizeof(TRX));
// Check, the data in the backup sram is correct, otherwise we use the second bank
if (TRX.ENDBit != 100 || TRX.flash_id != SETT_VERSION || TRX.csum != calculateCSUM())
{
memcpy(&TRX, BACKUP_SRAM_BANK2_ADDR, sizeof(TRX));
if (TRX.ENDBit != 100 || TRX.flash_id != SETT_VERSION || TRX.csum != calculateCSUM())
{
sendToDebug_strln("[ERR] BACKUP SRAM data incorrect");
LoadSettingsFromEEPROM();
if (TRX.ENDBit != 100 || TRX.flash_id != SETT_VERSION || TRX.csum != calculateCSUM())
{
sendToDebug_strln("[ERR] EEPROM Settings data incorrect");
}
else
{
SaveSettings();
sendToDebug_strln("[OK] Settings data succesfully loaded from EEPROM");
}
}
else
{
sendToDebug_strln("[OK] Settings data succesfully loaded from BACKUP SRAM bank 2");
}
}
else
{
sendToDebug_strln("[OK] Settings data succesfully loaded from BACKUP SRAM bank 1");
}
BKPSRAM_Disable();
if (TRX.flash_id != SETT_VERSION || clear || TRX.ENDBit != 100) // code to trace new clean flash
{
if(clear)
sendToDebug_strln("[OK] Soft reset TRX");
memset(&TRX, 0x00, sizeof(TRX));
TRX.flash_id = SETT_VERSION; // Firmware ID in SRAM, if it doesn't match, use the default
TRX.VFO_A.Freq = 7100000; // stored VFO-A frequency
TRX.VFO_A.Mode = TRX_MODE_LSB; // saved VFO-A mode
TRX.VFO_A.LPF_Filter_Width = 2700; // saved bandwidth for VFO-A
TRX.VFO_A.HPF_Filter_Width = 300; // saved bandwidth for VFO-A
TRX.VFO_A.AutoNotchFilter = false; // notch filter to cut out noise
TRX.VFO_A.NotchFC = 1000; // cutoff frequency of the notch filter
TRX.VFO_A.AGC = true; // AGC
TRX.VFO_B.Freq = 14150000; // stored VFO-B frequency
TRX.VFO_B.Mode = TRX_MODE_USB; // saved VFO-B mode
TRX.VFO_B.LPF_Filter_Width = 2700; // saved bandwidth for VFO-B
TRX.VFO_B.HPF_Filter_Width = 300; // saved bandwidth for VFO-B
TRX.VFO_B.AutoNotchFilter = false; // notch filter to cut out noise
TRX.VFO_B.NotchFC = 1000; // cutoff frequency of the notch filter
TRX.VFO_B.AGC = true; // AGC
TRX.current_vfo = false; // current VFO (false - A)
TRX.ADC_Driver = true; // preamplifier (ADC driver)
TRX.ATT = false; // attenuator
TRX.ATT_DB = 12.0f; // suppress the attenuator
TRX.ATT_STEP = 6.0f; // step of tuning the attenuator
TRX.FM_SQL_threshold = 4; // FM noise reduction
TRX.Fast = true; // accelerated frequency change when the encoder rotates
for (uint8_t i = 0; i < BANDS_COUNT; i++)
{
TRX.BANDS_SAVED_SETTINGS[i].Freq = BANDS[i].startFreq + (BANDS[i].endFreq - BANDS[i].startFreq) / 2; // saved frequencies by bands
TRX.BANDS_SAVED_SETTINGS[i].Mode = (uint8_t)getModeFromFreq(TRX.BANDS_SAVED_SETTINGS[i].Freq);
TRX.BANDS_SAVED_SETTINGS[i].ATT = TRX.ATT;
TRX.BANDS_SAVED_SETTINGS[i].ATT_DB = TRX.ATT_DB;
TRX.BANDS_SAVED_SETTINGS[i].ADC_Driver = TRX.ADC_Driver;
TRX.BANDS_SAVED_SETTINGS[i].FM_SQL_threshold = TRX.FM_SQL_threshold;
TRX.BANDS_SAVED_SETTINGS[i].AGC = true;
TRX.BANDS_SAVED_SETTINGS[i].AutoGain_Stage = 6;
}
TRX.FFT_Zoom = 1; // approximation of the FFT spectrum
TRX.AutoGain = false; // auto-control preamp and attenuator
TRX.InputType_MIC = true; // type of input to transfer
TRX.InputType_LINE = false;
TRX.InputType_USB = false;
TRX.CW_LPF_Filter = 700; // default value of CW filter width
TRX.CW_HPF_Filter = 0; // default value of CW filter width
TRX.SSB_LPF_Filter = 2700; // default value of SSB filter width
TRX.SSB_HPF_Filter = 300; // default value of SSB filter width
TRX.AM_LPF_Filter = 4000; // default value of AM filter width
TRX.FM_LPF_Filter = 15000; // default value of the FM filter width
TRX.RF_Power = 20; //output power (%)
TRX.RX_AGC_SSB_speed = 10; // AGC receive rate on SSB
TRX.RX_AGC_CW_speed = 1; // AGC receive rate on CW
TRX.TX_AGC_speed = 3; // AGC transfer rate
TRX.BandMapEnabled = true; // automatic change of mode according to the range map
TRX.FFT_Enabled = true; // use FFT spectrum
TRX.CW_GENERATOR_SHIFT_HZ = 500; // LO offset in CW mode
TRX.CW_Key_timeout = 500; // time of releasing transmission after the last character on the key
TRX.FFT_Averaging = 4; // averaging the FFT to make it smoother
TRX.CW_SelfHear = true; // self-control CW
TRX.ADC_SHDN = false; // ADC disable
TRX.FFT_Window = 1;
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.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.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
TRX.DNR_AVERAGE = 2; // DNR averaging when looking for average magnitude
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.MIC_GAIN = 3; // Microphone gain
TRX.RX_EQ_LOW = 0; // Receiver Equalizer (Low)
TRX.RX_EQ_MID = 0; // Receiver EQ (mids)
TRX.RX_EQ_HIG = 0; // Receiver EQ (high)
TRX.MIC_EQ_LOW = 0; // Mic EQ (Low)
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_Compressor = true; //Compress FFT Peaks
TRX.Encoder_Accelerate = true; //Accelerate Encoder on fast rate
strcpy(TRX.CALLSIGN, "HamRad"); // Callsign
TRX.ColorThemeId = 0; //Selected Color theme
TRX.Transverter_Enabled = false; //Enable transverter mode
TRX.Transverter_Offset_Mhz = 120; //Offset from VFO
TRX.Volume = 50; //AF Volume
TRX.CW_GaussFilter = true; //Gauss responce LPF filter
TRX.ENDBit = 100; // Bit for the end of a successful write to eeprom
sendToDebug_strln("[OK] Loaded default settings");
SaveSettings();
SaveSettingsToEEPROM();
}
}
static void LoadSettingsFromEEPROM(void)
{
EEPROM_PowerUp();
uint8_t tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Read_Data((uint8_t *)&TRX, sizeof(TRX), EEPROM_SECTOR_SETTINGS, true, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
sendToDebug_strln("[ERR] Read EEPROM SETTINGS multiple errors");
EEPROM_PowerDown();
}
void LoadCalibration(bool clear)
{
EEPROM_PowerUp();
uint8_t tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Read_Data((uint8_t *)&CALIBRATE, sizeof(CALIBRATE), EEPROM_SECTOR_CALIBRATION, true, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
sendToDebug_strln("[ERR] Read EEPROM CALIBRATE multiple errors");
if (CALIBRATE.ENDBit != 100 || CALIBRATE.flash_id != CALIB_VERSION || clear || CALIBRATE.csum != calculateCSUM_EEPROM()) // code for checking the firmware in the eeprom, if it does not match, we use the default
{
sendToDebug_str("[ERR] CALIBRATE Flash check");
sendToDebug_uint8(CALIBRATE.ENDBit, false);
sendToDebug_uint8(CALIBRATE.flash_id, false);
sendToDebug_uint8(CALIB_VERSION, false);
sendToDebug_uint8(clear, false);
sendToDebug_uint8(CALIBRATE.csum, false);
sendToDebug_uint8(calculateCSUM_EEPROM(), false);
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.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
CALIBRATE.ENCODER_ON_FALLING = false; // encoder only triggers when level A falls
CALIBRATE.CIC_GAINER_val = 78; // Offset from the output of the CIC compensator
CALIBRATE.CICFIR_GAINER_val = 26; // Offset from the output of the CIC compensator
CALIBRATE.TXCICFIR_GAINER_val = 27; // Offset from the TX-CIC output of the compensator
CALIBRATE.DAC_GAINER_val = 26; // DAC offset offset
// Calibrate the maximum output power for each band
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 = -13; // S-Meter calibration, set when calibrating the transceiver to S9
CALIBRATE.swr_trans_rate = 11.0f; //SWR Transormator rate
CALIBRATE.ENDBit = 100;
sendToDebug_strln("[OK] Loaded default calibrate settings");
SaveCalibration();
}
EEPROM_PowerDown();
}
inline VFO *CurrentVFO(void)
{
if (!TRX.current_vfo)
return &TRX.VFO_A;
else
return &TRX.VFO_B;
}
inline VFO *SecondaryVFO(void)
{
if (!TRX.current_vfo)
return &TRX.VFO_B;
else
return &TRX.VFO_A;
}
void SaveSettings(void)
{
BKPSRAM_Enable();
TRX.csum = calculateCSUM();
if(settings_bank == 1)
{
memcpy(BACKUP_SRAM_BANK1_ADDR, &TRX, sizeof(TRX));
memset(BACKUP_SRAM_BANK2_ADDR, 0x00, sizeof(TRX));
}
else
{
memcpy(BACKUP_SRAM_BANK2_ADDR, &TRX, sizeof(TRX));
memset(BACKUP_SRAM_BANK1_ADDR, 0x00, sizeof(TRX));
}
BKPSRAM_Disable();
NeedSaveSettings = false;
//sendToDebug_str("[OK] Settings Saved to bank ");
//sendToDebug_uint8(settings_bank, false);
//sendToDebug_uint32(sizeof(TRX), false);
if(settings_bank == 1)
settings_bank = 2;
else
settings_bank = 1;
}
void SaveSettingsToEEPROM(void)
{
if (EEPROM_Busy)
return;
EEPROM_PowerUp();
EEPROM_Busy = true;
TRX.csum = calculateCSUM();
uint8_t tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Sector_Erase(EEPROM_SECTOR_SETTINGS, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
{
sendToDebug_strln("[ERR] Erase EEPROM Settings multiple errors");
sendToDebug_flush();
EEPROM_Busy = false;
return;
}
tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Write_Data((uint8_t *)&TRX, sizeof(TRX), EEPROM_SECTOR_SETTINGS, true, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
{
sendToDebug_strln("[ERR] Write EEPROM Settings multiple errors");
sendToDebug_flush();
EEPROM_Busy = false;
return;
}
EEPROM_Busy = false;
EEPROM_PowerDown();
sendToDebug_strln("[OK] EEPROM Settings Saved");
sendToDebug_flush();
}
void SaveCalibration(void)
{
if (EEPROM_Busy)
return;
EEPROM_PowerUp();
EEPROM_Busy = true;
CALIBRATE.csum = calculateCSUM_EEPROM();
uint8_t tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Sector_Erase(EEPROM_SECTOR_CALIBRATION, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
{
sendToDebug_strln("[ERR] Erase EEPROM calibrate multiple errors");
EEPROM_Busy = false;
return;
}
tryes = 0;
while (tryes < EEPROM_REPEAT_TRYES && !EEPROM_Write_Data((uint8_t *)&CALIBRATE, sizeof(CALIBRATE), EEPROM_SECTOR_CALIBRATION, true, false))
{
tryes++;
}
if (tryes >= EEPROM_REPEAT_TRYES)
{
sendToDebug_strln("[ERR] Write EEPROM calibrate multiple errors");
EEPROM_Busy = false;
return;
}
EEPROM_Busy = false;
EEPROM_PowerDown();
sendToDebug_strln("[OK] EEPROM Calibrations Saved");
NeedSaveCalibration = false;
}
static bool EEPROM_Sector_Erase(uint8_t sector, bool force)
{
if (!force && !EEPROM_Enabled)
return true;
if (!force && SPI_process)
return false;
else
SPI_process = true;
uint32_t BigAddress = sector * W25Q16_SECTOR_SIZE;
Address[2] = (BigAddress >> 16) & 0xFF;
Address[1] = (BigAddress >> 8) & 0xFF;
Address[0] = BigAddress & 0xFF;
//disable write protect
//SPI_Transmit(&Write_Status, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // WRITE STATUS REGISTER Command
//SPI_Transmit(&Write_Status_REG, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // WRITE STATUS REGISTER argument
//EEPROM_WaitWrite();
SPI_Transmit(&Write_Enable, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Write Enable Command
SPI_Transmit(&Sector_Erase, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Erase Command
SPI_Transmit(Address, NULL, 3, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Write Address ( The first address of flash module is 0x00000000 )
EEPROM_WaitWrite();
SPI_process = false;
return true;
}
static bool EEPROM_Write_Data(uint8_t *Buffer, uint16_t size, uint8_t sector, bool verify, bool force)
{
if (!force && !EEPROM_Enabled)
return true;
if (!force && SPI_process)
return false;
else
SPI_process = true;
if(size > sizeof(write_clone))
{
sendToDebug_strln("EEPROM buffer error");
return false;
}
memcpy(write_clone, Buffer, size);
const uint16_t page_size = 256;
for (uint16_t page = 0; page <= (size / page_size); page++)
{
uint32_t BigAddress = page * page_size + (sector * W25Q16_SECTOR_SIZE);
Address[2] = (BigAddress >> 16) & 0xFF;
Address[1] = (BigAddress >> 8) & 0xFF;
Address[0] = BigAddress & 0xFF;
uint16_t bsize = size - page_size * page;
if (bsize > page_size)
bsize = page_size;
SPI_Transmit(&Write_Enable, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Write Enable Command
SPI_Transmit(&Page_Program, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Write Command
SPI_Transmit(Address, NULL, 3, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Write Address ( The first address of flash module is 0x00000000 )
SPI_Transmit((uint8_t *)(write_clone + page_size * page), NULL, bsize, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Write Data
EEPROM_WaitWrite();
}
//verify
if (verify)
{
EEPROM_Read_Data(verify_clone, size, sector, false, true);
for (uint16_t i = 0; i < size; i++)
if (verify_clone[i] != write_clone[i])
{
EEPROM_Sector_Erase(sector, true);
SPI_process = false;
return false;
}
}
SPI_process = false;
return true;
}
static bool EEPROM_Read_Data(uint8_t *Buffer, uint16_t size, uint8_t sector, bool verify, bool force)
{
if (!force && !EEPROM_Enabled)
return true;
if (!force && SPI_process)
return false;
else
SPI_process = true;
uint32_t BigAddress = sector * W25Q16_SECTOR_SIZE;
Address[2] = (BigAddress >> 16) & 0xFF;
Address[1] = (BigAddress >> 8) & 0xFF;
Address[0] = BigAddress & 0xFF;
bool res = SPI_Transmit(&Read_Data, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Read Command
if (!res)
{
EEPROM_Enabled = false;
sendToDebug_strln("[ERR] EEPROM not found...");
LCD_showError("EEPROM init error", true);
SPI_process = false;
return true;
}
SPI_Transmit(Address, NULL, 3, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Write Address
SPI_Transmit(NULL, (uint8_t *)(Buffer), size, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Read
//verify
if (verify)
{
EEPROM_Read_Data(read_clone, size, sector, false, true);
for (uint16_t i = 0; i < size; i++)
if (read_clone[i] != Buffer[i])
{
sendToDebug_uint8(read_clone[i],false);
SPI_process = false;
return false;
}
}
SPI_process = false;
return true;
}
static void EEPROM_WaitWrite(void)
{
if (!EEPROM_Enabled)
return;
uint8_t status = 0;
uint8_t tryes = 0;
do
{
tryes++;
SPI_Transmit(&Get_Status, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, true, SPI_EEPROM_PRESCALER); // Get Status command
SPI_Transmit(NULL, &status, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Read data
if((status & 0x01) == 0x01)
HAL_Delay(1);
}
while((status & 0x01) == 0x01 && (tryes < 200));
if(tryes == 200)
sendToDebug_strln("[ERR]EEPROM Lock wait error");
}
static void EEPROM_PowerDown(void)
{
if (!EEPROM_Enabled)
return;
SPI_Transmit(&Power_Down, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Power_Down Command
}
static void EEPROM_PowerUp(void)
{
if (!EEPROM_Enabled)
return;
SPI_Transmit(&Power_Up, NULL, 1, W25Q16_CS_GPIO_Port, W25Q16_CS_Pin, false, SPI_EEPROM_PRESCALER); // Power_Up Command
EEPROM_WaitWrite();
}
void BKPSRAM_Enable(void)
{
RCC->APB1ENR |= RCC_APB1ENR_PWREN;
RCC->AHB1ENR |= RCC_AHB1ENR_BKPSRAMEN;
HAL_PWREx_EnableBkUpReg();
HAL_PWR_EnableBkUpAccess();
*(__IO uint32_t *) CSR_BRE_BB = (uint32_t) ENABLE;
while (!(PWR->CSR & (PWR_FLAG_BRR)));
}
void BKPSRAM_Disable(void)
{
HAL_PWR_DisableBkUpAccess();
}
static uint8_t calculateCSUM(void)
{
uint8_t csum_old = TRX.csum;
uint8_t csum_new = 0;
TRX.csum = 0;
uint8_t* TRX_addr = (uint8_t*)&TRX;
for(uint16_t i = 0; i < sizeof(TRX); i++)
csum_new += *(TRX_addr + i);
TRX.csum = csum_old;
return csum_new;
}
static uint8_t calculateCSUM_EEPROM(void)
{
uint8_t csum_old = CALIBRATE.csum;
uint8_t csum_new =
CALIBRATE.csum = 0;
uint8_t* CALIBRATE_addr = (uint8_t*)&CALIBRATE;
for(uint16_t i = 0; i < sizeof(CALIBRATE); i++)
csum_new += *(CALIBRATE_addr + i);
CALIBRATE.csum = csum_old;
return csum_new;
}

Wyświetl plik

@ -1,228 +0,0 @@
#ifndef SETTINGS_h
#define SETTINGS_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include <stdbool.h>
#include "functions.h"
#include "bands.h"
#define SETT_VERSION 100 // 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 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_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 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 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
#define ENCODER_ACCELERATION 50 //acceleration rate if rotate
#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!)
// select LCD and Touchpad, comment on others
//#define LCD_ILI9481 true
//#define LCD_HX8357B true
//#define LCD_HX8357C true
//#define LCD_R61581 true //untested
#define LCD_ILI9486 true
//SPI Speed
#define SPI_FRONT_UNIT_PRESCALER SPI_BAUDRATEPRESCALER_8
#define SPI_EEPROM_PRESCALER SPI_BAUDRATEPRESCALER_8
#define ADC_BITS 12 // ADC bit depth
#define FPGA_BUS_BITS 16 // bitness of data from FPGA
#define CODEC_BITS 16 // bitness of data in the audio codec
//#define FPGA_BUS_FULL_SCALE 65536 // maximum signal amplitude in the bus // powf (2, FPGA_BUS_BITS)
//#define FPGA_BUS_FULL_SCALE_POW ((float64_t)FPGA_BUS_FULL_SCALE * (float64_t)FPGA_BUS_FULL_SCALE) // maximum bus signal magnitude // (FPGA_BUS_FULL_SCALE * FPGA_BUS_FULL_SCALE)
#define CODEC_BITS_FULL_SCALE 65536 // maximum signal amplitude in the bus // powf (2, FPGA_BUS_BITS)
//#define CODEC_BITS_FULL_SCALE_POW ((float64_t)CODEC_BITS_FULL_SCALE * (float64_t)CODEC_BITS_FULL_SCALE) // maximum bus signal magnitude // (FPGA_BUS_FULL_SCALE * FPGA_BUS )_FULL_SCALE
//#define ADC_FULL_SCALE 65536 // maximum signal amplitude in the ADC // powf (2, ADC_BITS)
#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
#define LCD_DEBUG_ENABLED false // enable LCD as a console
#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 MAX_CALLSIGN_LENGTH 16
#define W25Q16_COMMAND_Write_Disable 0x04
#define W25Q16_COMMAND_Write_Enable 0x06
#define W25Q16_COMMAND_Erase_Chip 0xC7
#define W25Q16_COMMAND_Sector_Erase 0x20
#define W25Q16_COMMAND_32KBlock_Erase 0x52
#define W25Q16_COMMAND_Page_Program 0x02
#define W25Q16_COMMAND_Read_Data 0x03
#define W25Q16_COMMAND_FastRead_Data 0x0B
#define W25Q16_COMMAND_Power_Down 0xB9
#define W25Q16_COMMAND_Power_Up 0xAB
#define W25Q16_COMMAND_GetStatus 0x05
#define W25Q16_COMMAND_WriteStatus 0x01
#define W25Q16_SECTOR_SIZE 4096
#define EEPROM_SECTOR_CALIBRATION 0
#define EEPROM_SECTOR_SETTINGS 4
#define EEPROM_REPEAT_TRYES 5 // command tryes
typedef struct
{
uint32_t Freq;
uint_fast8_t Mode;
uint_fast16_t HPF_Filter_Width;
uint_fast16_t LPF_Filter_Width;
bool AutoNotchFilter;
uint_fast16_t NotchFC;
bool AGC;
} VFO;
// Save settings by band
typedef struct
{
uint32_t Freq;
uint8_t Mode;
float32_t ATT_DB;
bool ATT;
bool ADC_Driver;
uint8_t FM_SQL_threshold;
bool AGC;
uint8_t AutoGain_Stage;
} BAND_SAVED_SETTINGS_TYPE;
extern struct TRX_SETTINGS
{
uint8_t flash_id;
//TRX
bool current_vfo; // false - A; true - B
VFO VFO_A;
VFO VFO_B;
bool Fast;
BAND_SAVED_SETTINGS_TYPE BANDS_SAVED_SETTINGS[BANDS_COUNT];
float32_t ATT_DB;
uint8_t ATT_STEP;
bool ATT;
uint8_t RF_Power;
bool ShiftEnabled;
uint16_t SHIFT_INTERVAL;
bool TWO_SIGNAL_TUNE;
uint16_t FRQ_STEP;
uint16_t FRQ_FAST_STEP;
bool Debug_Console;
bool BandMapEnabled;
bool InputType_MIC;
bool InputType_LINE;
bool InputType_USB;
bool AutoGain;
bool Locked;
bool CLAR;
bool Encoder_Accelerate;
char CALLSIGN[MAX_CALLSIGN_LENGTH];
bool Transverter_Enabled;
uint16_t Transverter_Offset_Mhz;
//AUDIO
uint8_t Volume;
uint8_t IF_Gain;
int8_t AGC_GAIN_TARGET;
uint8_t MIC_GAIN;
int8_t RX_EQ_LOW;
int8_t RX_EQ_MID;
int8_t RX_EQ_HIG;
int8_t MIC_EQ_LOW;
int8_t MIC_EQ_MID;
int8_t MIC_EQ_HIG;
uint8_t DNR_SNR_THRESHOLD;
uint8_t DNR_AVERAGE;
uint8_t DNR_MINIMAL;
uint8_t RX_AGC_SSB_speed;
uint8_t RX_AGC_CW_speed;
uint8_t TX_AGC_speed;
uint16_t CW_LPF_Filter;
uint16_t CW_HPF_Filter;
uint16_t SSB_LPF_Filter;
uint16_t SSB_HPF_Filter;
uint16_t AM_LPF_Filter;
uint16_t FM_LPF_Filter;
uint8_t FM_SQL_threshold;
bool Beeper;
//CW
uint16_t CW_GENERATOR_SHIFT_HZ;
uint16_t CW_Key_timeout;
uint16_t CW_SelfHear;
bool CW_KEYER;
uint16_t CW_KEYER_WPM;
bool CW_GaussFilter;
//SCREEN
uint8_t ColorThemeId;
bool FFT_Enabled;
uint8_t FFT_Zoom;
uint8_t FFT_Averaging;
uint8_t FFT_Window;
uint8_t FFT_Color;
bool FFT_Compressor;
int8_t FFT_Grid;
bool FFT_Background;
//ADC
bool ADC_Driver;
bool ADC_SHDN;
//
uint8_t csum; //check sum
uint8_t ENDBit; //end bit
} TRX;
extern struct TRX_CALIBRATE
{
uint8_t flash_id; //eeprom check
bool ENCODER_INVERT;
bool ENCODER2_INVERT;
uint8_t ENCODER_DEBOUNCE;
uint8_t ENCODER2_DEBOUNCE;
uint8_t ENCODER_SLOW_RATE;
bool ENCODER_ON_FALLING;
uint8_t CIC_GAINER_val;
uint8_t CICFIR_GAINER_val;
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;
uint8_t rf_out_power_vhf;
int16_t smeter_calibration;
float32_t swr_trans_rate;
uint8_t csum; //check sum
uint8_t ENDBit; //end bit
} CALIBRATE;
extern char version_string[19]; //1.2.3-yymmdd.hhmmss
extern volatile bool NeedSaveSettings;
extern volatile bool NeedSaveCalibration;
extern volatile bool EEPROM_Busy;
extern volatile bool LCD_inited;
extern void InitSettings(void);
extern void LoadSettings(bool clear);
extern void LoadCalibration(bool clear);
extern void SaveSettings(void);
extern void SaveCalibration(void);
extern void SaveSettingsToEEPROM(void);
extern void BKPSRAM_Enable(void);
extern void BKPSRAM_Disable(void);
extern VFO *CurrentVFO(void);
extern VFO *SecondaryVFO(void);
#endif

Wyświetl plik

@ -1,844 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* File Name : stm32f4xx_hal_msp.c
* Description : This file provides code for the MSP Initialization
* and de-Initialization codes.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
extern DMA_HandleTypeDef hdma_spi3_tx;
extern DMA_HandleTypeDef hdma_i2s3_ext_rx;
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN Define */
/* USER CODE END Define */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN Macro */
/* USER CODE END Macro */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* External functions --------------------------------------------------------*/
/* USER CODE BEGIN ExternalFunctions */
/* USER CODE END ExternalFunctions */
/* USER CODE BEGIN 0 */
/* USER CODE END 0 */
/**
* Initializes the Global MSP.
*/
void HAL_MspInit(void)
{
/* USER CODE BEGIN MspInit 0 */
/* USER CODE END MspInit 0 */
__HAL_RCC_SYSCFG_CLK_ENABLE();
__HAL_RCC_PWR_CLK_ENABLE();
/* System interrupt init*/
/* USER CODE BEGIN MspInit 1 */
/* USER CODE END MspInit 1 */
}
/**
* @brief ADC MSP Initialization
* This function configures the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspInit(ADC_HandleTypeDef* hadc)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspInit 0 */
/* USER CODE END ADC1_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ADC1_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**ADC1 GPIO Configuration
PC0 ------> ADC1_IN10
PC1 ------> ADC1_IN11
PB0 ------> ADC1_IN8
PB1 ------> ADC1_IN9
*/
GPIO_InitStruct.Pin = SWR_FORW_Pin|SWR_BACKW_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = PTT_SW1_Pin|PTT_SW2_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN ADC1_MspInit 1 */
/* USER CODE END ADC1_MspInit 1 */
}
else if(hadc->Instance==ADC2)
{
/* USER CODE BEGIN ADC2_MspInit 0 */
/* USER CODE END ADC2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_ADC2_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**ADC2 GPIO Configuration
PC4 ------> ADC2_IN14
PC5 ------> ADC2_IN15
*/
GPIO_InitStruct.Pin = Power_IN_Pin|ALC_IN_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_ANALOG;
GPIO_InitStruct.Pull = GPIO_NOPULL;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
/* USER CODE BEGIN ADC2_MspInit 1 */
/* USER CODE END ADC2_MspInit 1 */
}
}
/**
* @brief ADC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hadc: ADC handle pointer
* @retval None
*/
void HAL_ADC_MspDeInit(ADC_HandleTypeDef* hadc)
{
if(hadc->Instance==ADC1)
{
/* USER CODE BEGIN ADC1_MspDeInit 0 */
/* USER CODE END ADC1_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC1_CLK_DISABLE();
/**ADC1 GPIO Configuration
PC0 ------> ADC1_IN10
PC1 ------> ADC1_IN11
PB0 ------> ADC1_IN8
PB1 ------> ADC1_IN9
*/
HAL_GPIO_DeInit(GPIOC, SWR_FORW_Pin|SWR_BACKW_Pin);
HAL_GPIO_DeInit(GPIOB, PTT_SW1_Pin|PTT_SW2_Pin);
/* USER CODE BEGIN ADC1_MspDeInit 1 */
/* USER CODE END ADC1_MspDeInit 1 */
}
else if(hadc->Instance==ADC2)
{
/* USER CODE BEGIN ADC2_MspDeInit 0 */
/* USER CODE END ADC2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_ADC2_CLK_DISABLE();
/**ADC2 GPIO Configuration
PC4 ------> ADC2_IN14
PC5 ------> ADC2_IN15
*/
HAL_GPIO_DeInit(GPIOC, Power_IN_Pin|ALC_IN_Pin);
/* USER CODE BEGIN ADC2_MspDeInit 1 */
/* USER CODE END ADC2_MspDeInit 1 */
}
}
/**
* @brief I2S MSP Initialization
* This function configures the hardware resources used in this example
* @param hi2s: I2S handle pointer
* @retval None
*/
void HAL_I2S_MspInit(I2S_HandleTypeDef* hi2s)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hi2s->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspInit 0 */
/* BUG FIX: Enabling Audio Clock Input in CubeMX does not set I2SSRC bit
* in RCC_CFGR register! Hence we need to set it manually here! * WARNING: A bug fix is also needed in __HAL_RCC_GET_I2S_SOURCE()
Line 6131 stm32f4xx_hal_rcc_ex.h -> #define __HAL_RCC_GET_I2S_SOURCE() ((uint32_t)(READ_BIT(RCC->CFGR, RCC_CFGR_I2SSRC)) >> RCC_CFGR_I2SSRC_Pos)
*/
__HAL_RCC_I2S_CONFIG(RCC_I2SCLKSOURCE_EXT);
/* USER CODE END SPI3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI3_CLK_ENABLE();
__HAL_RCC_GPIOA_CLK_ENABLE();
__HAL_RCC_GPIOC_CLK_ENABLE();
/**I2S3 GPIO Configuration
PA15 ------> I2S3_WS
PC10 ------> I2S3_CK
PC11 ------> I2S3_ext_SD
PC12 ------> I2S3_SD
*/
GPIO_InitStruct.Pin = WM8731_WS_LRC_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(WM8731_WS_LRC_GPIO_Port, &GPIO_InitStruct);
GPIO_InitStruct.Pin = WM8731_BCLK_Pin|WM8731_DAC_SD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF6_SPI3;
HAL_GPIO_Init(GPIOC, &GPIO_InitStruct);
GPIO_InitStruct.Pin = WM8731_ADC_SD_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_VERY_HIGH;
GPIO_InitStruct.Alternate = GPIO_AF5_I2S3ext;
HAL_GPIO_Init(WM8731_ADC_SD_GPIO_Port, &GPIO_InitStruct);
/* I2S3 DMA Init */
/* SPI3_TX Init */
hdma_spi3_tx.Instance = DMA1_Stream5;
hdma_spi3_tx.Init.Channel = DMA_CHANNEL_0;
hdma_spi3_tx.Init.Direction = DMA_MEMORY_TO_PERIPH;
hdma_spi3_tx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_spi3_tx.Init.MemInc = DMA_MINC_ENABLE;
hdma_spi3_tx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_spi3_tx.Init.Mode = DMA_CIRCULAR;
hdma_spi3_tx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_spi3_tx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_spi3_tx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_spi3_tx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_spi3_tx.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&hdma_spi3_tx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hi2s,hdmatx,hdma_spi3_tx);
/* I2S3_EXT_RX Init */
hdma_i2s3_ext_rx.Instance = DMA1_Stream0;
hdma_i2s3_ext_rx.Init.Channel = DMA_CHANNEL_3;
hdma_i2s3_ext_rx.Init.Direction = DMA_PERIPH_TO_MEMORY;
hdma_i2s3_ext_rx.Init.PeriphInc = DMA_PINC_DISABLE;
hdma_i2s3_ext_rx.Init.MemInc = DMA_MINC_ENABLE;
hdma_i2s3_ext_rx.Init.PeriphDataAlignment = DMA_PDATAALIGN_HALFWORD;
hdma_i2s3_ext_rx.Init.MemDataAlignment = DMA_MDATAALIGN_HALFWORD;
hdma_i2s3_ext_rx.Init.Mode = DMA_CIRCULAR;
hdma_i2s3_ext_rx.Init.Priority = DMA_PRIORITY_VERY_HIGH;
hdma_i2s3_ext_rx.Init.FIFOMode = DMA_FIFOMODE_ENABLE;
hdma_i2s3_ext_rx.Init.FIFOThreshold = DMA_FIFO_THRESHOLD_FULL;
hdma_i2s3_ext_rx.Init.MemBurst = DMA_MBURST_SINGLE;
hdma_i2s3_ext_rx.Init.PeriphBurst = DMA_PBURST_SINGLE;
if (HAL_DMA_Init(&hdma_i2s3_ext_rx) != HAL_OK)
{
Error_Handler();
}
__HAL_LINKDMA(hi2s,hdmarx,hdma_i2s3_ext_rx);
/* I2S3 interrupt Init */
HAL_NVIC_SetPriority(SPI3_IRQn, 0, 0);
HAL_NVIC_EnableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspInit 1 */
/* USER CODE END SPI3_MspInit 1 */
}
}
/**
* @brief I2S MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hi2s: I2S handle pointer
* @retval None
*/
void HAL_I2S_MspDeInit(I2S_HandleTypeDef* hi2s)
{
if(hi2s->Instance==SPI3)
{
/* USER CODE BEGIN SPI3_MspDeInit 0 */
/* USER CODE END SPI3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI3_CLK_DISABLE();
/**I2S3 GPIO Configuration
PA15 ------> I2S3_WS
PC10 ------> I2S3_CK
PC11 ------> I2S3_ext_SD
PC12 ------> I2S3_SD
*/
HAL_GPIO_DeInit(WM8731_WS_LRC_GPIO_Port, WM8731_WS_LRC_Pin);
HAL_GPIO_DeInit(GPIOC, WM8731_BCLK_Pin|WM8731_ADC_SD_Pin|WM8731_DAC_SD_Pin);
/* I2S3 DMA DeInit */
HAL_DMA_DeInit(hi2s->hdmatx);
HAL_DMA_DeInit(hi2s->hdmarx);
/* I2S3 interrupt DeInit */
HAL_NVIC_DisableIRQ(SPI3_IRQn);
/* USER CODE BEGIN SPI3_MspDeInit 1 */
/* USER CODE END SPI3_MspDeInit 1 */
}
}
/**
* @brief RTC MSP Initialization
* This function configures the hardware resources used in this example
* @param hrtc: RTC handle pointer
* @retval None
*/
void HAL_RTC_MspInit(RTC_HandleTypeDef* hrtc)
{
if(hrtc->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspInit 0 */
/* USER CODE END RTC_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_RTC_ENABLE();
/* USER CODE BEGIN RTC_MspInit 1 */
/* USER CODE END RTC_MspInit 1 */
}
}
/**
* @brief RTC MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hrtc: RTC handle pointer
* @retval None
*/
void HAL_RTC_MspDeInit(RTC_HandleTypeDef* hrtc)
{
if(hrtc->Instance==RTC)
{
/* USER CODE BEGIN RTC_MspDeInit 0 */
/* USER CODE END RTC_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_RTC_DISABLE();
/* USER CODE BEGIN RTC_MspDeInit 1 */
/* USER CODE END RTC_MspDeInit 1 */
}
}
/**
* @brief SPI MSP Initialization
* This function configures the hardware resources used in this example
* @param hspi: SPI handle pointer
* @retval None
*/
void HAL_SPI_MspInit(SPI_HandleTypeDef* hspi)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hspi->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspInit 0 */
/* USER CODE END SPI2_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_SPI2_CLK_ENABLE();
__HAL_RCC_GPIOB_CLK_ENABLE();
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
GPIO_InitStruct.Pin = PERI_SCK_Pin|PERI_MISO_Pin|PERI_MOSI_Pin;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_PULLUP;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF5_SPI2;
HAL_GPIO_Init(GPIOB, &GPIO_InitStruct);
/* USER CODE BEGIN SPI2_MspInit 1 */
/* USER CODE END SPI2_MspInit 1 */
}
}
/**
* @brief SPI MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hspi: SPI handle pointer
* @retval None
*/
void HAL_SPI_MspDeInit(SPI_HandleTypeDef* hspi)
{
if(hspi->Instance==SPI2)
{
/* USER CODE BEGIN SPI2_MspDeInit 0 */
/* USER CODE END SPI2_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_SPI2_CLK_DISABLE();
/**SPI2 GPIO Configuration
PB13 ------> SPI2_SCK
PB14 ------> SPI2_MISO
PB15 ------> SPI2_MOSI
*/
HAL_GPIO_DeInit(GPIOB, PERI_SCK_Pin|PERI_MISO_Pin|PERI_MOSI_Pin);
/* USER CODE BEGIN SPI2_MspDeInit 1 */
/* USER CODE END SPI2_MspDeInit 1 */
}
}
/**
* @brief TIM_Base MSP Initialization
* This function configures the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspInit 0 */
/* USER CODE END TIM3_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM3_CLK_ENABLE();
/* TIM3 interrupt Init */
HAL_NVIC_SetPriority(TIM3_IRQn, 2, 0);
HAL_NVIC_EnableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspInit 1 */
/* USER CODE END TIM3_MspInit 1 */
}
else if(htim_base->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspInit 0 */
/* USER CODE END TIM4_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM4_CLK_ENABLE();
/* TIM4 interrupt Init */
HAL_NVIC_SetPriority(TIM4_IRQn, 9, 0);
HAL_NVIC_EnableIRQ(TIM4_IRQn);
/* USER CODE BEGIN TIM4_MspInit 1 */
/* USER CODE END TIM4_MspInit 1 */
}
else if(htim_base->Instance==TIM5)
{
/* USER CODE BEGIN TIM5_MspInit 0 */
/* USER CODE END TIM5_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM5_CLK_ENABLE();
/* TIM5 interrupt Init */
HAL_NVIC_SetPriority(TIM5_IRQn, 5, 0);
HAL_NVIC_EnableIRQ(TIM5_IRQn);
/* USER CODE BEGIN TIM5_MspInit 1 */
/* USER CODE END TIM5_MspInit 1 */
}
else if(htim_base->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspInit 0 */
/* USER CODE END TIM6_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM6_CLK_ENABLE();
/* TIM6 interrupt Init */
HAL_NVIC_SetPriority(TIM6_DAC_IRQn, 8, 0);
HAL_NVIC_EnableIRQ(TIM6_DAC_IRQn);
/* USER CODE BEGIN TIM6_MspInit 1 */
/* USER CODE END TIM6_MspInit 1 */
}
else if(htim_base->Instance==TIM7)
{
/* USER CODE BEGIN TIM7_MspInit 0 */
/* USER CODE END TIM7_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM7_CLK_ENABLE();
/* TIM7 interrupt Init */
HAL_NVIC_SetPriority(TIM7_IRQn, 11, 0);
HAL_NVIC_EnableIRQ(TIM7_IRQn);
/* USER CODE BEGIN TIM7_MspInit 1 */
/* USER CODE END TIM7_MspInit 1 */
}
else if(htim_base->Instance==TIM8)
{
/* USER CODE BEGIN TIM8_MspInit 0 */
/* USER CODE END TIM8_MspInit 0 */
/* Peripheral clock enable */
__HAL_RCC_TIM8_CLK_ENABLE();
/* TIM8 interrupt Init */
HAL_NVIC_SetPriority(TIM8_UP_TIM13_IRQn, 10, 0);
HAL_NVIC_EnableIRQ(TIM8_UP_TIM13_IRQn);
/* USER CODE BEGIN TIM8_MspInit 1 */
/* USER CODE END TIM8_MspInit 1 */
}
}
/**
* @brief TIM_Base MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param htim_base: TIM_Base handle pointer
* @retval None
*/
void HAL_TIM_Base_MspDeInit(TIM_HandleTypeDef* htim_base)
{
if(htim_base->Instance==TIM3)
{
/* USER CODE BEGIN TIM3_MspDeInit 0 */
/* USER CODE END TIM3_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM3_CLK_DISABLE();
/* TIM3 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM3_IRQn);
/* USER CODE BEGIN TIM3_MspDeInit 1 */
/* USER CODE END TIM3_MspDeInit 1 */
}
else if(htim_base->Instance==TIM4)
{
/* USER CODE BEGIN TIM4_MspDeInit 0 */
/* USER CODE END TIM4_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM4_CLK_DISABLE();
/* TIM4 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM4_IRQn);
/* USER CODE BEGIN TIM4_MspDeInit 1 */
/* USER CODE END TIM4_MspDeInit 1 */
}
else if(htim_base->Instance==TIM5)
{
/* USER CODE BEGIN TIM5_MspDeInit 0 */
/* USER CODE END TIM5_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM5_CLK_DISABLE();
/* TIM5 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM5_IRQn);
/* USER CODE BEGIN TIM5_MspDeInit 1 */
/* USER CODE END TIM5_MspDeInit 1 */
}
else if(htim_base->Instance==TIM6)
{
/* USER CODE BEGIN TIM6_MspDeInit 0 */
/* USER CODE END TIM6_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM6_CLK_DISABLE();
/* TIM6 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM6_DAC_IRQn);
/* USER CODE BEGIN TIM6_MspDeInit 1 */
/* USER CODE END TIM6_MspDeInit 1 */
}
else if(htim_base->Instance==TIM7)
{
/* USER CODE BEGIN TIM7_MspDeInit 0 */
/* USER CODE END TIM7_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM7_CLK_DISABLE();
/* TIM7 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM7_IRQn);
/* USER CODE BEGIN TIM7_MspDeInit 1 */
/* USER CODE END TIM7_MspDeInit 1 */
}
else if(htim_base->Instance==TIM8)
{
/* USER CODE BEGIN TIM8_MspDeInit 0 */
/* USER CODE END TIM8_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_TIM8_CLK_DISABLE();
/* TIM8 interrupt DeInit */
HAL_NVIC_DisableIRQ(TIM8_UP_TIM13_IRQn);
/* USER CODE BEGIN TIM8_MspDeInit 1 */
/* USER CODE END TIM8_MspDeInit 1 */
}
}
/**
* @brief PCD MSP Initialization
* This function configures the hardware resources used in this example
* @param hpcd: PCD handle pointer
* @retval None
*/
void HAL_PCD_MspInit(PCD_HandleTypeDef* hpcd)
{
GPIO_InitTypeDef GPIO_InitStruct = {0};
if(hpcd->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspInit 0 */
/* USER CODE END USB_OTG_FS_MspInit 0 */
__HAL_RCC_GPIOA_CLK_ENABLE();
/**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
*/
GPIO_InitStruct.Pin = GPIO_PIN_11|GPIO_PIN_12;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF10_OTG_FS;
HAL_GPIO_Init(GPIOA, &GPIO_InitStruct);
/* Peripheral clock enable */
__HAL_RCC_USB_OTG_FS_CLK_ENABLE();
/* USB_OTG_FS interrupt Init */
HAL_NVIC_SetPriority(OTG_FS_IRQn, 1, 0);
HAL_NVIC_EnableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspInit 1 */
/* USER CODE END USB_OTG_FS_MspInit 1 */
}
}
/**
* @brief PCD MSP De-Initialization
* This function freeze the hardware resources used in this example
* @param hpcd: PCD handle pointer
* @retval None
*/
void HAL_PCD_MspDeInit(PCD_HandleTypeDef* hpcd)
{
if(hpcd->Instance==USB_OTG_FS)
{
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 0 */
/* USER CODE END USB_OTG_FS_MspDeInit 0 */
/* Peripheral clock disable */
__HAL_RCC_USB_OTG_FS_CLK_DISABLE();
/**USB_OTG_FS GPIO Configuration
PA11 ------> USB_OTG_FS_DM
PA12 ------> USB_OTG_FS_DP
*/
HAL_GPIO_DeInit(GPIOA, GPIO_PIN_11|GPIO_PIN_12);
/* USB_OTG_FS interrupt DeInit */
HAL_NVIC_DisableIRQ(OTG_FS_IRQn);
/* USER CODE BEGIN USB_OTG_FS_MspDeInit 1 */
/* USER CODE END USB_OTG_FS_MspDeInit 1 */
}
}
static uint32_t FSMC_Initialized = 0;
static void HAL_FSMC_MspInit(void){
/* USER CODE BEGIN FSMC_MspInit 0 */
/* USER CODE END FSMC_MspInit 0 */
GPIO_InitTypeDef GPIO_InitStruct ={0};
if (FSMC_Initialized) {
return;
}
FSMC_Initialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FSMC_CLK_ENABLE();
/** FSMC GPIO Configuration
PE7 ------> FSMC_D4
PE8 ------> FSMC_D5
PE9 ------> FSMC_D6
PE10 ------> FSMC_D7
PE11 ------> FSMC_D8
PE12 ------> FSMC_D9
PE13 ------> FSMC_D10
PE14 ------> FSMC_D11
PE15 ------> FSMC_D12
PD8 ------> FSMC_D13
PD9 ------> FSMC_D14
PD10 ------> FSMC_D15
PD13 ------> FSMC_A18
PD14 ------> FSMC_D0
PD15 ------> FSMC_D1
PD0 ------> FSMC_D2
PD1 ------> FSMC_D3
PD4 ------> FSMC_NOE
PD5 ------> FSMC_NWE
PD7 ------> FSMC_NE1
*/
GPIO_InitStruct.Pin = GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOE, &GPIO_InitStruct);
GPIO_InitStruct.Pin = GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7;
GPIO_InitStruct.Mode = GPIO_MODE_AF_PP;
GPIO_InitStruct.Pull = GPIO_NOPULL;
GPIO_InitStruct.Speed = GPIO_SPEED_FREQ_LOW;
GPIO_InitStruct.Alternate = GPIO_AF12_FSMC;
HAL_GPIO_Init(GPIOD, &GPIO_InitStruct);
/* USER CODE BEGIN FSMC_MspInit 1 */
/* USER CODE END FSMC_MspInit 1 */
}
void HAL_SRAM_MspInit(SRAM_HandleTypeDef* hsram){
/* USER CODE BEGIN SRAM_MspInit 0 */
/* USER CODE END SRAM_MspInit 0 */
HAL_FSMC_MspInit();
/* USER CODE BEGIN SRAM_MspInit 1 */
/* USER CODE END SRAM_MspInit 1 */
}
static uint32_t FSMC_DeInitialized = 0;
static void HAL_FSMC_MspDeInit(void){
/* USER CODE BEGIN FSMC_MspDeInit 0 */
/* USER CODE END FSMC_MspDeInit 0 */
if (FSMC_DeInitialized) {
return;
}
FSMC_DeInitialized = 1;
/* Peripheral clock enable */
__HAL_RCC_FSMC_CLK_DISABLE();
/** FSMC GPIO Configuration
PE7 ------> FSMC_D4
PE8 ------> FSMC_D5
PE9 ------> FSMC_D6
PE10 ------> FSMC_D7
PE11 ------> FSMC_D8
PE12 ------> FSMC_D9
PE13 ------> FSMC_D10
PE14 ------> FSMC_D11
PE15 ------> FSMC_D12
PD8 ------> FSMC_D13
PD9 ------> FSMC_D14
PD10 ------> FSMC_D15
PD13 ------> FSMC_A18
PD14 ------> FSMC_D0
PD15 ------> FSMC_D1
PD0 ------> FSMC_D2
PD1 ------> FSMC_D3
PD4 ------> FSMC_NOE
PD5 ------> FSMC_NWE
PD7 ------> FSMC_NE1
*/
HAL_GPIO_DeInit(GPIOE, GPIO_PIN_7|GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10
|GPIO_PIN_11|GPIO_PIN_12|GPIO_PIN_13|GPIO_PIN_14
|GPIO_PIN_15);
HAL_GPIO_DeInit(GPIOD, GPIO_PIN_8|GPIO_PIN_9|GPIO_PIN_10|GPIO_PIN_13
|GPIO_PIN_14|GPIO_PIN_15|GPIO_PIN_0|GPIO_PIN_1
|GPIO_PIN_4|GPIO_PIN_5|GPIO_PIN_7);
/* USER CODE BEGIN FSMC_MspDeInit 1 */
/* USER CODE END FSMC_MspDeInit 1 */
}
void HAL_SRAM_MspDeInit(SRAM_HandleTypeDef* hsram){
/* USER CODE BEGIN SRAM_MspDeInit 0 */
/* USER CODE END SRAM_MspDeInit 0 */
HAL_FSMC_MspDeInit();
/* USER CODE BEGIN SRAM_MspDeInit 1 */
/* USER CODE END SRAM_MspDeInit 1 */
}
/* USER CODE BEGIN 1 */
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -1,866 +0,0 @@
/* USER CODE BEGIN Header */
/**
******************************************************************************
* @file stm32f4xx_it.c
* @brief Interrupt Service Routines.
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2020 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
// EXTI0 - KEY DASH
// EXTI1 - KEY DOT
// EXTI2 - ENC_CLK
// EXTI4 - PTT_IN
// EXTI10 - 48K_Clock
// EXTI11 - PWR_button
// EXTI13 - ENC2_CLK
// TIM3 - WIFI
// TIM4 - FFT calculation
// TIM5 - audio processor
// TIM6 - every 10ms, different actions
// TIM7 - USB FIFO
// TIM15 - EEPROM / front panel
// TIM16 - Interrogation of the auxiliary encoder, because it hangs on the same interrupt as the FPGA
// TIM17 - Digital CW decoding, ...
// DMA1-0 - receiving data from the audio codec
// DMA1-1 - receiving data from WiFi via UART
// DMA1-5 - sending data to audio codec
// DMA2-4 - DMA for copying 16 bit arrays
// DMA2-5 - draw the fft at 16 bits, increment
// DMA2-6 - draw the waterfall at 16 bits, increment
// DMA2-7 - move the waterfall down
// DMA2-0 - copy audio buffers at 32bit
// DMA2-1 - send audio processor buffer to codec buffer - A
// DMA2-2 - send audio processor buffer to codec buffer - B
// DMA2-3 - DMA video driver, for filling, 16 bits without increment
/* USER CODE END Header */
/* Includes ------------------------------------------------------------------*/
#include "main.h"
#include "stm32f4xx_it.h"
/* Private includes ----------------------------------------------------------*/
/* USER CODE BEGIN Includes */
/* USER CODE END Includes */
/* Private typedef -----------------------------------------------------------*/
/* USER CODE BEGIN TD */
/* USER CODE END TD */
/* Private define ------------------------------------------------------------*/
/* USER CODE BEGIN PD */
/* USER CODE END PD */
/* Private macro -------------------------------------------------------------*/
/* USER CODE BEGIN PM */
/* USER CODE END PM */
/* Private variables ---------------------------------------------------------*/
/* USER CODE BEGIN PV */
/* USER CODE END PV */
/* Private function prototypes -----------------------------------------------*/
/* USER CODE BEGIN PFP */
/* USER CODE END PFP */
/* Private user code ---------------------------------------------------------*/
/* USER CODE BEGIN 0 */
#include "functions.h"
#include "front_unit.h"
#include "rf_unit.h"
#include "fpga.h"
#include "lcd.h"
#include "wm8731.h"
#include "audio_processor.h"
#include "agc.h"
#include "fft.h"
#include "settings.h"
#include "fpga.h"
#include "profiler.h"
#include "usbd_debug_if.h"
#include "usbd_cat_if.h"
#include "usbd_audio_if.h"
#include "usbd_ua3reo.h"
#include "trx_manager.h"
#include "audio_filters.h"
#include "system_menu.h"
#include "bootloader.h"
#include "swr_analyzer.h"
static uint32_t ms10_counter = 0;
static uint32_t tim6_delay = 0;
static uint32_t powerdown_start_delay = 0;
/* USER CODE END 0 */
/* External variables --------------------------------------------------------*/
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream7;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream6;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream4;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream1;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream0;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream2;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream3;
extern DMA_HandleTypeDef hdma_memtomem_dma2_stream5;
extern DMA_HandleTypeDef hdma_spi3_tx;
extern DMA_HandleTypeDef hdma_i2s3_ext_rx;
extern I2S_HandleTypeDef hi2s3;
extern TIM_HandleTypeDef htim3;
extern TIM_HandleTypeDef htim4;
extern TIM_HandleTypeDef htim5;
extern TIM_HandleTypeDef htim6;
extern TIM_HandleTypeDef htim7;
extern TIM_HandleTypeDef htim8;
extern PCD_HandleTypeDef hpcd_USB_OTG_FS;
/* USER CODE BEGIN EV */
/* USER CODE END EV */
/******************************************************************************/
/* Cortex-M4 Processor Interruption and Exception Handlers */
/******************************************************************************/
/**
* @brief This function handles Non maskable interrupt.
*/
void NMI_Handler(void)
{
/* USER CODE BEGIN NonMaskableInt_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END NonMaskableInt_IRQn 0 */
/* USER CODE BEGIN NonMaskableInt_IRQn 1 */
/* USER CODE END NonMaskableInt_IRQn 1 */
}
/**
* @brief This function handles Hard fault interrupt.
*/
void HardFault_Handler(void)
{
/* USER CODE BEGIN HardFault_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END HardFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_HardFault_IRQn 0 */
LCD_showError("Hard Fault", false);
static uint32_t i = 0; while(i < 99999999) { i++; __asm("nop"); }
HAL_GPIO_WritePin(CPU_PW_HOLD_GPIO_Port, CPU_PW_HOLD_Pin, GPIO_PIN_RESET);
/* USER CODE END W1_HardFault_IRQn 0 */
}
}
/**
* @brief This function handles Memory management fault.
*/
void MemManage_Handler(void)
{
/* USER CODE BEGIN MemoryManagement_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END MemoryManagement_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_MemoryManagement_IRQn 0 */
LCD_showError("Memory Fault", false);
static uint32_t i = 0; while(i < 99999999) { i++; __asm("nop"); }
HAL_GPIO_WritePin(CPU_PW_HOLD_GPIO_Port, CPU_PW_HOLD_Pin, GPIO_PIN_RESET);
/* USER CODE END W1_MemoryManagement_IRQn 0 */
}
}
/**
* @brief This function handles Pre-fetch fault, memory access fault.
*/
void BusFault_Handler(void)
{
/* USER CODE BEGIN BusFault_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END BusFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_BusFault_IRQn 0 */
LCD_showError("Bus Fault", false);
static uint32_t i = 0; while(i < 99999999) { i++; __asm("nop"); }
HAL_GPIO_WritePin(CPU_PW_HOLD_GPIO_Port, CPU_PW_HOLD_Pin, GPIO_PIN_RESET);
/* USER CODE END W1_BusFault_IRQn 0 */
}
}
/**
* @brief This function handles Undefined instruction or illegal state.
*/
void UsageFault_Handler(void)
{
/* USER CODE BEGIN UsageFault_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END UsageFault_IRQn 0 */
while (1)
{
/* USER CODE BEGIN W1_UsageFault_IRQn 0 */
LCD_showError("Usage Fault", false);
static uint32_t i = 0; while(i < 99999999) { i++; __asm("nop"); }
HAL_GPIO_WritePin(CPU_PW_HOLD_GPIO_Port, CPU_PW_HOLD_Pin, GPIO_PIN_RESET);
/* USER CODE END W1_UsageFault_IRQn 0 */
}
}
/**
* @brief This function handles System service call via SWI instruction.
*/
void SVC_Handler(void)
{
/* USER CODE BEGIN SVCall_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END SVCall_IRQn 0 */
/* USER CODE BEGIN SVCall_IRQn 1 */
/* USER CODE END SVCall_IRQn 1 */
}
/**
* @brief This function handles Debug monitor.
*/
void DebugMon_Handler(void)
{
/* USER CODE BEGIN DebugMonitor_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DebugMonitor_IRQn 0 */
/* USER CODE BEGIN DebugMonitor_IRQn 1 */
/* USER CODE END DebugMonitor_IRQn 1 */
}
/**
* @brief This function handles Pendable request for system service.
*/
void PendSV_Handler(void)
{
/* USER CODE BEGIN PendSV_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END PendSV_IRQn 0 */
/* USER CODE BEGIN PendSV_IRQn 1 */
/* USER CODE END PendSV_IRQn 1 */
}
/**
* @brief This function handles System tick timer.
*/
void SysTick_Handler(void)
{
/* USER CODE BEGIN SysTick_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END SysTick_IRQn 0 */
HAL_IncTick();
/* USER CODE BEGIN SysTick_IRQn 1 */
/* USER CODE END SysTick_IRQn 1 */
}
/******************************************************************************/
/* STM32F4xx Peripheral Interrupt Handlers */
/* Add here the Interrupt Handlers for the used peripherals. */
/* For the available peripheral interrupt handler names, */
/* please refer to the startup file (startup_stm32f4xx.s). */
/******************************************************************************/
/**
* @brief This function handles EXTI line0 interrupt.
*/
void EXTI0_IRQHandler(void)
{
/* USER CODE BEGIN EXTI0_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI0_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_0);
/* USER CODE BEGIN EXTI0_IRQn 1 */
/* USER CODE END EXTI0_IRQn 1 */
}
/**
* @brief This function handles EXTI line1 interrupt.
*/
void EXTI1_IRQHandler(void)
{
/* USER CODE BEGIN EXTI1_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI1_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_1);
/* USER CODE BEGIN EXTI1_IRQn 1 */
/* USER CODE END EXTI1_IRQn 1 */
}
/**
* @brief This function handles EXTI line2 interrupt.
*/
void EXTI2_IRQHandler(void)
{
/* USER CODE BEGIN EXTI2_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI2_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_2);
/* USER CODE BEGIN EXTI2_IRQn 1 */
/* USER CODE END EXTI2_IRQn 1 */
}
/**
* @brief This function handles EXTI line3 interrupt.
*/
void EXTI3_IRQHandler(void)
{
/* USER CODE BEGIN EXTI3_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI3_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_3);
/* USER CODE BEGIN EXTI3_IRQn 1 */
/* USER CODE END EXTI3_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream0 global interrupt.
*/
void DMA1_Stream0_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream0_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DMA1_Stream0_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_i2s3_ext_rx);
/* USER CODE BEGIN DMA1_Stream0_IRQn 1 */
/* USER CODE END DMA1_Stream0_IRQn 1 */
}
/**
* @brief This function handles DMA1 stream5 global interrupt.
*/
void DMA1_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA1_Stream5_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DMA1_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_spi3_tx);
/* USER CODE BEGIN DMA1_Stream5_IRQn 1 */
/* USER CODE END DMA1_Stream5_IRQn 1 */
}
/**
* @brief This function handles EXTI line[9:5] interrupts.
*/
void EXTI9_5_IRQHandler(void)
{
/* USER CODE BEGIN EXTI9_5_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI9_5_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_7);
/* USER CODE BEGIN EXTI9_5_IRQn 1 */
/* USER CODE END EXTI9_5_IRQn 1 */
}
/**
* @brief This function handles TIM3 global interrupt.
*/
void TIM3_IRQHandler(void)
{
/* USER CODE BEGIN TIM3_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM3_IRQn 0 */
HAL_TIM_IRQHandler(&htim3);
/* USER CODE BEGIN TIM3_IRQn 1 */
static uint8_t ENC2lastClkVal = 0;
static bool ENC2first = true;
uint8_t ENCODER2_CLKVal = HAL_GPIO_ReadPin(ENC2_CLK_GPIO_Port, ENC2_CLK_Pin);
if (ENC2first)
{
ENC2lastClkVal = ENCODER2_CLKVal;
ENC2first = false;
}
if(ENC2lastClkVal != ENCODER2_CLKVal)
{
if (TRX_Inited)
FRONTPANEL_ENCODER2_checkRotate();
ENC2lastClkVal = ENCODER2_CLKVal;
}
/* USER CODE END TIM3_IRQn 1 */
}
/**
* @brief This function handles TIM4 global interrupt.
*/
void TIM4_IRQHandler(void)
{
/* USER CODE BEGIN TIM4_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM4_IRQn 0 */
HAL_TIM_IRQHandler(&htim4);
/* USER CODE BEGIN TIM4_IRQn 1 */
if (sysmenu_swr_opened)
{
SYSMENU_drawSystemMenu(false);
return;
}
if (FFT_new_buffer_ready)
FFT_bufferPrepare();
if (FFT_need_fft)
FFT_doFFT();
ua3reo_dev_cat_parseCommand();
/* USER CODE END TIM4_IRQn 1 */
}
/**
* @brief This function handles EXTI line[15:10] interrupts.
*/
void EXTI15_10_IRQHandler(void)
{
/* USER CODE BEGIN EXTI15_10_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END EXTI15_10_IRQn 0 */
HAL_GPIO_EXTI_IRQHandler(GPIO_PIN_10);
/* USER CODE BEGIN EXTI15_10_IRQn 1 */
/* USER CODE END EXTI15_10_IRQn 1 */
}
/**
* @brief This function handles TIM8 update interrupt and TIM13 global interrupt.
*/
void TIM8_UP_TIM13_IRQHandler(void)
{
/* USER CODE BEGIN TIM8_UP_TIM13_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM8_UP_TIM13_IRQn 0 */
HAL_TIM_IRQHandler(&htim8);
/* USER CODE BEGIN TIM8_UP_TIM13_IRQn 1 */
//FRONT PANEL SPI
FRONTPANEL_Process();
//EEPROM SPI
if (NeedSaveCalibration) // save calibration data to EEPROM
SaveCalibration();
/* USER CODE END TIM8_UP_TIM13_IRQn 1 */
}
/**
* @brief This function handles TIM5 global interrupt.
*/
void TIM5_IRQHandler(void)
{
/* USER CODE BEGIN TIM5_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM5_IRQn 0 */
HAL_TIM_IRQHandler(&htim5);
/* USER CODE BEGIN TIM5_IRQn 1 */
if (!Processor_NeedTXBuffer && !Processor_NeedRXBuffer)
return;
if (TRX_on_TX())
{
if (CurrentVFO()->Mode != TRX_MODE_NO_TX)
processTxAudio();
}
else
{
processRxAudio();
}
/* USER CODE END TIM5_IRQn 1 */
}
/**
* @brief This function handles SPI3 global interrupt.
*/
void SPI3_IRQHandler(void)
{
/* USER CODE BEGIN SPI3_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END SPI3_IRQn 0 */
HAL_I2S_IRQHandler(&hi2s3);
/* USER CODE BEGIN SPI3_IRQn 1 */
/* USER CODE END SPI3_IRQn 1 */
}
/**
* @brief This function handles TIM6 global interrupt, DAC1 and DAC2 underrun error interrupts.
*/
void TIM6_DAC_IRQHandler(void)
{
/* USER CODE BEGIN TIM6_DAC_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM6_DAC_IRQn 0 */
HAL_TIM_IRQHandler(&htim6);
/* USER CODE BEGIN TIM6_DAC_IRQn 1 */
ms10_counter++;
// transmission release time after key signal
if (TRX_Key_Timeout_est > 0 && !TRX_key_serial && !TRX_key_dot_hard && !TRX_key_dash_hard)
{
TRX_Key_Timeout_est -= 10;
if (TRX_Key_Timeout_est == 0)
{
LCD_UpdateQuery.StatusInfoGUI = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
//every 10ms
// if the settings have changed, update the parameters in the FPGA
if (NeedSaveSettings)
FPGA_NeedSendParams = true;
// there was a request to reinitialize audio filters
if (NeedReinitAudioFilters)
ReinitAudioFilters();
//Process SWR, Power meter, ALC, Thermal sensors, Fan, ...
RF_UNIT_ProcessSensors();
// emulate PTT over CAT
if (TRX_ptt_soft != TRX_old_ptt_soft)
TRX_ptt_change();
// emulate the key via the COM port
if (TRX_key_serial != TRX_old_key_serial)
TRX_key_change();
if ((ms10_counter % 10) == 0) // every 100ms
{
// every 100ms we receive data from FPGA (amplitude, ADC overload, etc.)
FPGA_NeedGetParams = true;
//S-Meter Calculate
TRX_DBMCalculate();
//Detect FPGA stuck error
static float32_t old_FPGA_Audio_Buffer_RX_I = 0;
static float32_t old_FPGA_Audio_Buffer_RX_Q = 0;
static uint16_t fpga_stuck_errors = 0;
if(FPGA_Audio_Buffer_RX_I[0] == old_FPGA_Audio_Buffer_RX_I || FPGA_Audio_Buffer_RX_Q[0] == old_FPGA_Audio_Buffer_RX_Q)
fpga_stuck_errors++;
else
fpga_stuck_errors=0;
if(fpga_stuck_errors>3 && !TRX_on_TX() && !TRX.ADC_SHDN)
{
/*sendToDebug_strln("[ERR] IQ stuck error, restart");
sendToDebug_float32(old_FPGA_Audio_Buffer_RX_I, false);
sendToDebug_float32(old_FPGA_Audio_Buffer_RX_Q, false);*/
fpga_stuck_errors=0;
FPGA_NeedRestart = true;
}
old_FPGA_Audio_Buffer_RX_I = FPGA_Audio_Buffer_RX_I[0];
old_FPGA_Audio_Buffer_RX_Q = FPGA_Audio_Buffer_RX_Q[0];
//Process AutoGain feature
TRX_DoAutoGain();
// reset error flags
WM8731_Buffer_underrun = false;
FPGA_Buffer_underrun = false;
RX_USB_AUDIO_underrun = false;
}
static bool needPrintFFT = false;
if ((ms10_counter % 3) == 0) // every 30ms
{
// update information on LCD
LCD_UpdateQuery.StatusInfoBar = true;
LCD_doEvents();
// draw FFT
needPrintFFT = true;
}
else if(LCD_UpdateQuery.FreqInfo)//Redraw freq fast
LCD_doEvents();
if(needPrintFFT && !LCD_UpdateQuery.Background && FFT_printFFT()) // draw FFT
needPrintFFT = false;
if (ms10_counter == 101) // every 1 sec
{
ms10_counter = 0;
//Detect FPGA IQ phase error
/*static bool phase_restarted = false;
if ((TRX_IQ_phase_error < 0.01f || TRX_IQ_phase_error > 0.08f) && !TRX_on_TX() && !phase_restarted && !TRX.ADC_SHDN)
{
sendToDebug_str("[ERR] IQ phase error, restart | ");
sendToDebug_float32(TRX_IQ_phase_error, false);
FPGA_NeedRestart = true;
phase_restarted = true;
}*/
// Calculate CPU load
CPULOAD_Calc();
if (TRX.Debug_Console)
{
//Save Debug variables
uint32_t dbg_tim6_delay = HAL_GetTick() - tim6_delay;
float32_t dbg_coeff = 1000.0f / (float32_t)dbg_tim6_delay;
uint32_t dbg_FPGA_samples = (uint32_t)((float32_t)FPGA_samples * dbg_coeff);
uint32_t dbg_WM8731_DMA_samples = (uint32_t)((float32_t)WM8731_DMA_samples / 2.0f * dbg_coeff);
float32_t dbg_FPGA_Audio_Buffer_I_tmp = FPGA_Audio_Buffer_RX_I[0];
float32_t dbg_FPGA_Audio_Buffer_Q_tmp = FPGA_Audio_Buffer_RX_Q[0];
if (TRX_on_TX())
{
dbg_FPGA_Audio_Buffer_I_tmp = FPGA_Audio_SendBuffer_I[0];
dbg_FPGA_Audio_Buffer_Q_tmp = FPGA_Audio_SendBuffer_Q[0];
}
uint32_t cpu_load = (uint32_t)CPU_LOAD.Load;
//Print Debug info
sendToDebug_str("FPGA Samples: ");
sendToDebug_uint32(dbg_FPGA_samples, false); //~96000
sendToDebug_str("Audio DMA samples: ");
sendToDebug_uint32(dbg_WM8731_DMA_samples, false); //~48000
sendToDebug_str("CPU Load: ");
sendToDebug_uint32(cpu_load, false);
sendToDebug_str("TIM6 delay: ");
sendToDebug_uint32(dbg_tim6_delay, false);
sendToDebug_str("First byte of RX-FPGA I/Q: ");
sendToDebug_float32(dbg_FPGA_Audio_Buffer_I_tmp, true); //first byte of I
sendToDebug_str(" / ");
sendToDebug_float32(dbg_FPGA_Audio_Buffer_Q_tmp, false); //first byte of Q
sendToDebug_str("IQ Phase error: ");
sendToDebug_float32(TRX_IQ_phase_error, false); //first byte of Q
sendToDebug_str("ADC MIN/MAX Amplitude: ");
sendToDebug_int16(TRX_ADC_MINAMPLITUDE, true);
sendToDebug_str(" / ");
sendToDebug_int16(TRX_ADC_MAXAMPLITUDE, false);
sendToDebug_newline();
PrintProfilerResult();
}
//Save Settings to Backup Memory
if (NeedSaveSettings && (HAL_GPIO_ReadPin(CPU_PW_GPIO_Port, CPU_PW_Pin) == GPIO_PIN_SET))
SaveSettings();
//Reset counters
tim6_delay = HAL_GetTick();
FPGA_samples = 0;
AUDIOPROC_samples = 0;
WM8731_DMA_samples = 0;
FFT_FPS = 0;
RX_USB_AUDIO_SAMPLES = 0;
TX_USB_AUDIO_SAMPLES = 0;
FPGA_NeedSendParams = true;
//redraw lcd to fix problem
#ifdef LCD_HX8357B
static uint8_t HX8357B_BUG_redraw_counter = 0;
HX8357B_BUG_redraw_counter++;
if(HX8357B_BUG_redraw_counter == 20)
{
LCD_UpdateQuery.TopButtonsRedraw = true;
LCD_UpdateQuery.StatusInfoBarRedraw = true;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
}
else if(HX8357B_BUG_redraw_counter == 40)
{
LCD_UpdateQuery.FreqInfoRedraw = true;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
}
else if(HX8357B_BUG_redraw_counter >= 60)
{
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
LCD_UpdateQuery.StatusInfoBarRedraw = true;
HX8357B_BUG_redraw_counter = 0;
}
#endif
}
//power off sequence
if ((HAL_GPIO_ReadPin(CPU_PW_GPIO_Port, CPU_PW_Pin) == GPIO_PIN_RESET) && ((HAL_GetTick() - powerdown_start_delay) > POWERDOWN_TIMEOUT) && !NeedSaveCalibration && !SPI_process && !EEPROM_Busy)
{
TRX_Inited = false;
LCD_busy = true;
HAL_Delay(10);
WM8731_Mute();
WM8731_CleanBuffer();
LCDDriver_Fill(COLOR_BLACK);
LCD_showInfo("GOOD BYE!", false);
SaveSettings();
SaveSettingsToEEPROM();
sendToDebug_flush();
HAL_GPIO_WritePin(CPU_PW_HOLD_GPIO_Port, CPU_PW_HOLD_Pin, GPIO_PIN_RESET);
while (HAL_GPIO_ReadPin(CPU_PW_GPIO_Port, CPU_PW_Pin) == GPIO_PIN_RESET) {} //-V776
HAL_Delay(500);
//SCB->AIRCR = 0x05FA0004; // software resetw
while(true){}
}
//TRX protector
if(TRX_on_TX())
{
if(TRX_SWR > TRX_MAX_SWR && !TRX_Tune && CurrentVFO()->Mode != TRX_MODE_LOOPBACK)
{
TRX_Tune = false;
TRX_ptt_hard = false;
TRX_ptt_soft = false;
LCD_UpdateQuery.StatusInfoGUI = true;
LCD_UpdateQuery.TopButtons = true;
NeedSaveSettings = true;
TRX_Restart_Mode();
sendToDebug_strln("SWR too HIGH!");
LCD_showTooltip("SWR too HIGH!");
}
}
// restart USB if there is no activity (off) to find a new connection
if (TRX_Inited && ((USB_LastActiveTime + USB_RESTART_TIMEOUT < HAL_GetTick()))) // || (USB_LastActiveTime == 0)
USBD_Restart();
/* USER CODE END TIM6_DAC_IRQn 1 */
}
/**
* @brief This function handles TIM7 global interrupt.
*/
void TIM7_IRQHandler(void)
{
/* USER CODE BEGIN TIM7_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END TIM7_IRQn 0 */
HAL_TIM_IRQHandler(&htim7);
/* USER CODE BEGIN TIM7_IRQn 1 */
sendToDebug_flush(); // send data to debug from the buffer
// unmute after transition process end
if(TRX_Temporary_Mute_StartTime > 0 && (HAL_GetTick() - TRX_Temporary_Mute_StartTime) > 10)
{
WM8731_UnMute();
TRX_Temporary_Mute_StartTime = 0;
}
/* USER CODE END TIM7_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream1 global interrupt.
*/
void DMA2_Stream1_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream1_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DMA2_Stream1_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream1);
/* USER CODE BEGIN DMA2_Stream1_IRQn 1 */
/* USER CODE END DMA2_Stream1_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream2 global interrupt.
*/
void DMA2_Stream2_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream2_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DMA2_Stream2_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream2);
/* USER CODE BEGIN DMA2_Stream2_IRQn 1 */
/* USER CODE END DMA2_Stream2_IRQn 1 */
}
/**
* @brief This function handles USB On The Go FS global interrupt.
*/
void OTG_FS_IRQHandler(void)
{
/* USER CODE BEGIN OTG_FS_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END OTG_FS_IRQn 0 */
HAL_PCD_IRQHandler(&hpcd_USB_OTG_FS);
/* USER CODE BEGIN OTG_FS_IRQn 1 */
/* USER CODE END OTG_FS_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream5 global interrupt.
*/
void DMA2_Stream5_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream5_IRQn 0 */
/* USER CODE END DMA2_Stream5_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream5);
/* USER CODE BEGIN DMA2_Stream5_IRQn 1 */
FFT_afterPrintFFT();
/* USER CODE END DMA2_Stream5_IRQn 1 */
}
/**
* @brief This function handles DMA2 stream6 global interrupt.
*/
void DMA2_Stream6_IRQHandler(void)
{
/* USER CODE BEGIN DMA2_Stream6_IRQn 0 */
CPULOAD_WakeUp();
/* USER CODE END DMA2_Stream6_IRQn 0 */
HAL_DMA_IRQHandler(&hdma_memtomem_dma2_stream6);
/* USER CODE BEGIN DMA2_Stream6_IRQn 1 */
FFT_printWaterfallDMA(); // display the waterfall
/* USER CODE END DMA2_Stream6_IRQn 1 */
}
/* USER CODE BEGIN 1 */
void HAL_GPIO_EXTI_Callback(uint16_t GPIO_Pin)
{
CPULOAD_WakeUp();
if (GPIO_Pin == GPIO_PIN_10) //FPGA BUS
{
if(!WM8731_Buffer_underrun)
FPGA_fpgadata_iqclock(); // IQ data
FPGA_fpgadata_stuffclock(); // parameters and other services
}
else if (GPIO_Pin == GPIO_PIN_3) //Main encoder
{
if (TRX_Inited)
FRONTPANEL_ENCODER_checkRotate();
}
else if (GPIO_Pin == GPIO_PIN_2) //PTT
{
if (TRX_Inited && CurrentVFO()->Mode != TRX_MODE_NO_TX)
TRX_ptt_change();
}
else if (GPIO_Pin == GPIO_PIN_1) //KEY DOT
{
TRX_key_change();
}
else if (GPIO_Pin == GPIO_PIN_0) //KEY DASH
{
TRX_key_change();
}
else if (GPIO_Pin == GPIO_PIN_7) //POWER OFF
{
powerdown_start_delay = HAL_GetTick();
}
}
/* USER CODE END 1 */
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -1,201 +0,0 @@
#include "swr_analyzer.h"
#include "main.h"
#include "lcd_driver.h"
#include "trx_manager.h"
#include "functions.h"
#include "fpga.h"
#include "lcd.h"
#include "rf_unit.h"
//Private variables
static const uint16_t graph_start_x = 25;
static const uint16_t graph_width = LCD_WIDTH - 30;
static const uint16_t graph_start_y = 5;
static const uint16_t graph_height = LCD_HEIGHT - 25;
static float32_t now_freq;
static float32_t freq_step;
static uint16_t graph_sweep_x = 0;
static uint32_t tick_start_time = 0;
static int16_t graph_selected_x = (LCD_WIDTH - 30) / 2;
static float32_t data[LCD_WIDTH - 30] = {0};
static uint32_t startFreq = 0;
static uint32_t endFreq = 0;
//Saved variables
static uint32_t Lastfreq = 0;
static bool LastMute = false;
//Public variables
bool sysmenu_swr_opened = false;
//Prototypes
static void SWR_DrawBottomGUI(void); // display status at the bottom of the screen
static void SWR_DrawGraphCol(uint16_t x, bool clear); // display the data column
static uint16_t SWR_getYfromX(uint16_t x); // get height from data id
// prepare the spectrum analyzer
void SWR_Start(uint32_t start, uint32_t end)
{
LCD_busy = true;
startFreq = start;
endFreq = end;
//save settings
Lastfreq = CurrentVFO()->Freq;
LastMute = TRX_Mute;
// draw the GUI
LCDDriver_Fill(COLOR_BLACK);
LCDDriver_drawFastVLine(graph_start_x, graph_start_y, graph_height, COLOR_WHITE);
LCDDriver_drawFastHLine(graph_start_x, graph_start_y + graph_height, graph_width, COLOR_WHITE);
// horizontal labels
char ctmp[64] = {0};
sprintf(ctmp, "%u", (startFreq / 1000));
LCDDriver_printText(ctmp, graph_start_x + 2, graph_start_y + graph_height + 3, COLOR_GREEN, COLOR_BLACK, 1);
sprintf(ctmp, "%u", (endFreq / 1000));
LCDDriver_printText(ctmp, graph_start_x + graph_width - 36, graph_start_y + graph_height + 3, COLOR_GREEN, COLOR_BLACK, 1);
SWR_DrawBottomGUI();
// vertical labels
float32_t vres = SWR_TopSWR - 1.0f;
float32_t partsize = vres / (SWR_VParts - 1);
for (uint8_t n = 0; n < SWR_VParts; n++)
{
int32_t y = graph_start_y + (int32_t)(partsize * n * graph_height / vres);
sprintf(ctmp, "%.1f", (double)(SWR_TopSWR - partsize * n));
LCDDriver_printText(ctmp, 0, (uint16_t)y, COLOR_GREEN, COLOR_BLACK, 1);
LCDDriver_drawFastHLine(graph_start_x, (uint16_t)y, graph_width, COLOR_DGRAY);
}
// start scanning
TRX_setFrequency(startFreq, CurrentVFO());
TRX_Mute = true;
TRX_Tune = true;
TRX_ptt_hard = TRX_Tune;
TRX_Restart_Mode();
FPGA_NeedSendParams = true;
now_freq = startFreq;
freq_step = (endFreq - startFreq) / graph_width;
graph_sweep_x = 0;
tick_start_time = HAL_GetTick();
LCD_busy = false;
LCD_UpdateQuery.SystemMenu = true;
}
void SWR_Stop(void)
{
TRX_setFrequency(Lastfreq, CurrentVFO());
TRX_Mute = LastMute;
TRX_Tune = false;
TRX_ptt_hard = false;
TRX_ptt_soft = false;
TRX_Restart_Mode();
}
// draw the spectrum analyzer
void SWR_Draw(void)
{
if (LCD_busy)
return;
// Wait while data is being typed
if ((HAL_GetTick() - tick_start_time) < SWR_StepDelay)
{
LCD_UpdateQuery.SystemMenu = true;
return;
}
if (TRX_SWR == 0) //-V550
return;
tick_start_time = HAL_GetTick();
LCD_busy = true;
// Read the signal SWR
RF_UNIT_ProcessSensors();
// Draw
data[graph_sweep_x] = TRX_SWR;
SWR_DrawGraphCol(graph_sweep_x, true);
// draw a marker
if (graph_sweep_x == graph_selected_x)
SWR_DrawBottomGUI();
// Move on to calculating the next step
graph_sweep_x++;
if (now_freq > endFreq)
{
graph_sweep_x = 0;
now_freq = startFreq;
}
now_freq += freq_step;
TRX_setFrequency((uint32_t)now_freq, CurrentVFO());
FPGA_NeedSendParams = true;
LCD_busy = false;
}
// get height from data id
static uint16_t SWR_getYfromX(uint16_t x)
{
int32_t y = graph_start_y + (int32_t)((SWR_TopSWR - data[x]) * (float32_t)(graph_height) / (SWR_TopSWR - 1.0f));
if (y < graph_start_y)
y = graph_start_y;
if (y > ((graph_start_y + graph_height) - 1))
y = (graph_start_y + graph_height) - 1;
return (uint16_t)y;
}
// display the data column
static void SWR_DrawGraphCol(uint16_t x, bool clear)
{
if (x >= graph_width)
return;
if (clear)
{
// clear
LCDDriver_drawFastVLine((graph_start_x + x + 1), graph_start_y, graph_height, COLOR_BLACK);
// draw stripes behind the chart
int16_t vres = SWR_TopSWR;
for (uint8_t n = 0; n < (SWR_VParts - 1); n++)
LCDDriver_drawPixel((graph_start_x + x + 1), (uint16_t)(graph_start_y + ((vres / (SWR_VParts - 1)) * n * graph_height / vres)), COLOR_DGRAY);
}
// draw the graph
if (x > 0)
LCDDriver_drawLine((graph_start_x + x), SWR_getYfromX(x - 1), (graph_start_x + x + 1), SWR_getYfromX(x), COLOR_RED);
else
LCDDriver_drawPixel((graph_start_x + x + 1), SWR_getYfromX(x), COLOR_RED);
}
// display status at the bottom of the screen
static void SWR_DrawBottomGUI(void)
{
char ctmp[64] = {0};
int32_t freq = (int32_t)startFreq + ((int32_t)(endFreq - startFreq) / (graph_width - 1) * graph_selected_x);
sprintf(ctmp, "Freq=%dkHz SWR=%.1f", (freq / 1000), (double)data[graph_selected_x]);
LCDDriver_Fill_RectWH(170, graph_start_y + graph_height + 3, 200, 6, COLOR_BLACK);
LCDDriver_printText(ctmp, 170, graph_start_y + graph_height + 3, COLOR_GREEN, COLOR_BLACK, 1);
LCDDriver_drawFastVLine(graph_start_x + (uint16_t)graph_selected_x + 1, graph_start_y, graph_height, COLOR_GREEN);
}
// analyzer events to the encoder
void SWR_EncRotate(int8_t direction)
{
if(LCD_busy)
return;
LCD_busy = true;
// erase the old marker
SWR_DrawGraphCol((uint16_t)graph_selected_x, true);
if (direction < 0)
SWR_DrawGraphCol((uint16_t)graph_selected_x + 1, false);
// draw a new one
graph_selected_x += direction;
if (graph_selected_x < 0)
graph_selected_x = 0;
if (graph_selected_x > (graph_width - 1))
graph_selected_x = graph_width - 1;
SWR_DrawBottomGUI();
LCD_busy = false;
}

Wyświetl plik

@ -1,21 +0,0 @@
#ifndef SWR_ANALYZER_H
#define SWR_ANALYZER_H
#include "stm32f4xx.h"
#include "main.h"
#include "stdbool.h"
#define SWR_StepDelay 1 //scan delay, msec
#define SWR_VParts 6 //vertical signatures
#define SWR_TopSWR 10.0f
//Public variabled
extern bool sysmenu_swr_opened;
//Public methods
extern void SWR_Start(uint32_t start, uint32_t end); //analyzer launch
extern void SWR_Stop(void); //stop session
extern void SWR_Draw(void); //drawing analyzer
extern void SWR_EncRotate(int8_t direction); //analyzer events per encoder
#endif

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,53 +0,0 @@
#ifndef SYSTEM_MENU_H
#define SYSTEM_MENU_H
#include "stm32f4xx.h"
#include <stdbool.h>
typedef enum
{
SYSMENU_BOOLEAN = 0x01,
SYSMENU_RUN = 0x02,
SYSMENU_UINT8 = 0x03,
SYSMENU_UINT16 = 0x04,
SYSMENU_UINT32 = 0x05,
SYSMENU_UINT32R = 0x06,
SYSMENU_INT8 = 0x07,
SYSMENU_INT16 = 0x08,
SYSMENU_INT32 = 0x09,
SYSMENU_FLOAT32 = 0x0A,
SYSMENU_MENU = 0x0B,
SYSMENU_HIDDEN_MENU = 0x0C,
SYSMENU_INFOLINE = 0x0D,
} SystemMenuType;
struct sysmenu_item_handler
{
char *title;
SystemMenuType type;
uint32_t *value;
void (*menuHandler)(int8_t direction);
};
extern void SYSMENU_drawSystemMenu(bool draw_background);
extern void SYSMENU_redrawCurrentItem(void);
extern void eventRotateSystemMenu(int8_t direction);
extern void eventSecRotateSystemMenu(int8_t direction);
extern void eventCloseSystemMenu(void);
extern void eventCloseAllSystemMenu(void);
extern bool sysmenu_hiddenmenu_enabled;
extern void SYSMENU_TRX_RFPOWER_HOTKEY(void);
extern void SYSMENU_TRX_STEP_HOTKEY(void);
extern void SYSMENU_CW_WPM_HOTKEY(void);
extern void SYSMENU_CW_KEYER_HOTKEY(void);
extern void SYSMENU_AUDIO_VOLUME_HOTKEY(void);
extern void SYSMENU_AUDIO_BW_SSB_HOTKEY(void);
extern void SYSMENU_AUDIO_BW_CW_HOTKEY(void);
extern void SYSMENU_AUDIO_BW_AM_HOTKEY(void);
extern void SYSMENU_AUDIO_BW_FM_HOTKEY(void);
extern void SYSMENU_AUDIO_HPF_SSB_HOTKEY(void);
extern void SYSMENU_AUDIO_HPF_CW_HOTKEY(void);
extern void SYSMENU_AUDIO_SQUELCH_HOTKEY(void);
extern void SYSMENU_AUDIO_AGC_HOTKEY(void);
#endif

Wyświetl plik

@ -1,727 +0,0 @@
/**
******************************************************************************
* @file system_stm32f4xx.c
* @author MCD Application Team
* @brief CMSIS Cortex-M4 Device Peripheral Access Layer System Source File.
*
* This file provides two functions and one global variable to be called from
* user application:
* - SystemInit(): This function is called at startup just after reset and
* before branch to main program. This call is made inside
* the "startup_stm32f4xx.s" file.
*
* - SystemCoreClock variable: Contains the core clock (HCLK), it can be used
* by the user application to setup the SysTick
* timer or configure other parameters.
*
* - SystemCoreClockUpdate(): Updates the variable SystemCoreClock and must
* be called whenever the core clock is changed
* during program execution.
*
*
******************************************************************************
* @attention
*
* <h2><center>&copy; Copyright (c) 2017 STMicroelectronics.
* All rights reserved.</center></h2>
*
* This software component is licensed by ST under BSD 3-Clause license,
* the "License"; You may not use this file except in compliance with the
* License. You may obtain a copy of the License at:
* opensource.org/licenses/BSD-3-Clause
*
******************************************************************************
*/
/** @addtogroup CMSIS
* @{
*/
/** @addtogroup stm32f4xx_system
* @{
*/
/** @addtogroup STM32F4xx_System_Private_Includes
* @{
*/
#include "stm32f4xx.h"
#if !defined (HSE_VALUE)
#define HSE_VALUE ((uint32_t)25000000) /*!< Default value of the External oscillator in Hz */
#endif /* HSE_VALUE */
#if !defined (HSI_VALUE)
#define HSI_VALUE ((uint32_t)16000000) /*!< Value of the Internal oscillator in Hz*/
#endif /* HSI_VALUE */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_TypesDefinitions
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Defines
* @{
*/
/************************* Miscellaneous Configuration ************************/
/*!< Uncomment the following line if you need to use external SRAM or SDRAM as data memory */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
/* #define DATA_IN_ExtSRAM */
#endif /* STM32F40xxx || STM32F41xxx || STM32F42xxx || STM32F43xxx || STM32F469xx || STM32F479xx ||\
STM32F412Zx || STM32F412Vx */
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
/* #define DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx ||\
STM32F479xx */
/*!< Uncomment the following line if you need to relocate your vector Table in
Internal SRAM. */
/* #define VECT_TAB_SRAM */
#define VECT_TAB_OFFSET 0x00 /*!< Vector Table base offset field.
This value must be a multiple of 0x200. */
/******************************************************************************/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Macros
* @{
*/
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Variables
* @{
*/
/* This variable is updated in three ways:
1) by calling CMSIS function SystemCoreClockUpdate()
2) by calling HAL API function HAL_RCC_GetHCLKFreq()
3) each time HAL_RCC_ClockConfig() is called to configure the system clock frequency
Note: If you use this function to configure the system clock; then there
is no need to call the 2 first functions listed above, since SystemCoreClock
variable is updated automatically.
*/
uint32_t SystemCoreClock = 16000000;
const uint8_t AHBPrescTable[16] = {0, 0, 0, 0, 0, 0, 0, 0, 1, 2, 3, 4, 6, 7, 8, 9};
const uint8_t APBPrescTable[8] = {0, 0, 0, 0, 1, 2, 3, 4};
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_FunctionPrototypes
* @{
*/
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
static void SystemInit_ExtMemCtl(void);
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/**
* @}
*/
/** @addtogroup STM32F4xx_System_Private_Functions
* @{
*/
/**
* @brief Setup the microcontroller system
* Initialize the FPU setting, vector table location and External memory
* configuration.
* @param None
* @retval None
*/
void SystemInit(void)
{
/* FPU settings ------------------------------------------------------------*/
#if (__FPU_PRESENT == 1) && (__FPU_USED == 1)
SCB->CPACR |= ((3UL << 10*2)|(3UL << 11*2)); /* set CP10 and CP11 Full Access */
#endif
#if defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
SystemInit_ExtMemCtl();
#endif /* DATA_IN_ExtSRAM || DATA_IN_ExtSDRAM */
/* Configure the Vector Table location add offset address ------------------*/
#ifdef VECT_TAB_SRAM
SCB->VTOR = SRAM_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal SRAM */
#else
SCB->VTOR = FLASH_BASE | VECT_TAB_OFFSET; /* Vector Table Relocation in Internal FLASH */
#endif
}
/**
* @brief Update SystemCoreClock variable according to Clock Register Values.
* The SystemCoreClock variable contains the core clock (HCLK), it can
* be used by the user application to setup the SysTick timer or configure
* other parameters.
*
* @note Each time the core clock (HCLK) changes, this function must be called
* to update SystemCoreClock variable value. Otherwise, any configuration
* based on this variable will be incorrect.
*
* @note - The system frequency computed by this function is not the real
* frequency in the chip. It is calculated based on the predefined
* constant and the selected clock source:
*
* - If SYSCLK source is HSI, SystemCoreClock will contain the HSI_VALUE(*)
*
* - If SYSCLK source is HSE, SystemCoreClock will contain the HSE_VALUE(**)
*
* - If SYSCLK source is PLL, SystemCoreClock will contain the HSE_VALUE(**)
* or HSI_VALUE(*) multiplied/divided by the PLL factors.
*
* (*) HSI_VALUE is a constant defined in stm32f4xx_hal_conf.h file (default value
* 16 MHz) but the real value may vary depending on the variations
* in voltage and temperature.
*
* (**) HSE_VALUE is a constant defined in stm32f4xx_hal_conf.h file (its value
* depends on the application requirements), user has to ensure that HSE_VALUE
* is same as the real frequency of the crystal used. Otherwise, this function
* may have wrong result.
*
* - The result of this function could be not correct when using fractional
* value for HSE crystal.
*
* @param None
* @retval None
*/
void SystemCoreClockUpdate(void)
{
uint32_t tmp = 0, pllvco = 0, pllp = 2, pllsource = 0, pllm = 2;
/* Get SYSCLK source -------------------------------------------------------*/
tmp = RCC->CFGR & RCC_CFGR_SWS;
switch (tmp)
{
case 0x00: /* HSI used as system clock source */
SystemCoreClock = HSI_VALUE;
break;
case 0x04: /* HSE used as system clock source */
SystemCoreClock = HSE_VALUE;
break;
case 0x08: /* PLL used as system clock source */
/* PLL_VCO = (HSE_VALUE or HSI_VALUE / PLL_M) * PLL_N
SYSCLK = PLL_VCO / PLL_P
*/
pllsource = (RCC->PLLCFGR & RCC_PLLCFGR_PLLSRC) >> 22;
pllm = RCC->PLLCFGR & RCC_PLLCFGR_PLLM;
if (pllsource != 0)
{
/* HSE used as PLL clock source */
pllvco = (HSE_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
else
{
/* HSI used as PLL clock source */
pllvco = (HSI_VALUE / pllm) * ((RCC->PLLCFGR & RCC_PLLCFGR_PLLN) >> 6);
}
pllp = (((RCC->PLLCFGR & RCC_PLLCFGR_PLLP) >>16) + 1 ) *2;
SystemCoreClock = pllvco/pllp;
break;
default:
SystemCoreClock = HSI_VALUE;
break;
}
/* Compute HCLK frequency --------------------------------------------------*/
/* Get HCLK prescaler */
tmp = AHBPrescTable[((RCC->CFGR & RCC_CFGR_HPRE) >> 4)];
/* HCLK frequency */
SystemCoreClock >>= tmp;
}
#if defined (DATA_IN_ExtSRAM) && defined (DATA_IN_ExtSDRAM)
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmp = 0x00;
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface clock */
RCC->AHB1ENR |= 0x000001F8;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
/*-- FMC Configuration -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
FMC_Bank5_6->SDCR[0] = 0x000019E4;
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<1000; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
FMC_Bank5_6->SDCMR = 0x00000073;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
FMC_Bank5_6->SDCMR = 0x00046014;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
(void)(tmp);
}
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
#elif defined (DATA_IN_ExtSRAM) || defined (DATA_IN_ExtSDRAM)
/**
* @brief Setup the external memory controller.
* Called in startup_stm32f4xx.s before jump to main.
* This function configures the external memories (SRAM/SDRAM)
* This SRAM/SDRAM will be used as program data memory (including heap and stack).
* @param None
* @retval None
*/
void SystemInit_ExtMemCtl(void)
{
__IO uint32_t tmp = 0x00;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F446xx) || defined(STM32F469xx) || defined(STM32F479xx)
#if defined (DATA_IN_ExtSDRAM)
register uint32_t tmpreg = 0, timeout = 0xFFFF;
register __IO uint32_t index;
#if defined(STM32F446xx)
/* Enable GPIOA, GPIOC, GPIOD, GPIOE, GPIOF, GPIOG interface
clock */
RCC->AHB1ENR |= 0x0000007D;
#else
/* Enable GPIOC, GPIOD, GPIOE, GPIOF, GPIOG, GPIOH and GPIOI interface
clock */
RCC->AHB1ENR |= 0x000001F8;
#endif /* STM32F446xx */
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIOCEN);
#if defined(STM32F446xx)
/* Connect PAx pins to FMC Alternate function */
GPIOA->AFR[0] |= 0xC0000000;
GPIOA->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOA->MODER |= 0x00008000;
/* Configure PDx pins speed to 50 MHz */
GPIOA->OSPEEDR |= 0x00008000;
/* Configure PDx pins Output type to push-pull */
GPIOA->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOA->PUPDR |= 0x00000000;
/* Connect PCx pins to FMC Alternate function */
GPIOC->AFR[0] |= 0x00CC0000;
GPIOC->AFR[1] |= 0x00000000;
/* Configure PDx pins in Alternate function mode */
GPIOC->MODER |= 0x00000A00;
/* Configure PDx pins speed to 50 MHz */
GPIOC->OSPEEDR |= 0x00000A00;
/* Configure PDx pins Output type to push-pull */
GPIOC->OTYPER |= 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOC->PUPDR |= 0x00000000;
#endif /* STM32F446xx */
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x000000CC;
GPIOD->AFR[1] = 0xCC000CCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xA02A000A;
/* Configure PDx pins speed to 50 MHz */
GPIOD->OSPEEDR = 0xA02A000A;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00000CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA800A;
/* Configure PEx pins speed to 50 MHz */
GPIOE->OSPEEDR = 0xAAAA800A;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0xCCCCCCCC;
GPIOF->AFR[1] = 0xCCCCCCCC;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA800AAA;
/* Configure PFx pins speed to 50 MHz */
GPIOF->OSPEEDR = 0xAA800AAA;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0xCCCCCCCC;
GPIOG->AFR[1] = 0xCCCCCCCC;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0xAAAAAAAA;
/* Configure PGx pins speed to 50 MHz */
GPIOG->OSPEEDR = 0xAAAAAAAA;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx)
/* Connect PHx pins to FMC Alternate function */
GPIOH->AFR[0] = 0x00C0CC00;
GPIOH->AFR[1] = 0xCCCCCCCC;
/* Configure PHx pins in Alternate function mode */
GPIOH->MODER = 0xAAAA08A0;
/* Configure PHx pins speed to 50 MHz */
GPIOH->OSPEEDR = 0xAAAA08A0;
/* Configure PHx pins Output type to push-pull */
GPIOH->OTYPER = 0x00000000;
/* No pull-up, pull-down for PHx pins */
GPIOH->PUPDR = 0x00000000;
/* Connect PIx pins to FMC Alternate function */
GPIOI->AFR[0] = 0xCCCCCCCC;
GPIOI->AFR[1] = 0x00000CC0;
/* Configure PIx pins in Alternate function mode */
GPIOI->MODER = 0x0028AAAA;
/* Configure PIx pins speed to 50 MHz */
GPIOI->OSPEEDR = 0x0028AAAA;
/* Configure PIx pins Output type to push-pull */
GPIOI->OTYPER = 0x00000000;
/* No pull-up, pull-down for PIx pins */
GPIOI->PUPDR = 0x00000000;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx */
/*-- FMC Configuration -------------------------------------------------------*/
/* Enable the FMC interface clock */
RCC->AHB3ENR |= 0x00000001;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable SDRAM bank1 */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCR[0] = 0x00001954;
#else
FMC_Bank5_6->SDCR[0] = 0x000019E4;
#endif /* STM32F446xx */
FMC_Bank5_6->SDTR[0] = 0x01115351;
/* SDRAM initialization sequence */
/* Clock enable command */
FMC_Bank5_6->SDCMR = 0x00000011;
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Delay */
for (index = 0; index<1000; index++);
/* PALL command */
FMC_Bank5_6->SDCMR = 0x00000012;
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Auto refresh command */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x000000F3;
#else
FMC_Bank5_6->SDCMR = 0x00000073;
#endif /* STM32F446xx */
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* MRD register program */
#if defined(STM32F446xx)
FMC_Bank5_6->SDCMR = 0x00044014;
#else
FMC_Bank5_6->SDCMR = 0x00046014;
#endif /* STM32F446xx */
timeout = 0xFFFF;
while((tmpreg != 0) && (timeout-- > 0))
{
tmpreg = FMC_Bank5_6->SDSR & 0x00000020;
}
/* Set refresh count */
tmpreg = FMC_Bank5_6->SDRTR;
#if defined(STM32F446xx)
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000050C<<1));
#else
FMC_Bank5_6->SDRTR = (tmpreg | (0x0000027C<<1));
#endif /* STM32F446xx */
/* Disable write protection */
tmpreg = FMC_Bank5_6->SDCR[0];
FMC_Bank5_6->SDCR[0] = (tmpreg & 0xFFFFFDFF);
#endif /* DATA_IN_ExtSDRAM */
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx || STM32F446xx || STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx) || defined(STM32F417xx)\
|| defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)\
|| defined(STM32F469xx) || defined(STM32F479xx) || defined(STM32F412Zx) || defined(STM32F412Vx)
#if defined(DATA_IN_ExtSRAM)
/*-- GPIOs Configuration -----------------------------------------------------*/
/* Enable GPIOD, GPIOE, GPIOF and GPIOG interface clock */
RCC->AHB1ENR |= 0x00000078;
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB1ENR, RCC_AHB1ENR_GPIODEN);
/* Connect PDx pins to FMC Alternate function */
GPIOD->AFR[0] = 0x00CCC0CC;
GPIOD->AFR[1] = 0xCCCCCCCC;
/* Configure PDx pins in Alternate function mode */
GPIOD->MODER = 0xAAAA0A8A;
/* Configure PDx pins speed to 100 MHz */
GPIOD->OSPEEDR = 0xFFFF0FCF;
/* Configure PDx pins Output type to push-pull */
GPIOD->OTYPER = 0x00000000;
/* No pull-up, pull-down for PDx pins */
GPIOD->PUPDR = 0x00000000;
/* Connect PEx pins to FMC Alternate function */
GPIOE->AFR[0] = 0xC00CC0CC;
GPIOE->AFR[1] = 0xCCCCCCCC;
/* Configure PEx pins in Alternate function mode */
GPIOE->MODER = 0xAAAA828A;
/* Configure PEx pins speed to 100 MHz */
GPIOE->OSPEEDR = 0xFFFFC3CF;
/* Configure PEx pins Output type to push-pull */
GPIOE->OTYPER = 0x00000000;
/* No pull-up, pull-down for PEx pins */
GPIOE->PUPDR = 0x00000000;
/* Connect PFx pins to FMC Alternate function */
GPIOF->AFR[0] = 0x00CCCCCC;
GPIOF->AFR[1] = 0xCCCC0000;
/* Configure PFx pins in Alternate function mode */
GPIOF->MODER = 0xAA000AAA;
/* Configure PFx pins speed to 100 MHz */
GPIOF->OSPEEDR = 0xFF000FFF;
/* Configure PFx pins Output type to push-pull */
GPIOF->OTYPER = 0x00000000;
/* No pull-up, pull-down for PFx pins */
GPIOF->PUPDR = 0x00000000;
/* Connect PGx pins to FMC Alternate function */
GPIOG->AFR[0] = 0x00CCCCCC;
GPIOG->AFR[1] = 0x000000C0;
/* Configure PGx pins in Alternate function mode */
GPIOG->MODER = 0x00085AAA;
/* Configure PGx pins speed to 100 MHz */
GPIOG->OSPEEDR = 0x000CAFFF;
/* Configure PGx pins Output type to push-pull */
GPIOG->OTYPER = 0x00000000;
/* No pull-up, pull-down for PGx pins */
GPIOG->PUPDR = 0x00000000;
/*-- FMC/FSMC Configuration --------------------------------------------------*/
/* Enable the FMC/FSMC interface clock */
RCC->AHB3ENR |= 0x00000001;
#if defined(STM32F427xx) || defined(STM32F437xx) || defined(STM32F429xx) || defined(STM32F439xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001011;
FMC_Bank1->BTCR[3] = 0x00000201;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F427xx || STM32F437xx || STM32F429xx || STM32F439xx */
#if defined(STM32F469xx) || defined(STM32F479xx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FMCEN);
/* Configure and enable Bank1_SRAM2 */
FMC_Bank1->BTCR[2] = 0x00001091;
FMC_Bank1->BTCR[3] = 0x00110212;
FMC_Bank1E->BWTR[2] = 0x0fffffff;
#endif /* STM32F469xx || STM32F479xx */
#if defined(STM32F405xx) || defined(STM32F415xx) || defined(STM32F407xx)|| defined(STM32F417xx)\
|| defined(STM32F412Zx) || defined(STM32F412Vx)
/* Delay after an RCC peripheral clock enabling */
tmp = READ_BIT(RCC->AHB3ENR, RCC_AHB3ENR_FSMCEN);
/* Configure and enable Bank1_SRAM2 */
FSMC_Bank1->BTCR[2] = 0x00001011;
FSMC_Bank1->BTCR[3] = 0x00000201;
FSMC_Bank1E->BWTR[2] = 0x0FFFFFFF;
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F412Zx || STM32F412Vx */
#endif /* DATA_IN_ExtSRAM */
#endif /* STM32F405xx || STM32F415xx || STM32F407xx || STM32F417xx || STM32F427xx || STM32F437xx ||\
STM32F429xx || STM32F439xx || STM32F469xx || STM32F479xx || STM32F412Zx || STM32F412Vx */
(void)(tmp);
}
#endif /* DATA_IN_ExtSRAM && DATA_IN_ExtSDRAM */
/**
* @}
*/
/**
* @}
*/
/**
* @}
*/
/************************ (C) COPYRIGHT STMicroelectronics *****END OF FILE****/

Wyświetl plik

@ -1,537 +0,0 @@
#include "stm32f4xx_hal.h"
#include "main.h"
#include "trx_manager.h"
#include "functions.h"
#include "lcd.h"
#include "fpga.h"
#include "settings.h"
#include "wm8731.h"
#include "fpga.h"
#include "bands.h"
#include "agc.h"
#include "audio_filters.h"
#include "usbd_audio_if.h"
#include "front_unit.h"
#include "rf_unit.h"
#include "system_menu.h"
volatile bool TRX_ptt_hard = false;
volatile bool TRX_ptt_soft = false;
volatile bool TRX_old_ptt_soft = false;
volatile bool TRX_key_serial = false;
volatile bool TRX_old_key_serial = false;
volatile bool TRX_key_dot_hard = false;
volatile bool TRX_key_dash_hard = false;
volatile uint_fast16_t TRX_Key_Timeout_est = 0;
volatile bool TRX_RX_IQ_swap = false;
volatile bool TRX_TX_IQ_swap = false;
volatile bool TRX_Tune = false;
volatile bool TRX_Inited = false;
volatile int_fast16_t TRX_RX_dBm = -100;
volatile bool TRX_ADC_OTR = false;
volatile bool TRX_DAC_OTR = false;
volatile int16_t TRX_ADC_MINAMPLITUDE = 0;
volatile int16_t TRX_ADC_MAXAMPLITUDE = 0;
volatile uint32_t TRX_SNTP_Synced = 0; // time of the last time synchronization
volatile int_fast16_t TRX_SHIFT = 0;
volatile float32_t TRX_MAX_TX_Amplitude = MAX_TX_AMPLITUDE;
volatile float32_t TRX_PWR_Forward = 0;
volatile float32_t TRX_PWR_Backward = 0;
volatile float32_t TRX_SWR = 0;
volatile float32_t TRX_ALC = 0;
static uint_fast8_t autogain_wait_reaction = 0; // timer for waiting for a reaction from changing the ATT / PRE modes
volatile uint8_t TRX_AutoGain_Stage = 0; // stage of working out the amplification corrector
static uint32_t KEYER_symbol_start_time = 0; // start time of the automatic key character
static uint_fast8_t KEYER_symbol_status = 0; // status (signal or period) of the automatic key symbol
volatile float32_t TRX_IQ_phase_error = 0.0f;
volatile bool TRX_NeedGoToBootloader = false;
volatile bool TRX_Temporary_Stop_BandMap = false;
volatile bool TRX_Mute = false;
volatile uint32_t TRX_Temporary_Mute_StartTime = 0;
uint32_t TRX_freq_phrase = 0;
uint32_t TRX_freq_phrase_tx = 0;
float32_t TRX_InVoltage = 12.0f;
static uint_fast8_t TRX_TXRXMode = 0; //0 - undef, 1 - rx, 2 - tx, 3 - txrx
static void TRX_Start_RX(void);
static void TRX_Start_TX(void);
static void TRX_Start_TXRX(void);
bool TRX_on_TX(void)
{
if (TRX_ptt_hard || TRX_ptt_soft || TRX_Tune || CurrentVFO()->Mode == TRX_MODE_LOOPBACK || TRX_Key_Timeout_est > 0)
return true;
return false;
}
void TRX_Init()
{
TRX_Start_RX();
uint_fast8_t saved_mode = CurrentVFO()->Mode;
TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO());
TRX_setMode(saved_mode, CurrentVFO());
HAL_ADCEx_InjectedStart(&hadc1);
HAL_ADCEx_InjectedStart(&hadc2);
}
void TRX_Restart_Mode()
{
uint_fast8_t mode = CurrentVFO()->Mode;
//CLAR
if (TRX.CLAR)
{
TRX.current_vfo = !TRX.current_vfo;
TRX_setFrequency(CurrentVFO()->Freq, CurrentVFO());
TRX_setMode(CurrentVFO()->Mode, CurrentVFO());
LCD_UpdateQuery.FreqInfo = true;
LCD_UpdateQuery.TopButtons = true;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
}
//
if (TRX_on_TX())
{
if (mode == TRX_MODE_LOOPBACK || mode == TRX_MODE_CW_L || mode == TRX_MODE_CW_U)
TRX_Start_TXRX();
else
TRX_Start_TX();
}
else
{
TRX_Start_RX();
}
FFT_Reset();
}
static void TRX_Start_RX()
{
if (TRX_TXRXMode == 1)
return;
//sendToDebug_str("RX MODE\r\n");
WM8731_CleanBuffer();
Processor_NeedRXBuffer = false;
WM8731_Buffer_underrun = false;
WM8731_DMA_state = true;
WM8731_RX_mode();
WM8731_start_i2s_and_dma();
TRX_TXRXMode = 1;
//clean TX buffer
memset((void *)&FPGA_Audio_SendBuffer_Q[0], 0x00, sizeof(FPGA_Audio_SendBuffer_Q));
memset((void *)&FPGA_Audio_SendBuffer_I[0], 0x00, sizeof(FPGA_Audio_SendBuffer_I));
}
static void TRX_Start_TX()
{
if (TRX_TXRXMode == 2)
return;
//sendToDebug_str("TX MODE\r\n");
WM8731_CleanBuffer();
HAL_Delay(10); // delay before the RF signal is applied, so that the relay has time to trigger
WM8731_TX_mode();
WM8731_start_i2s_and_dma();
TRX_TXRXMode = 2;
}
static void TRX_Start_TXRX()
{
if (TRX_TXRXMode == 3)
return;
//sendToDebug_str("TXRX MODE\r\n");
WM8731_CleanBuffer();
WM8731_TXRX_mode();
WM8731_start_i2s_and_dma();
TRX_TXRXMode = 3;
}
void TRX_ptt_change(void)
{
if (TRX_Tune)
return;
bool TRX_new_ptt_hard = !HAL_GPIO_ReadPin(PTT_IN_GPIO_Port, PTT_IN_Pin);
if (TRX_ptt_hard != TRX_new_ptt_hard)
{
TRX_ptt_hard = TRX_new_ptt_hard;
TRX_ptt_soft = false;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
if (TRX_ptt_soft != TRX_old_ptt_soft)
{
TRX_old_ptt_soft = TRX_ptt_soft;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
void TRX_key_change(void)
{
if (TRX_Tune)
return;
if (CurrentVFO()->Mode != TRX_MODE_CW_L && CurrentVFO()->Mode != TRX_MODE_CW_U)
return;
bool TRX_new_key_dot_hard = !HAL_GPIO_ReadPin(KEY_IN_DOT_GPIO_Port, KEY_IN_DOT_Pin);
if (TRX_key_dot_hard != TRX_new_key_dot_hard)
{
TRX_key_dot_hard = TRX_new_key_dot_hard;
if (TRX_key_dot_hard == true && (KEYER_symbol_status == 0 || !TRX.CW_KEYER))
{
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
bool TRX_new_key_dash_hard = !HAL_GPIO_ReadPin(KEY_IN_DASH_GPIO_Port, KEY_IN_DASH_Pin);
if (TRX_key_dash_hard != TRX_new_key_dash_hard)
{
TRX_key_dash_hard = TRX_new_key_dash_hard;
if (TRX_key_dash_hard == true && (KEYER_symbol_status == 0 || !TRX.CW_KEYER))
{
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
if (TRX_key_serial != TRX_old_key_serial)
{
TRX_old_key_serial = TRX_key_serial;
if (TRX_key_serial == true)
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
LCD_UpdateQuery.StatusInfoGUIRedraw = true;
FPGA_NeedSendParams = true;
TRX_Restart_Mode();
}
}
void TRX_setFrequency(uint32_t _freq, VFO *vfo)
{
if (_freq < 1)
return;
if (_freq >= MAX_RX_FREQ_HZ)
_freq = MAX_RX_FREQ_HZ;
vfo->Freq = _freq;
//get band
int_fast8_t bandFromFreq = getBandFromFreq(_freq, false);
if (bandFromFreq >= 0)
{
TRX.BANDS_SAVED_SETTINGS[bandFromFreq].Freq = _freq;
}
if (TRX.BandMapEnabled && !TRX_Temporary_Stop_BandMap)
{
uint_fast8_t mode_from_bandmap = getModeFromFreq(vfo->Freq);
if (vfo->Mode != mode_from_bandmap)
{
TRX_setMode(mode_from_bandmap, vfo);
TRX.BANDS_SAVED_SETTINGS[bandFromFreq].Mode = mode_from_bandmap;
LCD_UpdateQuery.TopButtons = true;
}
}
//get fpga freq phrase
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);
if (!TRX_on_TX())
{
switch (current_vfo->Mode)
{
case TRX_MODE_CW_L:
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq - TRX.CW_GENERATOR_SHIFT_HZ);
break;
case TRX_MODE_CW_U:
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq + TRX.CW_GENERATOR_SHIFT_HZ);
break;
default:
TRX_freq_phrase_tx = getTXPhraseFromFrequency((int32_t)current_vfo->Freq);
break;
}
}
//
TRX_MAX_TX_Amplitude = getMaxTXAmplitudeOnFreq(vfo->Freq);
FPGA_NeedSendParams = true;
}
void TRX_setMode(uint_fast8_t _mode, VFO *vfo)
{
if (vfo->Mode == TRX_MODE_LOOPBACK || _mode == TRX_MODE_LOOPBACK)
LCD_UpdateQuery.StatusInfoGUI = true;
vfo->Mode = _mode;
if (vfo->Mode == TRX_MODE_LOOPBACK)
TRX_Start_TXRX();
switch (_mode)
{
case TRX_MODE_AM:
vfo->LPF_Filter_Width = TRX.AM_LPF_Filter;
vfo->HPF_Filter_Width = 0;
break;
case TRX_MODE_LSB:
case TRX_MODE_USB:
case TRX_MODE_DIGI_L:
case TRX_MODE_DIGI_U:
vfo->LPF_Filter_Width = TRX.SSB_LPF_Filter;
vfo->HPF_Filter_Width = TRX.SSB_HPF_Filter;
break;
case TRX_MODE_CW_L:
case TRX_MODE_CW_U:
vfo->LPF_Filter_Width = TRX.CW_LPF_Filter;
vfo->HPF_Filter_Width = TRX.CW_HPF_Filter;
LCD_UpdateQuery.StatusInfoGUI = true;
break;
case TRX_MODE_NFM:
vfo->LPF_Filter_Width = TRX.FM_LPF_Filter;
vfo->HPF_Filter_Width = 0;
break;
case TRX_MODE_WFM:
vfo->LPF_Filter_Width = 0;
vfo->HPF_Filter_Width = 0;
break;
}
NeedReinitAudioFilters = true;
NeedSaveSettings = true;
LCD_UpdateQuery.StatusInfoBar = true;
LCD_UpdateQuery.StatusInfoGUI = true;
}
void TRX_DoAutoGain(void)
{
#define SKIP_CYCLES_DOWNSTAGE 10 //skip cycles on stage downgrade
static uint8_t skip_cycles = 0;
//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)
{
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)
{
TRX.BANDS_SAVED_SETTINGS[band].ATT = TRX.ATT;
TRX.BANDS_SAVED_SETTINGS[band].ADC_Driver = TRX.ADC_Driver;
TRX.BANDS_SAVED_SETTINGS[band].AutoGain_Stage = TRX_AutoGain_Stage;
}
}
}
void TRX_DBMCalculate(void)
{
if(Processor_RX_Power_value == 0)
return;
float32_t adc_volts = Processor_RX_Power_value * (ADC_RANGE / 2.0f);
if(adc_volts > 0.0f)
{
TRX_RX_dBm = (int16_t)(10.0f * log10f_fast((adc_volts * adc_volts / ADC_INPUT_IMPEDANCE) / 0.001f));
TRX_RX_dBm += CALIBRATE.smeter_calibration;
}
Processor_RX_Power_value = 0;
}
float32_t current_cw_power = 0.0f;
static float32_t TRX_generateRiseSignal(float32_t power)
{
if(current_cw_power < power)
current_cw_power += power * 0.01f;
if(current_cw_power > power)
current_cw_power = power;
return current_cw_power;
}
static float32_t TRX_generateFallSignal(float32_t power)
{
if(current_cw_power > 0.0f)
current_cw_power -= power * 0.01f;
if(current_cw_power < 0.0f)
current_cw_power = 0.0f;
return current_cw_power;
}
float32_t TRX_GenerateCWSignal(float32_t power)
{
if (!TRX.CW_KEYER)
{
if (!TRX_key_serial && !TRX_ptt_hard && !TRX_key_dot_hard && !TRX_key_dash_hard)
return TRX_generateFallSignal(power);
return TRX_generateRiseSignal(power);
}
uint32_t dot_length_ms = 1200 / TRX.CW_KEYER_WPM;
uint32_t dash_length_ms = dot_length_ms * 3;
uint32_t sim_space_length_ms = dot_length_ms;
uint32_t curTime = HAL_GetTick();
//dot
if (KEYER_symbol_status == 0 && TRX_key_dot_hard)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 1;
}
if (KEYER_symbol_status == 1 && (KEYER_symbol_start_time + dot_length_ms) > curTime)
{
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
return TRX_generateRiseSignal(power);
}
if (KEYER_symbol_status == 1 && (KEYER_symbol_start_time + dot_length_ms) < curTime)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 3;
}
//dash
if (KEYER_symbol_status == 0 && TRX_key_dash_hard)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 2;
}
if (KEYER_symbol_status == 2 && (KEYER_symbol_start_time + dash_length_ms) > curTime)
{
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
return TRX_generateRiseSignal(power);
}
if (KEYER_symbol_status == 2 && (KEYER_symbol_start_time + dash_length_ms) < curTime)
{
KEYER_symbol_start_time = curTime;
KEYER_symbol_status = 3;
}
//space
if (KEYER_symbol_status == 3 && (KEYER_symbol_start_time + sim_space_length_ms) > curTime)
{
TRX_Key_Timeout_est = TRX.CW_Key_timeout;
return TRX_generateFallSignal(power);
}
if (KEYER_symbol_status == 3 && (KEYER_symbol_start_time + sim_space_length_ms) < curTime)
{
KEYER_symbol_status = 0;
}
return TRX_generateFallSignal(power);
}
void TRX_TemporaryMute(void)
{
WM8731_Mute();
TRX_Temporary_Mute_StartTime = HAL_GetTick();
}

Wyświetl plik

@ -1,54 +0,0 @@
#ifndef TRX_MANAGER_H
#define TRX_MANAGER_H
#include "stm32f4xx_hal.h"
#include <stdbool.h>
#include "settings.h"
extern void TRX_Init(void);
extern void TRX_setFrequency(uint32_t _freq, VFO *vfo);
extern void TRX_setMode(uint_fast8_t _mode, VFO *vfo);
extern void TRX_ptt_change(void);
extern void TRX_key_change(void);
extern bool TRX_on_TX(void);
extern void TRX_DoAutoGain(void);
extern void TRX_Restart_Mode(void);
extern void TRX_DBMCalculate(void);
extern float32_t TRX_GenerateCWSignal(float32_t power);
extern void TRX_TemporaryMute(void);
volatile extern bool TRX_ptt_hard;
volatile extern bool TRX_ptt_soft;
volatile extern bool TRX_old_ptt_soft;
volatile extern bool TRX_key_serial;
volatile extern bool TRX_old_key_serial;
volatile extern bool TRX_key_dot_hard;
volatile extern bool TRX_key_dash_hard;
volatile extern uint_fast16_t TRX_Key_Timeout_est;
volatile extern bool TRX_RX_IQ_swap;
volatile extern bool TRX_TX_IQ_swap;
volatile extern bool TRX_Tune;
volatile extern bool TRX_Inited;
volatile extern int_fast16_t TRX_RX_dBm;
volatile extern bool TRX_ADC_OTR;
volatile extern bool TRX_DAC_OTR;
volatile extern int16_t TRX_ADC_MINAMPLITUDE;
volatile extern int16_t TRX_ADC_MAXAMPLITUDE;
volatile extern int_fast16_t TRX_SHIFT;
volatile extern float32_t TRX_MAX_TX_Amplitude;
volatile extern float32_t TRX_PWR_Forward;
volatile extern float32_t TRX_PWR_Backward;
volatile extern float32_t TRX_SWR;
volatile extern float32_t TRX_ALC;
volatile extern bool TRX_Mute;
volatile extern float32_t TRX_IQ_phase_error;
volatile extern bool TRX_NeedGoToBootloader;
volatile extern bool TRX_Temporary_Stop_BandMap;
volatile extern uint8_t TRX_AutoGain_Stage;
extern const char *MODE_DESCR[];
extern uint32_t TRX_freq_phrase;
extern uint32_t TRX_freq_phrase_tx;
volatile extern uint32_t TRX_Temporary_Mute_StartTime;
extern float32_t TRX_InVoltage;
#endif

Wyświetl plik

@ -1,64 +0,0 @@
#include "usbd_audio_if.h"
#include "functions.h"
#include "wm8731.h"
#include "trx_manager.h"
extern USBD_HandleTypeDef hUsbDeviceFS;
static int8_t AUDIO_Init_FS(void);
static int8_t AUDIO_DeInit_FS(void);
IRAM1 uint8_t USB_AUDIO_rx_buffer_a[USB_AUDIO_RX_BUFFER_SIZE] = {0};
IRAM1 uint8_t USB_AUDIO_rx_buffer_b[USB_AUDIO_RX_BUFFER_SIZE] = {0};
IRAM1 uint8_t USB_AUDIO_tx_buffer[USB_AUDIO_TX_BUFFER_SIZE] = {0};
volatile bool USB_AUDIO_current_rx_buffer = false; // a-false b-true
volatile bool USB_AUDIO_need_rx_buffer = false; // a-false b-true
static bool USB_AUDIO_Inited = false;
USBD_AUDIO_ItfTypeDef USBD_AUDIO_fops_FS =
{
AUDIO_Init_FS,
AUDIO_DeInit_FS,
};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the AUDIO media low layer over USB FS IP
* @param AudioFreq: Audio frequency used to play the audio stream.
* @param Volume: Initial volume level (from 0 (Mute) to 100 (Max))
* @param options: Reserved for future use
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_Init_FS(void)
{
USBD_AUDIO_HandleTypeDef *haudio = (USBD_AUDIO_HandleTypeDef *)hUsbDeviceFS.pClassDataAUDIO;
haudio->RxBuffer = (uint8_t *)&USB_AUDIO_rx_buffer_a;
haudio->TxBuffer = (uint8_t *)&USB_AUDIO_tx_buffer;
haudio->TxBufferIndex = 0;
USBD_AUDIO_StartTransmit(&hUsbDeviceFS);
USBD_AUDIO_StartReceive(&hUsbDeviceFS);
USB_AUDIO_Inited = true;
return (USBD_OK);
}
uint32_t USB_AUDIO_GetTXBufferIndex_FS(void)
{
if (!USB_AUDIO_Inited)
return 0;
USBD_AUDIO_HandleTypeDef *haudio = (USBD_AUDIO_HandleTypeDef *)hUsbDeviceFS.pClassDataAUDIO;
return haudio->TxBufferIndex;
}
/**
* @brief De-Initializes the AUDIO media low layer
* @param options: Reserved for future use
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t AUDIO_DeInit_FS(void)
{
/* USER CODE BEGIN 1 */
return (USBD_OK);
/* USER CODE END 1 */
}

Wyświetl plik

@ -1,27 +0,0 @@
#ifndef __USBD_AUDIO_IF_H__
#define __USBD_AUDIO_IF_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "usbd_ua3reo.h"
#include "functions.h"
extern USBD_AUDIO_ItfTypeDef USBD_AUDIO_fops_FS;
extern uint8_t USB_AUDIO_rx_buffer_a[USB_AUDIO_RX_BUFFER_SIZE];
extern uint8_t USB_AUDIO_rx_buffer_b[USB_AUDIO_RX_BUFFER_SIZE];
extern uint8_t USB_AUDIO_tx_buffer[USB_AUDIO_TX_BUFFER_SIZE];
extern volatile bool USB_AUDIO_current_rx_buffer; // a-false b-true
extern volatile bool USB_AUDIO_need_rx_buffer; // a-false b-true
extern uint32_t USB_AUDIO_GetTXBufferIndex_FS(void);
void TransferComplete_CallBack_FS(void);
void HalfTransfer_CallBack_FS(void);
#ifdef __cplusplus
}
#endif
#endif

Wyświetl plik

@ -1,773 +0,0 @@
#include "usbd_cat_if.h"
#include "functions.h"
#include "settings.h"
#include "trx_manager.h"
#include <stdlib.h>
#include "lcd.h"
#include "fpga.h"
#include "audio_filters.h"
#define CAT_APP_RX_DATA_SIZE 32
#define CAT_APP_TX_DATA_SIZE 32
#define CAT_BUFFER_SIZE 64
static char cat_buffer[CAT_BUFFER_SIZE] = {0};
static uint8_t cat_buffer_head = 0;
static char command_to_parse[CAT_BUFFER_SIZE] = {0};
static uint8_t CAT_UserRxBufferFS[CAT_APP_RX_DATA_SIZE];
static uint8_t CAT_UserTxBufferFS[CAT_APP_TX_DATA_SIZE];
static uint8_t lineCoding[7] = {0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08}; // 115200bps, 1stop, no parity, 8bit
extern USBD_HandleTypeDef hUsbDeviceFS;
static uint8_t getFT450Mode(uint8_t VFO_Mode);
static uint8_t setFT450Mode(char *FT450_Mode);
static int8_t CAT_Init_FS(void);
static int8_t CAT_DeInit_FS(void);
static int8_t CAT_Control_FS(uint8_t cmd, uint8_t *pbuf);
static int8_t CAT_Receive_FS(uint8_t *pbuf, uint32_t *Len);
static void CAT_Transmit(char *data);
static uint8_t CAT_Transmit_FS(uint8_t *Buf, uint16_t Len);
USBD_CAT_ItfTypeDef USBD_CAT_fops_FS =
{
CAT_Init_FS,
CAT_DeInit_FS,
CAT_Control_FS,
CAT_Receive_FS};
static int8_t CAT_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_CAT_SetTxBuffer(&hUsbDeviceFS, CAT_UserTxBufferFS, 0);
USBD_CAT_SetRxBuffer(&hUsbDeviceFS, CAT_UserRxBufferFS);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief DeInitializes the CDC media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CAT_DeInit_FS(void)
{
/* USER CODE BEGIN 4 */
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CAT_Control_FS(uint8_t cmd, uint8_t *pbuf)
{
/* USER CODE BEGIN 5 */
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
memcpy(lineCoding, pbuf, sizeof(lineCoding));
break;
case CDC_GET_LINE_CODING:
memcpy(pbuf, lineCoding, sizeof(lineCoding));
break;
case CDC_SET_CONTROL_LINE_STATE:
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t CAT_Receive_FS(uint8_t *Buf, uint32_t *Len)
{
char charBuff[CAT_BUFFER_SIZE] = {0};
strncpy(charBuff, (char *)Buf, Len[0]);
if (Len[0] <= CAT_BUFFER_SIZE)
{
for (uint16_t i = 0; i < Len[0]; i++)
{
if (charBuff[i] != 0)
{
cat_buffer[cat_buffer_head] = charBuff[i];
if (cat_buffer[cat_buffer_head] == ';')
{
memset(&command_to_parse, 0, CAT_BUFFER_SIZE);
memcpy(command_to_parse, cat_buffer, cat_buffer_head);
cat_buffer_head = 0;
memset(&cat_buffer, 0, CAT_BUFFER_SIZE);
continue;
}
cat_buffer_head++;
if (cat_buffer_head >= CAT_BUFFER_SIZE)
{
cat_buffer_head = 0;
memset(&cat_buffer, 0, CAT_BUFFER_SIZE);
}
}
}
}
return (USBD_OK);
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
static uint8_t CAT_Transmit_FS(uint8_t *Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
USBD_CAT_HandleTypeDef *hcdc = (USBD_CAT_HandleTypeDef *)hUsbDeviceFS.pClassDataCAT;
if (hcdc->TxState != 0)
{
return USBD_BUSY;
}
USBD_CAT_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_CAT_TransmitPacket(&hUsbDeviceFS);
return result;
}
static void CAT_Transmit(char *data)
{
CAT_Transmit_FS((uint8_t *)data, (uint16_t)strlen(data));
//sendToDebug_str3("CAT command answer: |",data,"|\r\n");
}
void ua3reo_dev_cat_parseCommand(void)
{
USBD_CAT_ReceivePacket(&hUsbDeviceFS); //prepare next command
if (command_to_parse[0] == 0)
return;
char _command_buffer[CAT_BUFFER_SIZE] = {0};
char *_command = _command_buffer;
memcpy(_command, command_to_parse, CAT_BUFFER_SIZE);
memset(&command_to_parse, 0, CAT_BUFFER_SIZE);
while (*_command == '\r' || *_command == '\n' || *_command == ' ') //trim
_command++;
if (strlen(_command) < 2)
return;
//sendToDebug_str3("New CAT command: |",_command,"|\r\n");
char command[3] = {0};
strncpy(command, _command, 2);
bool has_args = false;
char arguments[32] = {0};
char ctmp[30] = {0};
if (strlen(_command) > 2)
{
strncpy(arguments, _command + 2, strlen(_command) - 2);
has_args = true;
}
//sendToDebug_str3("Arguments: |",arguments,"|\r\n");
if (strcmp(command, "AI") == 0) // AUTO INFORMATION
{
if (!has_args)
{
CAT_Transmit("AI0;");
}
else
{
//ничего не делаем, автоуведомления и так не работают
}
return;
}
if (strcmp(command, "ID") == 0) // IDENTIFICATION
{
if (!has_args)
{
CAT_Transmit("ID0241;");
}
else
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "FT") == 0) // FUNCTION TX
{
if (!has_args)
{
CAT_Transmit("FT0;");
}
else
{
if (strcmp(arguments, "0") == 0)
{
} //SPLIT DONT SUPPOTED
else if (strcmp(arguments, "1") == 0)
{
} //SPLIT DONT SUPPOTED
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "VS") == 0) // VFO SELECT
{
if (!has_args)
{
if (!TRX.current_vfo)
CAT_Transmit("VS0;");
else
CAT_Transmit("VS1;");
}
else
{
if (strcmp(arguments, "0") == 0)
TRX.current_vfo = 0;
else if (strcmp(arguments, "1") == 0)
TRX.current_vfo = 1;
NeedSaveSettings = true;
NeedReinitAudioFilters = true;
LCD_redraw(false);
sendToDebug_str3("CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "IF") == 0) // INFORMATION
{
if (!has_args)
{
char answer[30] = {0};
strcat(answer, "IF001"); //memory channel
if (CurrentVFO()->Freq < 10000000)
strcat(answer, "0");
sprintf(ctmp, "%u", CurrentVFO()->Freq);
strcat(answer, ctmp); //freq
strcat(answer, "+0000"); //clirifier offset
strcat(answer, "0"); //RX clar off
strcat(answer, "0"); //TX clar off
sprintf(ctmp, "%d", getFT450Mode((uint8_t)CurrentVFO()->Mode));
strcat(answer, ctmp); //mode
strcat(answer, "0"); //VFO Memory
strcat(answer, "0"); //CTCSS OFF
strcat(answer, "00"); //TONE NUMBER
strcat(answer, "0;"); //Simplex
CAT_Transmit(answer);
}
else
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "FA") == 0) // FREQUENCY VFO-A
{
if (!has_args)
{
char answer[30] = {0};
strcat(answer, "FA");
if (TRX.VFO_A.Freq < 10000000)
strcat(answer, "0");
sprintf(ctmp, "%u", TRX.VFO_A.Freq);
strcat(answer, ctmp); //freq
strcat(answer, ";");
CAT_Transmit(answer);
}
else
{
if (TRX.current_vfo == 0)
TRX_setFrequency((uint32_t)atoi(arguments), CurrentVFO());
TRX.VFO_A.Freq = (uint32_t)atoi(arguments);
LCD_UpdateQuery.FreqInfo = true;
LCD_UpdateQuery.TopButtons = true;
}
return;
}
if (strcmp(command, "FB") == 0) // FREQUENCY VFO-B
{
if (!has_args)
{
char answer[30] = {0};
strcat(answer, "FA");
if (TRX.VFO_B.Freq < 10000000)
strcat(answer, "0");
sprintf(ctmp, "%u", TRX.VFO_B.Freq);
strcat(answer, ctmp); //freq
strcat(answer, ";");
CAT_Transmit(answer);
}
else
{
if (TRX.current_vfo == 1)
TRX_setFrequency((uint32_t)atoi(arguments), CurrentVFO());
TRX.VFO_B.Freq = (uint32_t)atoi(arguments);
LCD_UpdateQuery.FreqInfo = true;
LCD_UpdateQuery.TopButtons = true;
}
return;
}
if (strcmp(command, "RA") == 0) // RF ATTENUATOR
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
CAT_Transmit("RA00;");
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "PA") == 0) // PRE-AMP
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
if (TRX.ADC_Driver)
CAT_Transmit("PA01;");
else
CAT_Transmit("PA00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "PS") == 0) // POWER-SWITCH
{
if (!has_args)
{
CAT_Transmit("PS1;");
}
else
{
if (strcmp(arguments, "0") == 0)
{
//power off
}
else if (strcmp(arguments, "1") == 0)
{
//power on
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "GT") == 0) // AGC FUNCTION
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
if (TRX.RX_AGC_SSB_speed == 0 || !CurrentVFO()->AGC)
CAT_Transmit("GT00;");
else if (TRX.RX_AGC_SSB_speed == 1)
CAT_Transmit("GT04;");
else if (TRX.RX_AGC_SSB_speed == 2)
CAT_Transmit("GT03;");
else if (TRX.RX_AGC_SSB_speed == 3)
CAT_Transmit("GT02;");
else
CAT_Transmit("GT01;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "MD") == 0) // MODE
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
char answer[30] = {0};
strcat(answer, "MD0");
sprintf(ctmp, "%d", getFT450Mode((uint8_t)CurrentVFO()->Mode));
strcat(answer, ctmp); //mode
strcat(answer, ";");
CAT_Transmit(answer);
}
else
{
if (CurrentVFO()->Mode != setFT450Mode(arguments))
{
TRX_setMode(setFT450Mode(arguments), CurrentVFO());
LCD_UpdateQuery.TopButtons = true;
}
}
}
return;
}
if (strcmp(command, "PC") == 0) // POWER CONTROL
{
if (!has_args)
{
char answer[30] = {0};
strcat(answer, "PC");
sprintf(ctmp, "%d", TRX.RF_Power);
strcat(answer, ctmp);
strcat(answer, ";");
CAT_Transmit(answer);
}
else
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "SH") == 0) // WIDTH
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("SH016;");
}
}
return;
}
if (strcmp(command, "NB") == 0) // NOISE BLANKER
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("NB00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "NR") == 0) // NOISE REDUCTION
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("NR00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "VX") == 0) // VOX STATUS
{
if (!has_args)
{
CAT_Transmit("VX0;");
}
else
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "CT") == 0) // CTCSS
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("CT00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "ML") == 0) // MONITOR LEVEL
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("ML00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "BP") == 0) // MANUAL NOTCH
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "00") == 0)
{
CAT_Transmit("BP00000;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "BI") == 0) // BREAK IN
{
if (!has_args)
{
CAT_Transmit("BI0;");
}
else
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "OS") == 0) // OFFSET
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
{
CAT_Transmit("OS00;");
}
else
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
return;
}
if (strcmp(command, "NA") == 0) // NARROW
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
CAT_Transmit("NA00;");
}
return;
}
if (strcmp(command, "SM") == 0) // READ S-METER
{
if (!has_args)
{
sendToDebug_str3("Unknown CAT arguments: ", _command, "\r\n");
}
else
{
if (strcmp(arguments, "0") == 0)
CAT_Transmit("SM0100;");
}
return;
}
if (strcmp(command, "TX") == 0) // TX SET
{
if (!has_args)
{
if (TRX_ptt_soft)
CAT_Transmit("TX1;");
else if (TRX_ptt_hard)
CAT_Transmit("TX2;");
else
CAT_Transmit("TX0;");
}
else
{
if (strcmp(arguments, "0") == 0)
{
TRX_ptt_soft = false;
}
if (strcmp(arguments, "1") == 0)
{
TRX_ptt_soft = true;
}
}
return;
}
sendToDebug_str3("Unknown CAT command: ", _command, "\r\n");
//sendToDebug_str2(command,"|\r\n");
//sendToDebug_str2(arguments,"|\r\n");
}
static uint8_t getFT450Mode(uint8_t VFO_Mode)
{
if (VFO_Mode == TRX_MODE_LSB)
return 1;
if (VFO_Mode == TRX_MODE_USB)
return 2;
if (VFO_Mode == TRX_MODE_IQ)
return 8;
if (VFO_Mode == TRX_MODE_CW_L)
return 3;
if (VFO_Mode == TRX_MODE_CW_U)
return 3;
if (VFO_Mode == TRX_MODE_DIGI_L)
return 6;
if (VFO_Mode == TRX_MODE_DIGI_U)
return 9;
if (VFO_Mode == TRX_MODE_NO_TX)
return 8;
if (VFO_Mode == TRX_MODE_NFM)
return 4;
if (VFO_Mode == TRX_MODE_WFM)
return 4;
if (VFO_Mode == TRX_MODE_AM)
return 5;
if (VFO_Mode == TRX_MODE_LOOPBACK)
return 8;
return 1;
}
static uint8_t setFT450Mode(char *FT450_Mode)
{
if (strcmp(FT450_Mode, "01") == 0)
return TRX_MODE_LSB;
if (strcmp(FT450_Mode, "02") == 0)
return TRX_MODE_USB;
if (strcmp(FT450_Mode, "08") == 0)
return TRX_MODE_IQ;
if (strcmp(FT450_Mode, "03") == 0)
return TRX_MODE_CW_L;
if (strcmp(FT450_Mode, "06") == 0)
return TRX_MODE_DIGI_L;
if (strcmp(FT450_Mode, "09") == 0)
return TRX_MODE_DIGI_U;
if (strcmp(FT450_Mode, "0C") == 0)
return TRX_MODE_DIGI_U;
if (strcmp(FT450_Mode, "04") == 0)
return TRX_MODE_NFM;
if (strcmp(FT450_Mode, "05") == 0)
return TRX_MODE_AM;
sendToDebug_str3("Unknown mode ", FT450_Mode, "\r\n");
return TRX_MODE_USB;
}

Wyświetl plik

@ -1,18 +0,0 @@
#ifndef __USBD_CDC_CAT_IF_H__
#define __USBD_CDC_CAT_IF_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "usbd_ua3reo.h"
extern USBD_CAT_ItfTypeDef USBD_CAT_fops_FS;
extern void ua3reo_dev_cat_parseCommand(void);
#ifdef __cplusplus
}
#endif
#endif

Wyświetl plik

@ -1,241 +0,0 @@
#include "usbd_debug_if.h"
#include "usbd_cat_if.h"
#include "trx_manager.h"
#include "lcd_driver.h"
#define DEBUG_APP_RX_DATA_SIZE 8
#define DEBUG_APP_TX_DATA_SIZE 64
#define DEBUG_RX_FIFO_BUFFER_SIZE 128
#define DEBUG_TX_FIFO_BUFFER_SIZE 256
static uint8_t DEBUG_UserRxBufferFS[DEBUG_APP_RX_DATA_SIZE];
static uint8_t DEBUG_UserTxBufferFS[DEBUG_APP_TX_DATA_SIZE];
static uint8_t debug_tx_fifo[DEBUG_TX_FIFO_BUFFER_SIZE] = {0};
static uint16_t debug_tx_fifo_head = 0;
static uint16_t debug_tx_fifo_tail = 0;
static uint8_t lineCoding[7] = {0x00, 0xC2, 0x01, 0x00, 0x00, 0x00, 0x08}; // 115200bps, 1stop, no parity, 8bit
extern USBD_HandleTypeDef hUsbDeviceFS;
static int8_t DEBUG_Init_FS(void);
static int8_t DEBUG_DeInit_FS(void);
static int8_t DEBUG_Control_FS(uint8_t cmd, uint8_t *pbuf, uint32_t len);
static int8_t DEBUG_Receive_FS(uint8_t *pbuf);
USBD_DEBUG_ItfTypeDef USBD_DEBUG_fops_FS =
{
DEBUG_Init_FS,
DEBUG_DeInit_FS,
DEBUG_Control_FS,
DEBUG_Receive_FS};
/* Private functions ---------------------------------------------------------*/
/**
* @brief Initializes the CDC media low layer over the FS USB IP
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t DEBUG_Init_FS(void)
{
/* USER CODE BEGIN 3 */
/* Set Application Buffers */
USBD_DEBUG_SetTxBuffer(&hUsbDeviceFS, DEBUG_UserTxBufferFS, 0);
USBD_DEBUG_SetRxBuffer(&hUsbDeviceFS, DEBUG_UserRxBufferFS);
return (USBD_OK);
/* USER CODE END 3 */
}
/**
* @brief DeInitializes the CDC media low layer
* @retval USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t DEBUG_DeInit_FS(void)
{
/* USER CODE BEGIN 4 */
return (USBD_OK);
/* USER CODE END 4 */
}
/**
* @brief Manage the CDC class requests
* @param cmd: Command code
* @param pbuf: Buffer containing command data (request parameters)
* @param length: Number of data to be sent (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t DEBUG_Control_FS(uint8_t cmd, uint8_t *pbuf, uint32_t len)
{
/* USER CODE BEGIN 5 */
switch (cmd)
{
case CDC_SEND_ENCAPSULATED_COMMAND:
break;
case CDC_GET_ENCAPSULATED_RESPONSE:
break;
case CDC_SET_COMM_FEATURE:
break;
case CDC_GET_COMM_FEATURE:
break;
case CDC_CLEAR_COMM_FEATURE:
break;
/*******************************************************************************/
/* Line Coding Structure */
/*-----------------------------------------------------------------------------*/
/* Offset | Field | Size | Value | Description */
/* 0 | dwDTERate | 4 | Number |Data terminal rate, in bits per second*/
/* 4 | bCharFormat | 1 | Number | Stop bits */
/* 0 - 1 Stop bit */
/* 1 - 1.5 Stop bits */
/* 2 - 2 Stop bits */
/* 5 | bParityType | 1 | Number | Parity */
/* 0 - None */
/* 1 - Odd */
/* 2 - Even */
/* 3 - Mark */
/* 4 - Space */
/* 6 | bDataBits | 1 | Number Data bits (5, 6, 7, 8 or 16). */
/*******************************************************************************/
case CDC_SET_LINE_CODING:
memcpy(lineCoding, pbuf, sizeof(lineCoding));
break;
case CDC_GET_LINE_CODING:
memcpy(pbuf, lineCoding, sizeof(lineCoding));
break;
case CDC_SET_CONTROL_LINE_STATE:
if (pbuf[2] == 1)
TRX_key_serial = true;
else
TRX_key_serial = false;
break;
case CDC_SEND_BREAK:
break;
default:
break;
}
return (USBD_OK);
/* USER CODE END 5 */
}
/**
* @brief Data received over USB OUT endpoint are sent over CDC interface
* through this function.
*
* @note
* This function will block any OUT packet reception on USB endpoint
* untill exiting this function. If you exit this function before transfer
* is complete on CDC interface (ie. using DMA controller) it will result
* in receiving more data while previous ones are still not sent.
*
* @param Buf: Buffer of data to be received
* @param Len: Number of data received (in bytes)
* @retval Result of the operation: USBD_OK if all operations are OK else USBD_FAIL
*/
static int8_t DEBUG_Receive_FS(uint8_t *Buf)
{
/* USER CODE BEGIN 6 */
USBD_DEBUG_SetRxBuffer(&hUsbDeviceFS, &Buf[0]);
USBD_DEBUG_ReceivePacket(&hUsbDeviceFS);
return (USBD_OK);
/* USER CODE END 6 */
}
/**
* @brief CDC_Transmit_FS
* Data to send over USB IN endpoint are sent over CDC interface
* through this function.
* @note
*
*
* @param Buf: Buffer of data to be sent
* @param Len: Number of data to be sent (in bytes)
* @retval USBD_OK if all operations are OK else USBD_FAIL or USBD_BUSY
*/
uint8_t DEBUG_Transmit_FS(uint8_t *Buf, uint16_t Len)
{
uint8_t result = USBD_OK;
/* USER CODE BEGIN 7 */
USBD_DEBUG_HandleTypeDef *hcdc = (USBD_DEBUG_HandleTypeDef *)hUsbDeviceFS.pClassDataDEBUG;
if (hcdc->TxState != 0)
{
return USBD_BUSY;
}
USBD_DEBUG_SetTxBuffer(&hUsbDeviceFS, Buf, Len);
result = USBD_DEBUG_TransmitPacket(&hUsbDeviceFS);
/* USER CODE END 7 */
return result;
}
void DEBUG_Transmit_FIFO(uint8_t *data, uint16_t length)
{
if (length <= DEBUG_TX_FIFO_BUFFER_SIZE)
for (uint16_t i = 0; i < length; i++)
{
debug_tx_fifo[debug_tx_fifo_head] = data[i];
debug_tx_fifo_head++;
if (debug_tx_fifo_head == debug_tx_fifo_tail)
{
uint_fast16_t tryes = 0;
while (DEBUG_Transmit_FIFO_Events() == USBD_BUSY && tryes < 512)
tryes++;
if(DEBUG_Transmit_FIFO_Events() == USBD_BUSY)
break;
}
if (debug_tx_fifo_head >= DEBUG_TX_FIFO_BUFFER_SIZE)
debug_tx_fifo_head = 0;
}
}
static uint8_t temp_buff[DEBUG_TX_FIFO_BUFFER_SIZE] = {0};
static bool FIFO_Events_busy = false;
uint8_t DEBUG_Transmit_FIFO_Events(void)
{
if (FIFO_Events_busy)
return USBD_FAIL;
if (debug_tx_fifo_head == debug_tx_fifo_tail)
return USBD_OK;
USBD_DEBUG_HandleTypeDef *hcdc = (USBD_DEBUG_HandleTypeDef *)hUsbDeviceFS.pClassDataDEBUG;
if (hcdc->TxState != 0)
return USBD_FAIL;
FIFO_Events_busy = true;
uint16_t indx = 0;
memset(temp_buff, 0x00, DEBUG_TX_FIFO_BUFFER_SIZE);
if (debug_tx_fifo_tail > debug_tx_fifo_head)
{
for (uint16_t i = debug_tx_fifo_tail; i < DEBUG_TX_FIFO_BUFFER_SIZE; i++)
{
temp_buff[indx] = debug_tx_fifo[i];
indx++;
debug_tx_fifo_tail++;
if (indx == DEBUG_APP_TX_DATA_SIZE)
break;
}
if (debug_tx_fifo_tail == DEBUG_TX_FIFO_BUFFER_SIZE)
debug_tx_fifo_tail = 0;
}
else if (debug_tx_fifo_tail < debug_tx_fifo_head)
{
for (uint16_t i = debug_tx_fifo_tail; i < debug_tx_fifo_head; i++)
{
temp_buff[indx] = debug_tx_fifo[i];
indx++;
debug_tx_fifo_tail++;
if (indx == DEBUG_APP_TX_DATA_SIZE)
break;
}
}
DEBUG_Transmit_FS(temp_buff, indx);
FIFO_Events_busy = false;
return USBD_BUSY;
}

Wyświetl plik

@ -1,21 +0,0 @@
#ifndef __USBD_CDC_DEBUG_IF_H__
#define __USBD_CDC_DEBUG_IF_H__
#ifdef __cplusplus
extern "C"
{
#endif
#include "usbd_ua3reo.h"
extern USBD_DEBUG_ItfTypeDef USBD_DEBUG_fops_FS;
uint8_t DEBUG_Transmit_FS(uint8_t *Buf, uint16_t Len);
void DEBUG_Transmit_FIFO(uint8_t *data, uint16_t length);
extern uint8_t DEBUG_Transmit_FIFO_Events(void);
#ifdef __cplusplus
}
#endif
#endif

Plik diff jest za duży Load Diff

Wyświetl plik

@ -1,209 +0,0 @@
#ifndef __USB_CDC_H
#define __USB_CDC_H
#ifdef __cplusplus
extern "C"
{
#endif
#include "usbd_ioreq.h"
#include "audio_processor.h"
#define DEBUG_INTERFACE_IDX 0x0 // Index of DEBUG interface
#define CAT_INTERFACE_IDX 0x2 // Index of CAT interface
#define AUDIO_INTERFACE_IDX 0x4 // Index of AUDIO interface
#define DEBUG_EP_IDX 0x01
#define CAT_EP_IDX 0x02
#define AUDIO_EP_IDX 0x03
#define DEBUG_CMD_IDX 0x04
#define CAT_CMD_IDX 0x04
#define IN_EP_DIR 0x80 // Adds a direction bit
#define DEBUG_OUT_EP DEBUG_EP_IDX
#define DEBUG_IN_EP (DEBUG_EP_IDX | IN_EP_DIR)
#define DEBUG_CMD_EP (DEBUG_CMD_IDX | IN_EP_DIR)
#define CAT_OUT_EP CAT_EP_IDX
#define CAT_IN_EP (CAT_EP_IDX | IN_EP_DIR)
#define CAT_CMD_EP (CAT_CMD_IDX | IN_EP_DIR)
#define AUDIO_OUT_EP AUDIO_EP_IDX
#define AUDIO_IN_EP (AUDIO_EP_IDX | IN_EP_DIR)
#ifndef CDC_HS_BINTERVAL
#define CDC_HS_BINTERVAL 0x10U
#endif /* CDC_HS_BINTERVAL */
#ifndef CDC_FS_BINTERVAL
#define CDC_FS_BINTERVAL 0x10U
#endif /* CDC_FS_BINTERVAL */
/* CDC Endpoints parameters: you can fine tune these values depending on the needed baudrates and performance. */
#define CDC_DATA_HS_MAX_PACKET_SIZE 16U /* Endpoint IN & OUT Packet size */
#define CDC_DATA_FS_MAX_PACKET_SIZE 16U /* Endpoint IN & OUT Packet size */
#define CDC_CMD_PACKET_SIZE 16U /* Control Endpoint Packet size */
#define USB_CDC_CONFIG_DESC_SIZ 314U
#define CDC_DATA_HS_IN_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_HS_OUT_PACKET_SIZE CDC_DATA_HS_MAX_PACKET_SIZE
#define CDC_DATA_FS_IN_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
#define CDC_DATA_FS_OUT_PACKET_SIZE CDC_DATA_FS_MAX_PACKET_SIZE
/*---------------------------------------------------------------------*/
/* CDC definitions */
/*---------------------------------------------------------------------*/
#define CDC_SEND_ENCAPSULATED_COMMAND 0x00U
#define CDC_GET_ENCAPSULATED_RESPONSE 0x01U
#define CDC_SET_COMM_FEATURE 0x02U
#define CDC_GET_COMM_FEATURE 0x03U
#define CDC_CLEAR_COMM_FEATURE 0x04U
#define CDC_SET_LINE_CODING 0x20U
#define CDC_GET_LINE_CODING 0x21U
#define CDC_SET_CONTROL_LINE_STATE 0x22U
#define CDC_SEND_BREAK 0x23U
//AUDIO
#define USBD_AUDIO_FREQ 48000U
#define BYTES_IN_SAMPLE_AUDIO_OUT_PACKET 3U //24bit
#define AUDIO_OUT_PACKET (BYTES_IN_SAMPLE_AUDIO_OUT_PACKET * 2 * (USBD_AUDIO_FREQ / 1000)) //3bytes (24bit) * 2 channel * 48 packet per second
#define USB_AUDIO_RX_BUFFER_SIZE (AUDIO_BUFFER_SIZE * BYTES_IN_SAMPLE_AUDIO_OUT_PACKET) //24 bit
#define USB_AUDIO_TX_BUFFER_SIZE (AUDIO_BUFFER_SIZE * BYTES_IN_SAMPLE_AUDIO_OUT_PACKET * 2) //24 bit x2 size
#define AUDIO_REQ_GET_CUR 0x81U
#define AUDIO_REQ_SET_CUR 0x01U
#define AUDIO_OUT_STREAMING_CTRL 0x02U
#define USB_AUDIO_DESC_SIZ 0x09U
#define AUDIO_DESCRIPTOR_TYPE 0x21U
extern volatile uint32_t RX_USB_AUDIO_SAMPLES;
extern volatile uint32_t TX_USB_AUDIO_SAMPLES;
extern volatile bool RX_USB_AUDIO_underrun;
extern volatile uint32_t USB_LastActiveTime;
typedef struct
{
uint32_t bitrate;
uint8_t format;
uint8_t paritytype;
uint8_t datatype;
} USBD_CDC_LineCodingTypeDef;
typedef enum
{
AUDIO_CMD_START = 1,
AUDIO_CMD_PLAY,
AUDIO_CMD_STOP,
} AUDIO_CMD_TypeDef;
typedef enum
{
AUDIO_OFFSET_NONE = 0,
AUDIO_OFFSET_HALF,
AUDIO_OFFSET_FULL,
AUDIO_OFFSET_UNKNOWN,
} AUDIO_OffsetTypeDef;
typedef struct
{
uint8_t cmd;
uint8_t data[USB_MAX_EP0_SIZE];
uint8_t len;
uint8_t unit;
} USBD_AUDIO_ControlTypeDef;
typedef struct _USBD_DEBUG_Itf
{
int8_t (*Init)(void);
int8_t (*DeInit)(void);
int8_t (*Control)(uint8_t cmd, uint8_t *pbuf, uint32_t len);
int8_t (*Receive)(uint8_t *Buf);
} USBD_DEBUG_ItfTypeDef;
typedef struct _USBD_CAT_Itf
{
int8_t (*Init)(void);
int8_t (*DeInit)(void);
int8_t (*Control)(uint8_t cmd, uint8_t *pbuf);
int8_t (*Receive)(uint8_t *Buf, uint32_t *Len);
} USBD_CAT_ItfTypeDef;
typedef struct
{
int8_t (*Init)(void);
int8_t (*DeInit)(void);
} USBD_AUDIO_ItfTypeDef;
typedef struct
{
uint32_t alt_setting;
USBD_AUDIO_ControlTypeDef control;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t TxBufferIndex;
} USBD_AUDIO_HandleTypeDef;
typedef struct
{
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */
uint8_t CmdOpCode;
uint8_t CmdLength;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t RxLength;
uint32_t TxLength;
__IO uint32_t TxState;
__IO uint32_t RxState;
} USBD_DEBUG_HandleTypeDef;
typedef struct
{
uint32_t data[CDC_DATA_HS_MAX_PACKET_SIZE / 4U]; /* Force 32bits alignment */
uint8_t CmdOpCode;
uint8_t CmdLength;
uint8_t *RxBuffer;
uint8_t *TxBuffer;
uint32_t RxLength;
uint32_t TxLength;
__IO uint32_t TxState;
__IO uint32_t RxState;
} USBD_CAT_HandleTypeDef;
extern USBD_ClassTypeDef USBD_UA3REO;
extern USBD_HandleTypeDef hUsbDeviceFS;
#define USBD_UA3REO_CLASS &USBD_UA3REO
extern uint8_t USBD_DEBUG_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_DEBUG_ItfTypeDef *fops);
extern uint8_t USBD_DEBUG_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint16_t length);
extern uint8_t USBD_DEBUG_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
extern uint8_t USBD_DEBUG_ReceivePacket(USBD_HandleTypeDef *pdev);
extern uint8_t USBD_DEBUG_TransmitPacket(USBD_HandleTypeDef *pdev);
extern uint8_t USBD_CAT_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_CAT_ItfTypeDef *fops);
extern uint8_t USBD_CAT_SetTxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff, uint16_t length);
extern uint8_t USBD_CAT_SetRxBuffer(USBD_HandleTypeDef *pdev, uint8_t *pbuff);
extern uint8_t USBD_CAT_ReceivePacket(USBD_HandleTypeDef *pdev);
extern uint8_t USBD_CAT_TransmitPacket(USBD_HandleTypeDef *pdev);
extern uint8_t USBD_AUDIO_RegisterInterface(USBD_HandleTypeDef *pdev, USBD_AUDIO_ItfTypeDef *fops);
extern uint8_t USBD_AUDIO_StartTransmit(USBD_HandleTypeDef *pdev);
extern uint8_t USBD_AUDIO_StartReceive(USBD_HandleTypeDef *pdev);
extern void USBD_Restart(void);
/**
* @}
*/
#ifdef __cplusplus
}
#endif
#endif

Wyświetl plik

@ -1,223 +0,0 @@
#include "stm32f4xx_hal.h"
#include "wm8731.h"
#include "trx_manager.h"
#include "i2c.h"
#include "lcd.h"
#include "agc.h"
#include "usbd_audio_if.h"
//Public variables
uint32_t WM8731_DMA_samples = 0; // count the number of samples passed to the audio codec
bool WM8731_DMA_state = true; // what part of the buffer we are working with, true - compleate; false - half
bool WM8731_Buffer_underrun = false; // lack of data in the buffer from the audio processor
IRAM1 int32_t CODEC_Audio_Buffer_RX[CODEC_AUDIO_BUFFER_SIZE] = {0}; // audio codec ring buffers
IRAM1 int32_t CODEC_Audio_Buffer_TX[CODEC_AUDIO_BUFFER_SIZE] = {0};
bool WM8731_Beeping; //Beeping flag
bool WM8731_Muting; //Muting flag
//Private variables
//Prototypes
static uint8_t WM8731_SendI2CCommand(uint8_t reg, uint8_t value); // send I2C command to codec
static HAL_StatusTypeDef HAL_I2S_TXRX_DMA(I2S_HandleTypeDef *hi2s, uint16_t *txData, uint16_t *rxData, uint16_t txSize, uint16_t rxSize); // Full-duplex implementation of I2S startup
static void I2SEx_Fix(I2S_HandleTypeDef *hi2s);
// start the I2S bus
void WM8731_start_i2s_and_dma(void)
{
WM8731_CleanBuffer();
if (HAL_I2S_GetState(&hi2s3) == HAL_I2S_STATE_READY)
{
HAL_I2SEx_TransmitReceive_DMA(&hi2s3, (uint16_t*)&CODEC_Audio_Buffer_RX[0], (uint16_t*)&CODEC_Audio_Buffer_TX[0], CODEC_AUDIO_BUFFER_SIZE);
I2SEx_Fix(&hi2s3);
}
}
// clear the audio codec and USB audio buffer
void WM8731_CleanBuffer(void)
{
memset(CODEC_Audio_Buffer_RX, 0x00, sizeof CODEC_Audio_Buffer_RX);
memset(CODEC_Audio_Buffer_TX, 0x00, sizeof CODEC_Audio_Buffer_TX);
memset(USB_AUDIO_rx_buffer_a, 0x00, sizeof USB_AUDIO_rx_buffer_a);
memset(USB_AUDIO_rx_buffer_b, 0x00, sizeof USB_AUDIO_rx_buffer_a);
memset(USB_AUDIO_tx_buffer, 0x00, sizeof USB_AUDIO_tx_buffer);
ResetAGC();
}
// send I2C command to codec
static uint8_t WM8731_SendI2CCommand(uint8_t reg, uint8_t value)
{
uint8_t st = 2;
uint8_t repeats = 0;
while (st != 0 && repeats < 3)
{
i2c_beginTransmission_u8(&I2C_WM8731, B8(0011010)); //I2C_ADDRESS_WM8731 00110100
i2c_write_u8(&I2C_WM8731, reg); // MSB
i2c_write_u8(&I2C_WM8731, value); // MSB
st = i2c_endTransmission(&I2C_WM8731);
if (st != 0)
repeats++;
HAL_Delay(1);
}
return st;
}
// switch to TX mode (mute the speaker, etc.)
void WM8731_TX_mode(void)
{
WM8731_SendI2CCommand(B8(00000101), B8(10000000)); //R2 Left Headphone Out
WM8731_SendI2CCommand(B8(00000111), B8(10000000)); //R3 Right Headphone Out
WM8731_SendI2CCommand(B8(00001010), B8(00011110)); //R5 Digital Audio Path Control
if (TRX.InputType_LINE) //line
{
WM8731_SendI2CCommand(B8(00000000), B8(00010111)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000010), B8(00010111)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00001000), B8(00000010)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01101010)); //R6 Power Down Control
}
if (TRX.InputType_MIC) //mic
{
WM8731_SendI2CCommand(B8(00000001), B8(10000000)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000011), B8(10000000)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00001000), B8(00000101)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01101001)); //R6 Power Down Control
}
}
// switch to RX mode (mute the microphone, etc.)
void WM8731_RX_mode(void)
{
WM8731_SendI2CCommand(B8(00000000), B8(10000000)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000010), B8(10000000)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00000101), B8(11111111)); //R2 Left Headphone Out
WM8731_SendI2CCommand(B8(00000111), B8(11111111)); //R3 Right Headphone Out
WM8731_SendI2CCommand(B8(00001000), B8(00010110)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001010), B8(00010000)); //R5 Digital Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01100111)); //R6 Power Down Control
}
// switch to mixed RX-TX mode (for LOOP)
void WM8731_TXRX_mode(void) //loopback
{
WM8731_SendI2CCommand(B8(00000101), B8(11111111)); //R2 Left Headphone Out
WM8731_SendI2CCommand(B8(00000111), B8(11111111)); //R3 Right Headphone Out
WM8731_SendI2CCommand(B8(00001010), B8(00010000)); //R5 Digital Audio Path Control
if (TRX.InputType_LINE) //line
{
WM8731_SendI2CCommand(B8(00000000), B8(00010111)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000010), B8(00010111)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00001000), B8(00010010)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01100010)); //R6 Power Down Control, internal crystal
}
if (TRX.InputType_MIC) //mic
{
WM8731_SendI2CCommand(B8(00000001), B8(10000000)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000011), B8(10000000)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00001000), B8(00010101)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01100001)); //R6 Power Down Control, internal crystal
}
}
void WM8731_Mute(void)
{
WM8731_Muting = true;
HAL_GPIO_WritePin(MUTE_GPIO_Port, MUTE_Pin, GPIO_PIN_RESET);
}
void WM8731_UnMute(void)
{
WM8731_Muting = false;
HAL_GPIO_WritePin(MUTE_GPIO_Port, MUTE_Pin, GPIO_PIN_SET);
}
void WM8731_Beep(void)
{
if(TRX.Beeper)
{
WM8731_Beeping = true;
HAL_Delay(50);
WM8731_Beeping = false;
}
}
// initialize the audio codec over I2C
void WM8731_Init(void)
{
if (WM8731_SendI2CCommand(B8(00011110), B8(00000000)) != 0) //R15 Reset Chip
{
sendToDebug_strln("[ERR] Audio codec not found");
LCD_showError("Audio codec init error", true);
}
WM8731_SendI2CCommand(B8(00000101), B8(10000000)); //R2 Left Headphone Out Mute
WM8731_SendI2CCommand(B8(00000111), B8(10000000)); //R3 Right Headphone Out Mute
WM8731_SendI2CCommand(B8(00001110), B8(00001110)); //R7 Digital Audio Interface Format, Codec Slave, 32bits, I2S Format, MSB-First left-1 justified
WM8731_SendI2CCommand(B8(00010000), B8(00000000)); //R8 Sampling Control normal mode, 256fs, SR=0 (MCLK@12.288Mhz, fs=48kHz))
WM8731_SendI2CCommand(B8(00010010), B8(00000001)); //R9 reactivate digital audio interface
WM8731_SendI2CCommand(B8(00000000), B8(10000000)); //R0 Left Line In
WM8731_SendI2CCommand(B8(00000010), B8(10000000)); //R1 Right Line In
WM8731_SendI2CCommand(B8(00001000), B8(00010110)); //R4 Analogue Audio Path Control
WM8731_SendI2CCommand(B8(00001010), B8(00010000)); //R5 Digital Audio Path Control
WM8731_SendI2CCommand(B8(00001100), B8(01100111)); //R6 Power Down Control
WM8731_UnMute();
}
// RX Buffer is fully sent to the codec
void HAL_I2SEx_TxRxCpltCallback(I2S_HandleTypeDef *hi2s)
{
if (hi2s->Instance == SPI3)
{
if (Processor_NeedRXBuffer) // if the audio codec did not provide data to the buffer, raise the error flag
{
WM8731_Buffer_underrun = true;
}
WM8731_DMA_state = true;
Processor_NeedRXBuffer = true;
if (CurrentVFO()->Mode == TRX_MODE_LOOPBACK)
Processor_NeedTXBuffer = true;
WM8731_DMA_samples += (CODEC_AUDIO_BUFFER_SIZE / 2);
}
}
// RX Buffer half sent to the codec
void HAL_I2SEx_TxRxHalfCpltCallback(I2S_HandleTypeDef *hi2s)
{
if (hi2s->Instance == SPI3)
{
if (Processor_NeedRXBuffer) // if the audio codec did not provide data to the buffer, raise the error flag
{
WM8731_Buffer_underrun = true;
}
WM8731_DMA_state = false;
Processor_NeedRXBuffer = true;
if (CurrentVFO()->Mode == TRX_MODE_LOOPBACK)
Processor_NeedTXBuffer = true;
WM8731_DMA_samples += (CODEC_AUDIO_BUFFER_SIZE / 2);
}
}
static void UA3REO_I2SEx_TxRxDMAHalfCplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
HAL_I2SEx_TxRxHalfCpltCallback(hi2s);
}
static void UA3REO_I2SEx_TxRxDMACplt(DMA_HandleTypeDef *hdma)
{
I2S_HandleTypeDef* hi2s = (I2S_HandleTypeDef*)((DMA_HandleTypeDef*)hdma)->Parent;
HAL_I2SEx_TxRxCpltCallback(hi2s);
}
static void UA3REO_I2SEx_DMAErr(DMA_HandleTypeDef *hdma)
{
sendToDebug_str("err");
}
static void I2SEx_Fix(I2S_HandleTypeDef *hi2s)
{
hi2s->hdmarx->XferHalfCpltCallback = NULL;
hi2s->hdmatx->XferHalfCpltCallback = UA3REO_I2SEx_TxRxDMAHalfCplt;
hi2s->hdmarx->XferCpltCallback = NULL;
hi2s->hdmatx->XferCpltCallback = UA3REO_I2SEx_TxRxDMACplt;
hi2s->hdmarx->XferErrorCallback = NULL;
hi2s->hdmatx->XferErrorCallback = UA3REO_I2SEx_DMAErr;
}

Wyświetl plik

@ -1,32 +0,0 @@
#ifndef WM8731_h
#define WM8731_h
#include "stm32f4xx_hal.h"
#include <stdio.h>
#include "audio_processor.h"
#include "functions.h"
#define I2C_ADDRESS_WM8731 0x34 //audio codec address
#define CODEC_AUDIO_BUFFER_SIZE (AUDIO_BUFFER_SIZE * 2) //the size of the circular buffer is 2 times larger than the FPGA buffer, we work in the first half, then on the other
#define CODEC_AUDIO_BUFFER_HALF_SIZE AUDIO_BUFFER_SIZE //half buffer
//Public variables
extern int32_t CODEC_Audio_Buffer_RX[CODEC_AUDIO_BUFFER_SIZE];
extern int32_t CODEC_Audio_Buffer_TX[CODEC_AUDIO_BUFFER_SIZE];
extern bool WM8731_DMA_state; //what part of the buffer are we working with, true - complete; false - half
extern bool WM8731_Buffer_underrun; //lack of data in the buffer from the audio processor
extern uint32_t WM8731_DMA_samples; //count the number of samples transmitted to the audio codec
extern bool WM8731_Beeping; //Beeping flag
extern bool WM8731_Muting; //Muting flag
//Public methods
extern void WM8731_Init(void); //I2C audio codec initialization
extern void WM8731_start_i2s_and_dma(void); //I2S bus start
extern void WM8731_CleanBuffer(void); //clear the audio codec and USB audio buffer
extern void WM8731_TX_mode(void); //switch to TX mode (mute the speaker, etc.)
extern void WM8731_RX_mode(void); //switching to RX mode (mute the microphone, etc.)
extern void WM8731_TXRX_mode(void); //switch to mixed mode RX-TX (for LOOP)
extern void WM8731_Mute(void); //mute audio out
extern void WM8731_UnMute(void); //disable audio mute
extern void WM8731_Beep(void); //beep on key press
#endif