kopia lustrzana https://github.com/gcallipo/RadioDSP-Stm32f103
254 wiersze
6.6 KiB
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);
|
|
}
|
|
}
|