Skip to content

Commit

Permalink
Teensy SDR Monoband RX
Browse files Browse the repository at this point in the history
Fully functioning in monoband RX mode. SI5351 tuning using encoder
switch, AGC, simple UI
  • Loading branch information
rheslip committed Jan 19, 2015
1 parent a9cd050 commit fe96f1c
Show file tree
Hide file tree
Showing 11 changed files with 1,882 additions and 0 deletions.
420 changes: 420 additions & 0 deletions Teensy_SDR.ino

Large diffs are not rendered by default.

123 changes: 123 additions & 0 deletions agc.cpp
@@ -0,0 +1,123 @@
// soft AGC and S meter display by Loftur E. Jónasson TF3LJ/VE2LJX 6/14
//

#include <Metro.h>
#include <Audio.h>

#include <Adafruit_GFX.h> // LCD Core graphics library
//#include <Adafruit_QDTech.h> // 1.8" TFT Module using Samsung S6D02A1 chip
#include <Adafruit_S6D02A1.h> // Hardware-specific library

//extern Adafruit_QDTech tft;
extern Adafruit_S6D02A1 tft;

extern AudioMixer4 AGC; // Summer (add inputs)
extern AudioPeak AGCpeak; // Measure Audio Peak for AGC use
extern AudioPeak Smeter; // Measure Audio Peak for S meter

Metro l_ms = Metro(1); // Set up a 1ms Metro
Metro lcd_upd2=Metro(100); // Set up a Metro for LCD updates

int32_t sample[10]; // A ringbuffer of samples (has to be larger than AGCattack)

double AGCgain=1; // Initial AGC gain. 1 = unity gain, 32768.0 max, 0.00004 min
#define AGCMAX 10
const int32_t AGCnomVal = 10000; // Nominal Output (32768 max)
const int32_t AGCattack = 2; // AGC Hang time (milliseconds) before reducing gain
const int32_t AGChang = 30; // AGC Hang time before increasing gain
const double AGCslope = 1.05; // Relative gain change


//
// Automatic Gain Control function
//
void agc(void)
{
static uint8_t i;
static uint16_t hangtimer;
uint8_t j,k;
int32_t s_sample; // Raw signal strength (max per 1ms)
int32_t samp; // AGC feedback loop sample strength (max per 1ms)
int32_t temp; // yeah, just a temp value
double uv, dbuv, s;// microvolts, db-microvolts, s-units
char string[80]; // print format stuff

if (l_ms.check() == 1)
{
// Collect S-meter data
s_sample = Smeter.Dpp(); // Highest sample within 1 millisecond
Smeter.begin(); // Reset for next measurement

// AGC: Collect current 1ms peak at output and feed to a ringbuffer
sample[i++] = samp = AGCpeak.Dpp();
AGCpeak.begin();
if (i >= AGCattack) i=0;

// Check if we need to reduce gain
for(j=0,k=0;j<AGCattack;j++)
{
if (sample[j] > AGCnomVal) k++;
}

// We need to reduce gain
if ((k == AGCattack) || ((k>0) && (hangtimer>=AGChang))) // Activate AGCattack
{
// find largest value
temp = 0;
for(j=0;j<AGCattack;j++)
{
if (sample[j]> temp) temp = sample[j];
}

// Instant reduction to appropriate value
AGCgain = AGCgain * AGCnomVal/temp;
// Reset hang timer
hangtimer = 0;
}

// Increment hangtimer while level is lower than nominal
else if(samp < AGCnomVal) hangtimer++;

if (hangtimer >= AGChang) // We need to ramp up the gain
{
AGCgain = AGCgain * AGCslope;
}

if (AGCgain > AGCMAX) AGCgain=AGCMAX; // limit the gain

AGC.gain(0,AGCgain); // Adjust AGC gain

//
// Print stuff to LCD only once every 100ms
//
if (lcd_upd2.check() == 1)
{
// Calculate S units. 50uV = S9
uv = s_sample/30.0; // microvolts, roughly calibrated
dbuv = 20.0*log10(uv);
s = 1.0 + (14.0 + dbuv)/6.0;
if (s>9.0)
{
dbuv = dbuv - 34.0;
s = 9.0;
}
else dbuv = 0;
// Print S units
tft.fillRect(10, 85, 30, 7,S6D02A1_BLACK);
tft.setCursor(0, 85);
if (dbuv == 0) sprintf(string,"S:%3.1f",s);
else sprintf(string,"S:9+%02.0f",dbuv);
tft.print(string);

if(0) // Debug stuff
{
// Print AGC loop parameters
tft.fillRect(10, 105, 100, 7,S6D02A1_BLACK);
tft.setCursor(0, 105);
sprintf(string,"pk:%5lu g:%5.1f",samp, AGCgain);
tft.print(string);
}
}
}
}

28 changes: 28 additions & 0 deletions filters.cpp
@@ -0,0 +1,28 @@
#include "filters.h"

short hilbert45[HILBERT_COEFFS] = {
#include "hilbert_45.h"
};

short hilbertm45[HILBERT_COEFFS] = {
#include "hilbert_m45.h"
};

short firbpf_usb[BPF_COEFFS] = {
#include "fir_usb.h"
};

short firbpf_lsb[BPF_COEFFS] = {
#include "fir_lsb.h"
};

short postfir_700[COEFF_700] = {
#include "postfir_700hz.h"
};

short postfir_lpf[COEFF_LPF] = {
#include "postfir_lpf.h"
};



13 changes: 13 additions & 0 deletions filters.h
@@ -0,0 +1,13 @@
// Number of coefficients
#define HILBERT_COEFFS 100
extern short hilbert45[];
extern short hilbertm45[];

#define BPF_COEFFS 100
extern short firbpf_usb[];
extern short firbpf_lsb[];

#define COEFF_LPF 54
extern short postfir_700[];
#define COEFF_700 120
extern short postfir_lpf[];
110 changes: 110 additions & 0 deletions fir_lsb.h
@@ -0,0 +1,110 @@
// LSB filter by Loftur E. Jónasson TF3LJ/VE2LJX 6/14- 2.4 kHz centred at 9.5 kHz
// (sampling rate 44.1 kHz)
//
// Parameters generated using Iowa Hills FIR Filter Designer
// OmegaC 0.433
// Bandwidth 0.110
// 100 taps
// Transition width 0.085
// Window off
// Parks McClellan
32768 * -0.000010523800014581,
32768 * -0.000122681642892022,
32768 * -0.000036415773389628,
32768 * 0.000305793174245558,
32768 * 0.000283565937180380,
32768 * -0.000472031799665594,
32768 * -0.000804098046625973,
32768 * 0.000378709203535162,
32768 * 0.001479276230080921,
32768 * 0.000183083088650831,
32768 * -0.001941975044915265,
32768 * -0.001135526486858456,
32768 * 0.001772511141387945,
32768 * 0.001963039344977544,
32768 * -0.000908490376865581,
32768 * -0.001916521667456298,
32768 * -0.000020006590571434,
32768 * 0.000602618449322109,
32768 * -0.000173651213944996,
32768 * 0.001394251556711564,
32768 * 0.002470013673232240,
32768 * -0.002448216941233300,
32768 * -0.006628534787491658,
32768 * 0.000759869709492400,
32768 * 0.010735891124917961,
32768 * 0.004155599503225747,
32768 * -0.012018010710235907,
32768 * -0.010389082153523428,
32768 * 0.008810696972067640,
32768 * 0.014105829623790958,
32768 * -0.002524099694416429,
32768 * -0.011858498891210132,
32768 * -0.002042840172782165,
32768 * 0.003626318880290195,
32768 * -0.001030976719610831,
32768 * 0.005542290777138538,
32768 * 0.014722151249366884,
32768 * -0.007046559790046048,
32768 * -0.035610017720202412,
32768 * -0.006654434845418102,
32768 * 0.053711019474210531,
32768 * 0.036665440452510710,
32768 * -0.056625604477486352,
32768 * -0.074954104576882299,
32768 * 0.036276347208572125,
32768 * 0.106669361716220323,
32768 * 0.005549784942170579,
32768 * -0.116927488293852577,
32768 * -0.056465510909489432,
32768 * 0.098576362058282713,
32768 * 0.098576362058282713,
32768 * -0.056465510909489432,
32768 * -0.116927488293852577,
32768 * 0.005549784942170579,
32768 * 0.106669361716220323,
32768 * 0.036276347208572125,
32768 * -0.074954104576882299,
32768 * -0.056625604477486352,
32768 * 0.036665440452510710,
32768 * 0.053711019474210531,
32768 * -0.006654434845418102,
32768 * -0.035610017720202412,
32768 * -0.007046559790046048,
32768 * 0.014722151249366884,
32768 * 0.005542290777138538,
32768 * -0.001030976719610831,
32768 * 0.003626318880290195,
32768 * -0.002042840172782165,
32768 * -0.011858498891210132,
32768 * -0.002524099694416429,
32768 * 0.014105829623790958,
32768 * 0.008810696972067640,
32768 * -0.010389082153523428,
32768 * -0.012018010710235907,
32768 * 0.004155599503225747,
32768 * 0.010735891124917961,
32768 * 0.000759869709492400,
32768 * -0.006628534787491658,
32768 * -0.002448216941233300,
32768 * 0.002470013673232240,
32768 * 0.001394251556711564,
32768 * -0.000173651213944996,
32768 * 0.000602618449322109,
32768 * -0.000020006590571434,
32768 * -0.001916521667456298,
32768 * -0.000908490376865581,
32768 * 0.001963039344977544,
32768 * 0.001772511141387945,
32768 * -0.001135526486858456,
32768 * -0.001941975044915265,
32768 * 0.000183083088650831,
32768 * 0.001479276230080921,
32768 * 0.000378709203535162,
32768 * -0.000804098046625973,
32768 * -0.000472031799665594,
32768 * 0.000283565937180380,
32768 * 0.000305793174245558,
32768 * -0.000036415773389628,
32768 * -0.000122681642892022,
32768 * -0.000010523800014581
111 changes: 111 additions & 0 deletions fir_usb.h
@@ -0,0 +1,111 @@
// USB filter by Loftur E. Jónasson TF3LJ/VE2LJX 6/14 2.4 kHz centred at 12.5 kHz
// (sampling rate 44.1 kHz)
//
// Parameters generated using Iowa Hills FIR Filter Designer
// OmegaC 0.567
// Bandwidth 0.109
// 100 taps
// Transition width 0.085
// Window off
// Parks McClellan
32768 * 0.000077220197574123,
32768 * -1.694364742523110E-6,
32768 * -0.000247376363569229,
32768 * 0.000172349071145931,
32768 * 0.000442532978562303,
32768 * -0.000587921806885401,
32768 * -0.000490796464995067,
32768 * 0.001245366873040035,
32768 * 0.000130200340800485,
32768 * -0.001862166817785674,
32768 * 0.000703051894342210,
32768 * 0.002007465586182165,
32768 * -0.001685724919682768,
32768 * -0.001407920138837247,
32768 * 0.002116180748678689,
32768 * 0.000372547212250720,
32768 * -0.001360627435518710,
32768 * 0.000104411160061938,
32768 * -0.000488583862643263,
32768 * 0.001171803660774852,
32768 * 0.002230271567546280,
32768 * -0.004622738899125535,
32768 * -0.001988597303309669,
32768 * 0.009091087568736349,
32768 * -0.001507388998028951,
32768 * -0.012022955491491360,
32768 * 0.007518507241432481,
32768 * 0.010969367705405847,
32768 * -0.012943254772900497,
32768 * -0.005724754564656228,
32768 * 0.013800759554407906,
32768 * -0.000413209911619933,
32768 * -0.008117888769062576,
32768 * 0.001659860856017020,
32768 * -0.001521029232922352,
32768 * 0.006868472137034775,
32768 * 0.007858709633466776,
32768 * -0.025100680515366711,
32768 * -0.002212548908150258,
32768 * 0.046023064611360000,
32768 * -0.020182170398250168,
32768 * -0.057755470091797719,
32768 * 0.055819871330333046,
32768 * 0.049337804826868066,
32768 * -0.092667374657917745,
32768 * -0.017292461343810531,
32768 * 0.114978094867627500,
32768 * -0.030993743432389236,
32768 * -0.111032169995744168,
32768 * 0.079554595102602668,
32768 * 0.079554595102602668,
32768 * -0.111032169995744168,
32768 * -0.030993743432389236,
32768 * 0.114978094867627500,
32768 * -0.017292461343810531,
32768 * -0.092667374657917745,
32768 * 0.049337804826868066,
32768 * 0.055819871330333046,
32768 * -0.057755470091797719,
32768 * -0.020182170398250168,
32768 * 0.046023064611360000,
32768 * -0.002212548908150258,
32768 * -0.025100680515366711,
32768 * 0.007858709633466776,
32768 * 0.006868472137034775,
32768 * -0.001521029232922352,
32768 * 0.001659860856017020,
32768 * -0.008117888769062576,
32768 * -0.000413209911619933,
32768 * 0.013800759554407906,
32768 * -0.005724754564656228,
32768 * -0.012943254772900497,
32768 * 0.010969367705405847,
32768 * 0.007518507241432481,
32768 * -0.012022955491491360,
32768 * -0.001507388998028951,
32768 * 0.009091087568736349,
32768 * -0.001988597303309669,
32768 * -0.004622738899125535,
32768 * 0.002230271567546280,
32768 * 0.001171803660774852,
32768 * -0.000488583862643263,
32768 * 0.000104411160061938,
32768 * -0.001360627435518710,
32768 * 0.000372547212250720,
32768 * 0.002116180748678689,
32768 * -0.001407920138837247,
32768 * -0.001685724919682768,
32768 * 0.002007465586182165,
32768 * 0.000703051894342210,
32768 * -0.001862166817785674,
32768 * 0.000130200340800485,
32768 * 0.001245366873040035,
32768 * -0.000490796464995067,
32768 * -0.000587921806885401,
32768 * 0.000442532978562303,
32768 * 0.000172349071145931,
32768 * -0.000247376363569229,
32768 * -1.694364742523110E-6,
32768 * 0.000077220197574123

0 comments on commit fe96f1c

Please sign in to comment.