kopia lustrzana https://github.com/kamocat/uSDX
Drafted decimation filter for qsd receiver
rodzic
ace1e657b8
commit
4d55b178a9
|
@ -65,21 +65,13 @@
|
|||
|
||||
</folderInfo>
|
||||
|
||||
<folderInfo id="0.87736009.1762812655" name="/" resourcePath="board">
|
||||
<sourceEntries>
|
||||
|
||||
<toolChain id="org.eclipse.cdt.build.core.prefbase.toolchain.1198201678" name="No ToolChain" superClass="org.eclipse.cdt.build.core.prefbase.toolchain" unusedChildren="">
|
||||
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.libs.117598285" name="holder for library settings" superClass="org.eclipse.cdt.build.core.settings.holder.libs.686764108"/>
|
||||
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1159330235" name="Assembly" superClass="org.eclipse.cdt.build.core.settings.holder.1629275092"/>
|
||||
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.1564596667" name="GNU C++" superClass="org.eclipse.cdt.build.core.settings.holder.1369722403"/>
|
||||
|
||||
<tool id="org.eclipse.cdt.build.core.settings.holder.797214978" name="GNU C" superClass="org.eclipse.cdt.build.core.settings.holder.883301168"/>
|
||||
|
||||
</toolChain>
|
||||
<entry excluding="radio" flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name=""/>
|
||||
|
||||
<entry flags="VALUE_WORKSPACE_PATH|RESOLVED" kind="sourcePath" name="radio"/>
|
||||
|
||||
</folderInfo>
|
||||
</sourceEntries>
|
||||
|
||||
</configuration>
|
||||
|
||||
|
|
|
@ -120,7 +120,7 @@ LDSCRIPT= $(STARTUPLD)/STM32F051x8.ld
|
|||
# setting.
|
||||
CSRC = $(ALLCSRC) \
|
||||
$(TESTSRC) \
|
||||
main.c
|
||||
main.c dsp.c radio/rx.c
|
||||
|
||||
# C++ sources that can be compiled in ARM or THUMB mode depending on the global
|
||||
# setting.
|
||||
|
|
|
@ -0,0 +1,88 @@
|
|||
/*
|
||||
* dsp.c
|
||||
*
|
||||
* Created on: Jul 6, 2020
|
||||
* Author: marshal
|
||||
*/
|
||||
#include "dsp.h"
|
||||
#include "radio/rx.h"
|
||||
/*
|
||||
* ADC streaming callback.
|
||||
*
|
||||
* We sampled at 500kHz, but our bandwidth of interest is only
|
||||
* 2kHz. (Since it's quadrature sampling, nyquist rate is 1x)
|
||||
* We use a second-order IIR filter to prevent aliasing, followed
|
||||
* by an accumulate for decimation
|
||||
*/
|
||||
static void adccallback(ADCDriver *adcp) {
|
||||
adcsample_t * ptr = adcp->samples;
|
||||
size_t len = adcp->depth/2; // This also determines downsample ratio
|
||||
// These are persistent variables for filter history
|
||||
static uint32_t a1 = 0;
|
||||
static uint32_t b1 = 0;
|
||||
static uint32_t a2 = 0;
|
||||
static uint32_t b2 = 0;
|
||||
// These are temporary variables to return the downsampled signal
|
||||
uint32_t c1 = 0;
|
||||
uint32_t c2 = 0;
|
||||
/* This determines the corner frequency of our IIR filter.
|
||||
* It's actually 1/log2 of the corner
|
||||
*/
|
||||
const uint8_t corner = 7;
|
||||
for(unsigned int i=0; i<len; ++i){
|
||||
a1 += *ptr++ - (a1>>corner); // 12+7 = 19 bits
|
||||
b1 += a1 - (b1>>corner); // 19+7 = 26 bits
|
||||
a2 += *ptr++ - (a2>>corner);
|
||||
b2 += a2 - (b2>>corner);
|
||||
// If len>64, we need to shift right to prevent overflow.
|
||||
const uint8_t shift = 0;
|
||||
c1 += b1>>shift; // 26+6=32 bits
|
||||
c2 += b2>>shift;
|
||||
}
|
||||
struct complex c;
|
||||
c.real = (c1>>16) - 0x8000;
|
||||
c.imag = (c2>>16) - 0x8000;
|
||||
chMsgSend((void*)radio_rx, (msg_t)&c);
|
||||
}
|
||||
|
||||
static void adcerrorcallback(ADCDriver *adcp, adcerror_t err) {
|
||||
|
||||
(void)adcp;
|
||||
(void)err;
|
||||
}
|
||||
|
||||
/*
|
||||
* ADC conversion group.
|
||||
* Mode: Linear buffer, 8 samples of 1 channel, SW triggered.
|
||||
* Channels: IN10.
|
||||
*/
|
||||
static const ADCConversionGroup qsd_in = {
|
||||
TRUE, // continuous
|
||||
2, // 2 channels
|
||||
adccallback,
|
||||
adcerrorcallback,
|
||||
ADC_CFGR1_RES_12BIT, /* CFGR1 */
|
||||
ADC_TR(0, 0), /* TR */
|
||||
ADC_SMPR_SMP_1P5, /* SMPR */
|
||||
ADC_CHSELR_CHSEL6 | ADC_CHSELR_CHSEL7 /* CHSELR */
|
||||
};
|
||||
|
||||
|
||||
/** ADC init
|
||||
*/
|
||||
void adc_rx_init(void){
|
||||
static char re_init = 0;
|
||||
static adcsample_t * samples;
|
||||
const int len = 64;
|
||||
if(!re_init){
|
||||
re_init=1;
|
||||
// Allocate MxN buffer for continuous ADC
|
||||
samples = chCoreAllocFromBase(
|
||||
len * qsd_in.num_channels * sizeof(adcsample_t),
|
||||
sizeof(adcsample_t), 0);
|
||||
}
|
||||
// Start the continuous conversion
|
||||
adcStart(&ADCD1, NULL);
|
||||
adcStartConversion(&ADCD1, &qsd_in, samples, len);
|
||||
}
|
||||
|
|
@ -0,0 +1,32 @@
|
|||
/*
|
||||
* dsp.h
|
||||
*
|
||||
* Created on: Jul 6, 2020
|
||||
* Author: marshal
|
||||
*/
|
||||
|
||||
#ifndef DSP_H_
|
||||
#define DSP_H_
|
||||
|
||||
#include "hal.h"
|
||||
#include "ch.h"
|
||||
|
||||
/** ADC streaming callback for radio RX
|
||||
*
|
||||
* We sampled at 500kHz, but our bandwidth of interest is only
|
||||
* 2kHz. (Since it's quadrature sampling, nyquist rate is 1x)
|
||||
* We use a second-order IIR filter to prevent aliasing, followed
|
||||
* by an accumulate and decimation
|
||||
*/
|
||||
|
||||
/** Datatype for complex numbers */
|
||||
struct complex{
|
||||
int16_t real;
|
||||
int16_t imag;
|
||||
};
|
||||
|
||||
/** ADC init
|
||||
*/
|
||||
void adc_rx_init(void);
|
||||
|
||||
#endif /* DSP_H_ */
|
|
@ -0,0 +1,29 @@
|
|||
/*
|
||||
* rx.c
|
||||
*
|
||||
* Created on: Jul 6, 2020
|
||||
* Author: marshal
|
||||
*/
|
||||
|
||||
#include "rx.h"
|
||||
#include "dsp.h"
|
||||
|
||||
/** Mailbox for received data */
|
||||
msg_t new_sample;
|
||||
|
||||
THD_WORKING_AREA(waradio_rx, 128);
|
||||
THD_FUNCTION(radio_rx, arg){
|
||||
(void)arg;
|
||||
const int len = 256;
|
||||
int16_t * data = chCoreAllocFromBase(len*sizeof(int16_t), sizeof(int16_t), 0);
|
||||
while(1){
|
||||
for( int i=0; i<len;){
|
||||
thread_t * thd = chMsgWait();
|
||||
struct complex * c = (struct complex *)chMsgGet(thd);
|
||||
data[i++] = c->real;
|
||||
data[i++] = c->imag;
|
||||
chMsgRelease(thd, MSG_OK);
|
||||
}
|
||||
/** Here would be a good place to do a FFT or other processing */
|
||||
}
|
||||
}
|
|
@ -0,0 +1,19 @@
|
|||
/*
|
||||
* rx.h
|
||||
*
|
||||
* Created on: Jul 6, 2020
|
||||
* Author: marshal
|
||||
*/
|
||||
|
||||
#ifndef RX_H_
|
||||
#define RX_H_
|
||||
|
||||
#include "hal.h"
|
||||
#include "ch.h"
|
||||
|
||||
THD_FUNCTION(radio_rx, arg);
|
||||
|
||||
/** Mailbox for received data */
|
||||
extern msg_t new_sample;
|
||||
|
||||
#endif /* RX_H_ */
|
Ładowanie…
Reference in New Issue