RadioDSP-Stm32f103/src/RadioDSP_Fast/src/main.c

254 wiersze
6.6 KiB
C

/**
******************************************************************************
* @file main.c
* @author Giuseppe Callipo - IK8YFW - ik8yfw@libero.it
* @version V1.0.0
* @date 22-04-2018
* @brief Main routine file
*
******************************************************************************
*
* THE RADIO DSP - PROJECT
*
* This project RadioDSP define a experimental open platform to build
* Real Time filtering and audio digital signal elaboration from
* a source audio signal in output form radio transceiver or receiver.
* The RadioDSP firmware define some FIR filter and routines to perform
* real time Noise Reduction based on various algorithm.
* The target hardware platform is Stm32f103 - Arm Cortex-M3 based processor.
*
* The functions built in the RadioDSP are:
* Filter BPF CW NARROW (300 HZ)
* Filter BPF CW NARROW (700 Hz)
* Filter LPF SSB ( < 2400 Hz )
* Filter LPF SSB ( < 3500 Hz )
*
* Noise Reduction (Exponential Moving Average - 3 levels smoothing)
* Noise Reduction (Simple Moving Average - 3 levels smoothing: 8,16,24 samples)
*
* NOTE: this is an experimental project and the functions can be changed
* without any advise.
*
* Info to noise reduction algorithms: info: https://en.wikipedia.org/wiki/Moving_average
*
* Calculator used for FIR filters: https://www.arc.id.au/FilterDesign.html
*
* The RadioDSP use some parts of the ARM Cortex Microcontroller Software
* Interface Standard (CMSIS).
* The RadioDSP use some parts of STM32F103 examples by Yohanes Erwin and
* others examples and projects free and available in the opensource
* community.
*
* The RadioDSP openSource software is released under the license:
* Common Creative - Attribution 3.0
******************************************************************************
*/
/* ----------------------------------------------------------------------
** Include Files
** ------------------------------------------------------------------- */
#include "stm32f10x.h"
#include "stm32f10x_rcc.h"
#include "stm32f10x_gpio.h"
#include "stm32f10x_adc.h"
#include "stm32f10x_tim.h"
#include "arm_math.h"
#include "io_routines.h"
#include "filter_cmsis.h"
#include "filter_cmsis2.h"
#include "filter_cmsis_cw_nar.h"
#include "filter_cmsis_cw_nar2.h"
#include "filter_noise_reduction.h"
// Filter status
volatile uint16_t FILTER0_STATUS=0;
volatile uint16_t FILTER1_STATUS=0;
volatile uint16_t FILTER2_STATUS=0;
volatile uint16_t FILTER3_STATUS=0;
volatile uint16_t BYPASS=0;
volatile uint16_t adcValue = 0;
volatile float32_t adcValueF = 0;
volatile uint16_t sel_filter_0 = 0;
volatile uint16_t sel_filter_1 = 0;
volatile uint16_t sel_filter_2 = 0;
volatile uint16_t sel_filter_3 = 0;
void blinkDiode(){
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
DelayMs(30);
GPIO_SetBits(GPIOC, GPIO_Pin_13);
DelayMs(30);
}
void decodeFilterStatus (){
// Make a copy
uint16_t FILTER0_STATUS_TMP=FILTER0_STATUS;
uint16_t FILTER1_STATUS_TMP=FILTER1_STATUS;
uint16_t FILTER2_STATUS_TMP=FILTER2_STATUS;
uint16_t FILTER3_STATUS_TMP=FILTER3_STATUS;
uint16_t changed = 0;
// Check if push any button - active low
if (sel_filter_0==0)
{
FILTER0_STATUS_TMP = (FILTER0_STATUS_TMP ==0)?1:0;
changed = 1;
}
if (sel_filter_1==0)
{
FILTER1_STATUS_TMP = (FILTER1_STATUS_TMP ==0)?1:0;
changed = 1;
}
if (sel_filter_2==0)
{
FILTER2_STATUS_TMP ++;
FILTER2_STATUS_TMP = (FILTER2_STATUS_TMP >2)?0:FILTER2_STATUS_TMP;
changed = 1;
}
if (sel_filter_3==0)
{
FILTER3_STATUS_TMP ++;
FILTER3_STATUS_TMP = (FILTER3_STATUS_TMP >6)?0:FILTER3_STATUS_TMP;
changed = 1;
}
if( (FILTER0_STATUS_TMP + FILTER1_STATUS_TMP + FILTER2_STATUS_TMP + FILTER3_STATUS_TMP) >0){
BYPASS =1;
}else{
BYPASS =0;
}
// if any changes ...
if (changed == 1){
// Commit change ...
blinkDiode();
FILTER0_STATUS = FILTER0_STATUS_TMP;
FILTER1_STATUS = FILTER1_STATUS_TMP;
FILTER2_STATUS = FILTER2_STATUS_TMP;
FILTER3_STATUS = FILTER3_STATUS_TMP;
}
return;
}
void chekUserActions(){
// Read input switch (active low)
sel_filter_0 = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_12);
sel_filter_1 = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_13);
sel_filter_2 = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_14);
sel_filter_3 = GPIO_ReadInputDataBit(GPIOB, GPIO_Pin_15);
// Decode filter status
decodeFilterStatus();
// If any audio sel_filter is active, then turn on LED
if (BYPASS==1)
{
// Turn on LED (active low)
GPIO_ResetBits(GPIOC, GPIO_Pin_13);
}
else
{
GPIO_SetBits(GPIOC, GPIO_Pin_13);
}
}
int main(void)
{
// Initialize delay function
DelayInit();
// Initialize ADC, PWM, and GPIO
ADC_Setup();
PWM_Setup();
GPIO_Setup();
init_firFilter1_cmsis();
init_firFilter2_cmsis();
init_firFilter1_cmsis_cw_nar();
init_firFilter2_cmsis_cw_nar();
while (1)
{
chekUserActions();
// Hihh delay for debounce
DelayMs(10);
}
}
void TIM3_IRQHandler()
{
// Checks whether the TIM3 interrupt has occurred or not
if (TIM_GetITStatus(TIM3, TIM_IT_Update))
{
// Read ADC value downsize to 10 bit (10-bit PWM)
adcValue = ADC_Read() >> 2;
adcValueF = inputConvert(adcValue);
// CW NARROW work alone
if (FILTER0_STATUS==1)
{
adcValueF = firFilter2_cmsis(adcValueF);
adcValueF = firFilter2_cmsis_cw_nar(adcValueF);
//adcValueF = firFilter1_cmsis(adcValueF);
}
// Noise reduction can work with SSB or alone
if (FILTER1_STATUS==1)
{
// Variable noise Reduction
adcValueF = firFilter2_cmsis(adcValueF);
adcValueF = firFilter1_cmsis_cw_nar(adcValueF);
}
// SSB work alone or woth Noise reduction
if (FILTER2_STATUS==1)
{
adcValueF = firFilter1_cmsis(adcValueF);
}
// SSB work alone or woth Noise reduction
if (FILTER2_STATUS==2)
{
adcValueF = firFilter2_cmsis(adcValueF);
}
// Noise reduction can work with SSB or alone
if (FILTER3_STATUS>0 && FILTER3_STATUS<=3)
{
// Variable noise Reduction
adcValueF = fnrFilter_n(adcValueF, FILTER3_STATUS);
}
// Noise reduction can work with SSB or alone
if (FILTER3_STATUS>3)
{
// Variable noise Reduction
adcValueF = fnrFilter_n_Average(adcValueF, FILTER3_STATUS);
}
// Write back to PWM (DAC)
adcValue = outputConvert(adcValueF);
PWM_Write(adcValue);
// Clears the TIM3 interrupt pending bit
TIM_ClearITPendingBit(TIM3, TIM_IT_Update);
}
}